/*******************************************************************************
* Copyright (c) 2004 Stefan Zeiger and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.novocode.com/legal/epl-v10.html
*
* Contributors:
* Stefan Zeiger (szeiger@novocode.com) - initial API and implementation
*******************************************************************************/
package com.adito.agent.client.gui.swt;
import java.util.ArrayList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Widget;
/**
* A Shell wrapper which creates balloon popup windows.
*
* <p>
* By default, a balloon window has no title bar or system controls. The
* following styles are supported:
* </p>
*
* <ul>
* <li>SWT.ON_TOP - Keep the window on top of other windows</li>
* <li>SWT.TOOL - Add a drop shadow to the window (on supported platforms)</li>
* <li>SWT.CLOSE - Show a "close" control on the title bar (implies SWT.TITLE)</li>
* <li>SWT.TITLE - Show a title bar</li>
* </ul>
*
* @author Stefan Zeiger (szeiger@novocode.com)
* @since Jul 2, 2004
* @version $Id: SWTBalloonWindow.java,v 1.1 2007/02/08 11:44:35 brett Exp $
*/
public class SWTBalloonWindow {
private final Shell shell;
private final Composite contents;
private Label titleLabel;
private Canvas titleImageLabel;
private final int style;
private int preferredAnchor = SWT.BOTTOM | SWT.RIGHT;
private boolean autoAnchor = true;
private int autoLocation = SWT.NONE;
private int locX = Integer.MIN_VALUE, locY = Integer.MIN_VALUE;
private int marginLeft = 12, marginRight = 12, marginTop = 5, marginBottom = 10;
private int titleSpacing = 3, titleWidgetSpacing = 8;
private ToolBar systemControlsBar;
private ArrayList selectionControls = new ArrayList();
private boolean addedGlobalListener;
private ArrayList selectionListeners = new ArrayList();
public SWTBalloonWindow(Shell parent, int style) {
this(null, parent, style);
}
public SWTBalloonWindow(Display display, int style) {
this(display, null, style);
}
private SWTBalloonWindow(Display display, Shell parent, final int style) {
this.style = style;
int shellStyle = style & (SWT.ON_TOP | SWT.TOOL);
this.shell = (display != null) ? new Shell(display, SWT.NO_TRIM | shellStyle) : new Shell(parent, SWT.NO_TRIM | shellStyle);
this.contents = new Composite(shell, SWT.NONE);
final Color c = new Color(shell.getDisplay(), 255, 255, 225);
shell.setBackground(c);
shell.setForeground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
contents.setBackground(shell.getBackground());
contents.setForeground(shell.getForeground());
selectionControls.add(shell);
selectionControls.add(contents);
final Listener globalListener = new Listener() {
public void handleEvent(Event event) {
Widget w = event.widget;
for (int i = selectionControls.size() - 1; i >= 0; i--) {
if (selectionControls.get(i) == w) {
if ((style & SWT.CLOSE) != 0) {
for (int j = selectionListeners.size() - 1; j >= 0; j--)
((Listener) selectionListeners.get(j)).handleEvent(event);
} else {
shell.close();
}
event.doit = false;
}
}
}
};
shell.addListener(SWT.Show, new Listener() {
public void handleEvent(Event event) {
if (!addedGlobalListener) {
shell.getDisplay().addFilter(SWT.MouseDown, globalListener);
addedGlobalListener = true;
}
}
});
shell.addListener(SWT.Hide, new Listener() {
public void handleEvent(Event event) {
if (addedGlobalListener) {
shell.getDisplay().removeFilter(SWT.MouseDown, globalListener);
addedGlobalListener = false;
}
}
});
shell.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
if (addedGlobalListener) {
shell.getDisplay().removeFilter(SWT.MouseDown, globalListener);
addedGlobalListener = false;
}
c.dispose();
}
});
}
/**
* Adds a control to the list of controls which close the balloon window.
* The background, title image and title text are included by default.
*/
public void addSelectionControl(Control c) {
selectionControls.add(c);
}
public void addListener(int type, Listener l) {
if (type == SWT.Selection)
selectionListeners.add(l);
}
/**
* Set the location of the anchor. This must be one of the following values:
* SWT.NONE, SWT.LEFT|SWT.TOP, SWT.RIGHT|SWT.TOP, SWT.LEFT|SWT.BOTTOM,
* SWT.RIGHT|SWT.BOTTOM
*/
public void setAnchor(int anchor) {
switch (anchor) {
case SWT.NONE:
case SWT.LEFT | SWT.TOP:
case SWT.RIGHT | SWT.TOP:
case SWT.LEFT | SWT.BOTTOM:
case SWT.RIGHT | SWT.BOTTOM:
break;
default:
throw new IllegalArgumentException("Illegal anchor value " + anchor);
}
this.preferredAnchor = anchor;
}
public void setAutoAnchor(boolean autoAnchor) {
this.autoAnchor = autoAnchor;
}
public void setAutoLocation(int autoLocation) {
this.autoLocation = autoLocation;
}
public void setLocation(int x, int y) {
this.locX = x;
this.locY = y;
}
public void setLocation(Point p) {
this.locX = p.x;
this.locY = p.y;
}
public void setText(String title) {
shell.setText(title);
}
public void setImage(Image image) {
shell.setImage(image);
}
public void setMargins(int marginLeft, int marginRight, int marginTop, int marginBottom) {
this.marginLeft = marginLeft;
this.marginRight = marginRight;
this.marginTop = marginTop;
this.marginBottom = marginBottom;
}
public void setMargins(int marginX, int marginY) {
setMargins(marginX, marginX, marginY, marginY);
}
public void setMargins(int margin) {
setMargins(margin, margin, margin, margin);
}
public void setTitleSpacing(int titleSpacing) {
this.titleSpacing = titleSpacing;
}
public void setTitleWidgetSpacing(int titleImageSpacing) {
this.titleWidgetSpacing = titleImageSpacing;
}
public Shell getShell() {
return shell;
}
public Composite getContents() {
return contents;
}
public void prepareForOpen() {
Point contentsSize = contents.getSize();
Point titleSize = new Point(0, 0);
boolean showTitle = ((style & (SWT.CLOSE | SWT.TITLE)) != 0);
if (showTitle) {
if (titleLabel == null) {
titleLabel = new Label(shell, SWT.NONE);
titleLabel.setBackground(shell.getBackground());
titleLabel.setForeground(shell.getForeground());
FontData[] fds = shell.getFont().getFontData();
for (int i = 0; i < fds.length; i++) {
fds[i].setStyle(fds[i].getStyle() | SWT.BOLD);
}
final Font font = new Font(shell.getDisplay(), fds);
titleLabel.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
font.dispose();
}
});
titleLabel.setFont(font);
selectionControls.add(titleLabel);
}
String titleText = shell.getText();
titleLabel.setText(titleText == null ? "" : titleText);
titleLabel.pack();
titleSize = titleLabel.getSize();
final Image titleImage = shell.getImage();
if (titleImageLabel == null && shell.getImage() != null) {
titleImageLabel = new Canvas(shell, SWT.NONE);
titleImageLabel.setBackground(shell.getBackground());
titleImageLabel.setBounds(titleImage.getBounds());
titleImageLabel.addListener(SWT.Paint, new Listener() {
public void handleEvent(Event event) {
event.gc.drawImage(titleImage, 0, 0);
}
});
Point tilSize = titleImageLabel.getSize();
titleSize.x += tilSize.x + titleWidgetSpacing;
if (tilSize.y > titleSize.y)
titleSize.y = tilSize.y;
selectionControls.add(titleImageLabel);
}
if (systemControlsBar == null && (style & SWT.CLOSE) != 0) {
// Color closeFG = shell.getForeground(), closeBG =
// shell.getBackground();
// Color closeFG =
// shell.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY),
// closeBG = shell.getBackground();
Color closeFG = shell.getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND), closeBG = shell.getDisplay()
.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
final Image closeImage = createCloseImage(shell.getDisplay(), closeBG, closeFG);
shell.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
closeImage.dispose();
}
});
systemControlsBar = new ToolBar(shell, SWT.FLAT);
systemControlsBar.setBackground(closeBG);
systemControlsBar.setForeground(closeFG);
ToolItem closeItem = new ToolItem(systemControlsBar, SWT.PUSH);
closeItem.setImage(closeImage);
closeItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
shell.close();
}
});
systemControlsBar.pack();
Point closeSize = systemControlsBar.getSize();
titleSize.x += closeSize.x + titleWidgetSpacing;
if (closeSize.y > titleSize.y)
titleSize.y = closeSize.y;
}
titleSize.y += titleSpacing;
if (titleSize.x > contentsSize.x) {
contentsSize.x = titleSize.x;
contents.setSize(contentsSize.x, contentsSize.y);
}
contentsSize.y += titleSize.y;
}
Rectangle screen = shell.getDisplay().getClientArea();
int anchor = preferredAnchor;
if (anchor != SWT.NONE && autoAnchor && locX != Integer.MIN_VALUE) {
if ((anchor & SWT.LEFT) != 0) {
if (locX + contentsSize.x + marginLeft + marginRight - 16 >= screen.x + screen.width)
anchor = anchor - SWT.LEFT + SWT.RIGHT;
} else // RIGHT
{
if (locX - contentsSize.x - marginLeft - marginRight + 16 < screen.x)
anchor = anchor - SWT.RIGHT + SWT.LEFT;
}
if ((anchor & SWT.TOP) != 0) {
if (locY + contentsSize.y + 20 + marginTop + marginBottom >= screen.y + screen.height)
anchor = anchor - SWT.TOP + SWT.BOTTOM;
} else // BOTTOM
{
if (locY - contentsSize.y - 20 - marginTop - marginBottom < screen.y)
anchor = anchor - SWT.BOTTOM + SWT.TOP;
}
}
final Point shellSize = (anchor == SWT.NONE) ? new Point(contentsSize.x + marginLeft + marginRight,
contentsSize.y + marginTop + marginBottom) : new Point(contentsSize.x + marginLeft + marginRight,
contentsSize.y + marginTop + marginBottom + 20);
if (shellSize.x < 54 + marginLeft + marginRight)
shellSize.x = 54 + marginLeft + marginRight;
if (anchor == SWT.NONE) {
if (shellSize.y < 10 + marginTop + marginBottom)
shellSize.y = 10 + marginTop + marginBottom;
} else {
if (shellSize.y < 30 + marginTop + marginBottom)
shellSize.y = 30 + marginTop + marginBottom;
}
shell.setSize(shellSize);
int titleLocY = marginTop + (((anchor & SWT.TOP) != 0) ? 20 : 0);
contents.setLocation(marginLeft, titleSize.y + titleLocY);
if (showTitle) {
int realTitleHeight = titleSize.y - titleSpacing;
if (titleImageLabel != null) {
titleImageLabel.setLocation(marginLeft, titleLocY + (realTitleHeight - titleImageLabel.getSize().y) / 2);
titleLabel.setLocation(marginLeft + titleImageLabel.getSize().x + titleWidgetSpacing,
titleLocY + (realTitleHeight - titleLabel.getSize().y) / 2);
} else
titleLabel.setLocation(marginLeft, titleLocY + (realTitleHeight - titleLabel.getSize().y) / 2);
if (systemControlsBar != null)
systemControlsBar.setLocation(shellSize.x - marginRight - systemControlsBar.getSize().x,
titleLocY + (realTitleHeight - systemControlsBar.getSize().y) / 2);
}
final Region region = new Region();
region.add(createOutline(shellSize, anchor, true));
shell.setRegion(region);
shell.addListener(SWT.Dispose, new Listener() {
public void handleEvent(Event event) {
region.dispose();
}
});
final int[] outline = createOutline(shellSize, anchor, false);
shell.addListener(SWT.Paint, new Listener() {
public void handleEvent(Event event) {
event.gc.drawPolygon(outline);
}
});
if (autoLocation != SWT.NONE) {
Point shellLoc = new Point(locX == Integer.MIN_VALUE ? 0 : locX, locY == Integer.MIN_VALUE ? 0 : locY);
Rectangle screenBounds = shell.getDisplay().getPrimaryMonitor().getBounds();
if ((autoLocation & SWT.RIGHT) != 0) {
shellLoc.x = screenBounds.width - shellSize.x - shellLoc.x;
}
if ((autoLocation & SWT.BOTTOM) != 0) {
shellLoc.y = screenBounds.height - shellSize.y - shellLoc.y;
}
shell.setLocation(shellLoc);
}
else {
if (locX != Integer.MIN_VALUE) {
Point shellLoc = new Point(locX, locY);
if ((anchor & SWT.BOTTOM) != 0)
shellLoc.y = shellLoc.y - shellSize.y + 1;
if ((anchor & SWT.LEFT) != 0)
shellLoc.x -= 15;
else if ((anchor & SWT.RIGHT) != 0)
shellLoc.x = shellLoc.x - shellSize.x + 16;
if (autoAnchor) {
if (shellLoc.x < screen.x)
shellLoc.x = screen.x;
else if (shellLoc.x > screen.x + screen.width - shellSize.x)
shellLoc.x = screen.x + screen.width - shellSize.x;
if (anchor == SWT.NONE) {
if (shellLoc.y < screen.y)
shellLoc.y = screen.y;
else if (shellLoc.y > screen.y + screen.height - shellSize.y)
shellLoc.y = screen.y + screen.height - shellSize.y;
}
}
shell.setLocation(shellLoc);
}
}
}
public void open() {
prepareForOpen();
shell.open();
}
public void close() {
shell.close();
}
public void setVisible(boolean visible) {
if (visible)
prepareForOpen();
shell.setVisible(visible);
}
private static int[] createOutline(Point size, int anchor, boolean outer) {
int o = outer ? 1 : 0;
int w = size.x + o;
int h = size.y + o;
switch (anchor) {
case SWT.RIGHT | SWT.BOTTOM:
return new int[] {
// top and top right
5,
0,
w - 6,
0,
w - 6,
1,
w - 4,
1,
w - 4,
2,
w - 3,
2,
w - 3,
3,
w - 2,
3,
w - 2,
5,
w - 1,
5,
// right and bottom right
w - 1,
h - 26,
w - 2,
h - 26,
w - 2,
h - 24,
w - 3,
h - 24,
w - 3,
h - 23,
w - 4,
h - 23,
w - 4,
h - 22,
w - 6,
h - 22,
w - 6,
h - 21,
// bottom with anchor
w - 16,
h - 21,
w - 16,
h - 1,
w - 16 - o,
h - 1,
w - 16 - o,
h - 2,
w - 17 - o,
h - 2,
w - 17 - o,
h - 3,
w - 18 - o,
h - 3,
w - 18 - o,
h - 4,
w - 19 - o,
h - 4,
w - 19 - o,
h - 5,
w - 20 - o,
h - 5,
w - 20 - o,
h - 6,
w - 21 - o,
h - 6,
w - 21 - o,
h - 7,
w - 22 - o,
h - 7,
w - 22 - o,
h - 8,
w - 23 - o,
h - 8,
w - 23 - o,
h - 9,
w - 24 - o,
h - 9,
w - 24 - o,
h - 10,
w - 25 - o,
h - 10,
w - 25 - o,
h - 11,
w - 26 - o,
h - 11,
w - 26 - o,
h - 12,
w - 27 - o,
h - 12,
w - 27 - o,
h - 13,
w - 28 - o,
h - 13,
w - 28 - o,
h - 14,
w - 29 - o,
h - 14,
w - 29 - o,
h - 15,
w - 30 - o,
h - 15,
w - 30 - o,
h - 16,
w - 31 - o,
h - 16,
w - 31 - o,
h - 17,
w - 32 - o,
h - 17,
w - 32 - o,
h - 18,
w - 33 - o,
h - 18,
w - 33 - o,
h - 19,
w - 34 - o,
h - 19,
w - 34 - o,
h - 20,
w - 35 - o,
h - 20,
w - 35 - o,
h - 21,
// bottom left
5,
h - 21,
5,
h - 22,
3,
h - 22,
3,
h - 23,
2,
h - 23,
2,
h - 24,
1,
h - 24,
1,
h - 26,
0,
h - 26,
// left and top left
0,
5,
1,
5,
1,
3,
2,
3,
2,
2,
3,
2,
3,
1,
5,
1 };
case SWT.LEFT | SWT.BOTTOM:
return new int[] {
// top and top right
5,
0,
w - 6,
0,
w - 6,
1,
w - 4,
1,
w - 4,
2,
w - 3,
2,
w - 3,
3,
w - 2,
3,
w - 2,
5,
w - 1,
5,
// right and bottom right
w - 1,
h - 26,
w - 2,
h - 26,
w - 2,
h - 24,
w - 3,
h - 24,
w - 3,
h - 23,
w - 4,
h - 23,
w - 4,
h - 22,
w - 6,
h - 22,
w - 6,
h - 21,
// bottom with anchor
34 + o,
h - 21,
34 + o,
h - 20,
33 + o,
h - 20,
33 + o,
h - 19,
32 + o,
h - 19,
32 + o,
h - 18,
31 + o,
h - 18,
31 + o,
h - 17,
30 + o,
h - 17,
30 + o,
h - 16,
29 + o,
h - 16,
29 + o,
h - 15,
28 + o,
h - 15,
28 + o,
h - 14,
27 + o,
h - 14,
27 + o,
h - 13,
26 + o,
h - 13,
26 + o,
h - 12,
25 + o,
h - 12,
25 + o,
h - 11,
24 + o,
h - 11,
24 + o,
h - 10,
23 + o,
h - 10,
23 + o,
h - 9,
22 + o,
h - 9,
22 + o,
h - 8,
21 + o,
h - 8,
21 + o,
h - 7,
20 + o,
h - 7,
20 + o,
h - 6,
19 + o,
h - 6,
19 + o,
h - 5,
18 + o,
h - 5,
18 + o,
h - 4,
17 + o,
h - 4,
17 + o,
h - 3,
16 + o,
h - 3,
16 + o,
h - 2,
15 + o,
h - 2,
15,
h - 1,
15,
h - 21,
// bottom left
5,
h - 21,
5,
h - 22,
3,
h - 22,
3,
h - 23,
2,
h - 23,
2,
h - 24,
1,
h - 24,
1,
h - 26,
0,
h - 26,
// left and top left
0,
5,
1,
5,
1,
3,
2,
3,
2,
2,
3,
2,
3,
1,
5,
1 };
case SWT.RIGHT | SWT.TOP:
return new int[] {
// top with anchor
5,
20,
w - 35 - o,
20,
w - 35 - o,
19,
w - 34 - o,
19,
w - 34 - o,
18,
w - 33 - o,
18,
w - 33 - o,
17,
w - 32 - o,
17,
w - 32 - o,
16,
w - 31 - o,
16,
w - 31 - o,
15,
w - 30 - o,
15,
w - 30 - o,
14,
w - 29 - o,
14,
w - 29 - o,
13,
w - 28 - o,
13,
w - 28 - o,
12,
w - 27 - o,
12,
w - 27 - o,
11,
w - 26 - o,
11,
w - 26 - o,
10,
w - 25 - o,
10,
w - 25 - o,
9,
w - 24 - o,
9,
w - 24 - o,
8,
w - 23 - o,
8,
w - 23 - o,
7,
w - 22 - o,
7,
w - 22 - o,
6,
w - 21 - o,
6,
w - 21 - o,
5,
w - 20 - o,
5,
w - 20 - o,
4,
w - 19 - o,
4,
w - 19 - o,
3,
w - 18 - o,
3,
w - 18 - o,
2,
w - 17 - o,
2,
w - 17 - o,
1,
w - 16 - o,
1,
w - 16 - o,
0,
w - 16,
0,
w - 16,
20,
// top and top right
w - 6,
20,
w - 6,
21,
w - 4,
21,
w - 4,
22,
w - 3,
22,
w - 3,
23,
w - 2,
23,
w - 2,
25,
w - 1,
25,
// right and bottom right
w - 1,
h - 6,
w - 2,
h - 6,
w - 2,
h - 4,
w - 3,
h - 4,
w - 3,
h - 3,
w - 4,
h - 3,
w - 4,
h - 2,
w - 6,
h - 2,
w - 6,
h - 1,
// bottom and bottom left
5,
h - 1,
5,
h - 2,
3,
h - 2,
3,
h - 3,
2,
h - 3,
2,
h - 4,
1,
h - 4,
1,
h - 6,
0,
h - 6,
// left and top left
0,
25,
1,
25,
1,
23,
2,
23,
2,
22,
3,
22,
3,
21,
5,
21 };
case SWT.LEFT | SWT.TOP:
return new int[] {
// top with anchor
5,
20,
15,
20,
15,
0,
15 + o,
0,
16 + o,
1,
16 + o,
2,
17 + o,
2,
17 + o,
3,
18 + o,
3,
18 + o,
4,
19 + o,
4,
19 + o,
5,
20 + o,
5,
20 + o,
6,
21 + o,
6,
21 + o,
7,
22 + o,
7,
22 + o,
8,
23 + o,
8,
23 + o,
9,
24 + o,
9,
24 + o,
10,
25 + o,
10,
25 + o,
11,
26 + o,
11,
26 + o,
12,
27 + o,
12,
27 + o,
13,
28 + o,
13,
28 + o,
14,
29 + o,
14,
29 + o,
15,
30 + o,
15,
30 + o,
16,
31 + o,
16,
31 + o,
17,
32 + o,
17,
32 + o,
18,
33 + o,
18,
33 + o,
19,
34 + o,
19,
34 + o,
20,
// top and top right
w - 6,
20,
w - 6,
21,
w - 4,
21,
w - 4,
22,
w - 3,
22,
w - 3,
23,
w - 2,
23,
w - 2,
25,
w - 1,
25,
// right and bottom right
w - 1,
h - 6,
w - 2,
h - 6,
w - 2,
h - 4,
w - 3,
h - 4,
w - 3,
h - 3,
w - 4,
h - 3,
w - 4,
h - 2,
w - 6,
h - 2,
w - 6,
h - 1,
// bottom and bottom left
5,
h - 1,
5,
h - 2,
3,
h - 2,
3,
h - 3,
2,
h - 3,
2,
h - 4,
1,
h - 4,
1,
h - 6,
0,
h - 6,
// left and top left
0,
25,
1,
25,
1,
23,
2,
23,
2,
22,
3,
22,
3,
21,
5,
21 };
default:
return new int[] {
// top and top right
5,
0,
w - 6,
0,
w - 6,
1,
w - 4,
1,
w - 4,
2,
w - 3,
2,
w - 3,
3,
w - 2,
3,
w - 2,
5,
w - 1,
5,
// right and bottom right
w - 1,
h - 6,
w - 2,
h - 6,
w - 2,
h - 4,
w - 3,
h - 4,
w - 3,
h - 3,
w - 4,
h - 3,
w - 4,
h - 2,
w - 6,
h - 2,
w - 6,
h - 1,
// bottom and bottom left
5,
h - 1,
5,
h - 2,
3,
h - 2,
3,
h - 3,
2,
h - 3,
2,
h - 4,
1,
h - 4,
1,
h - 6,
0,
h - 6,
// left and top left
0,
5,
1,
5,
1,
3,
2,
3,
2,
2,
3,
2,
3,
1,
5,
1 };
}
}
private static final Image createCloseImage(Display display, Color bg, Color fg) {
int size = 11, off = 1;
Image image = new Image(display, size, size);
GC gc = new GC(image);
gc.setBackground(bg);
gc.fillRectangle(image.getBounds());
gc.setForeground(fg);
gc.drawLine(0 + off, 0 + off, size - 1 - off, size - 1 - off);
gc.drawLine(1 + off, 0 + off, size - 1 - off, size - 2 - off);
gc.drawLine(0 + off, 1 + off, size - 2 - off, size - 1 - off);
gc.drawLine(size - 1 - off, 0 + off, 0 + off, size - 1 - off);
gc.drawLine(size - 1 - off, 1 + off, 1 + off, size - 1 - off);
gc.drawLine(size - 2 - off, 0 + off, 0 + off, size - 2 - off);
/*
* gc.drawLine(1, 0, size-2, 0); gc.drawLine(1, size-1, size-2, size-1);
* gc.drawLine(0, 1, 0, size-2); gc.drawLine(size-1, 1, size-1, size-2);
*/
gc.dispose();
return image;
}
}