package DisplayProject;
import java.awt.Graphics;
import java.awt.Robot;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.StringTokenizer;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JWindow;
import DisplayProject.TMSchema.Part;
import DisplayProject.TMSchema.State;
import DisplayProject.XPStyle.Skin;
import com.sun.java.swing.plaf.windows.WindowsIconFactory;
/**
* This Adaptor provides the ability to disable the buttons in the frame on a window.
* Close, Maximize and Minimize can be disabled.
*
* This functionality is not available in Swing and is provided her by adding a small window over the close button.
*
* PM:16/5/08 Significant changes to handle resizable windows
*/
public class WindowButtonAdapter extends ComponentAdapter {
public static final int CLOSE = 1;
public static final int MAXIMIZE = 2;
public static final int MINIMUMIZE = 3;
public static final int XP = 1;
public static final int CLASSIC = 2;
public static final int VISTA = 3;
// CraigM:26/05/2008 - Added Vista support.
private static final int VISTA_BTNS_X_OFFSET = 7;
private static final int VISTA_BTNS_Y_OFFSET = 1;
private static final int VISTA_BTNS_HEIGHT = 18;
private static final int VISTA_CLOSE_WIDTH = 43;
private static final int VISTA_MAXIMIZE_WIDTH = 25;
private static final int VISTA_MINIMIZE_WIDTH = 26;
protected Icon closeIcon;
protected Icon minimizeIcon;
protected Icon maximizeIcon;
protected Icon target;
protected JFrame parent;
protected JWindow cover;
protected Robot robot;
protected int type;
protected int style;
protected XPStyle xp;
@SuppressWarnings("serial")
public WindowButtonAdapter(JFrame parent, int type){
this.parent = parent;
this.type = type;
xp = XPStyle.getXP();
closeIcon = WindowsIconFactory.createFrameCloseIcon();
maximizeIcon = WindowsIconFactory.createFrameMaximizeIcon();
minimizeIcon = WindowsIconFactory.createFrameIconifyIcon();
if (System.getProperty("os.name").toUpperCase().indexOf("VISTA") != -1) {
this.style = VISTA;
} else if ( xp != null) {
this.style = XP;
} else {
this.style = CLASSIC;
}
switch (type) {
case CLOSE:
target = closeIcon;
break;
case MAXIMIZE:
target = maximizeIcon;
break;
case MINIMUMIZE:
target = minimizeIcon;
break;
}
// final boolean versionOK = this.checkVersion();
this.cover = new JWindow(this.parent) {
@Override
public void paint(Graphics g) {
if (style == XP) {
Part part = null;
switch (WindowButtonAdapter.this.type){
case CLOSE:
part = Part.WP_CLOSEBUTTON;
break;
case MAXIMIZE:
part = Part.WP_MAXBUTTON;
break;
case MINIMUMIZE:
part = Part.WP_MINBUTTON;
break;
default:
part = Part.WP_CLOSEBUTTON;
break;
}
Skin skin = xp.getSkin(this, part);
skin.paintSkin(g, 0, 0, getWidth(), getHeight(), State.DISABLED);
}
else if (style == VISTA) {
// This needs to be improved to actually paint proper Vista icons. However, this is difficult
// as Vista Aero package makes the buttons semi transparent. CraigM:26/05/2008.
target.paintIcon(this, g, 0, 0);
}
else {
target.paintIcon(this, g, 0, 0);
}
}
};
this.cover.setBackground(UIutils.Gray3);
this.refresh();
}
/**
* Check the version is 1.5.0_12 or later. This is required for the XPStyle class.
*
* Written by Craig Mitchell
* @since 12/02/2008
*/
protected boolean checkVersion() {
boolean isVer1_5_0_12orLater = false;
final int[] version = this.parseVersion(System.getProperty("java.version", "."));
if (version.length > 0) {
if (version[0] == 1) {
if (version.length > 1) {
if (version[1] == 5) {
if (version.length > 2) {
if (version[2] == 0) {
if (version.length > 3 && version[3] >= 12) {
isVer1_5_0_12orLater = true;
}
}
else {
isVer1_5_0_12orLater = true;
}
}
}
else if (version[1] > 5) {
isVer1_5_0_12orLater = true;
}
}
}
else if (version[0] > 1) {
isVer1_5_0_12orLater = true;
}
}
return isVer1_5_0_12orLater;
}
/**
* Copied from: http://forum.java.sun.com/thread.jspa?threadID=624398&messageID=3791496
*/
private int[] parseVersion(String v) {
StringTokenizer st = new StringTokenizer(v, "._, \t|/\\;:");
int[] vi = new int[st.countTokens()];
for(int i = 0; i < vi.length; i++) {
try {
vi[i] = Integer.parseInt(st.nextToken(), 10);
} catch(Exception e) {
vi[i] = -1;
}
}
return vi;
}
@Override
public void componentHidden(ComponentEvent e) {
this.cover.setVisible(false);
}
@Override
public void componentMoved(ComponentEvent e) {
this.refresh();
}
@Override
public void componentResized(ComponentEvent e) {
this.refresh();
}
@Override
public void componentShown(ComponentEvent e) {
// CraigM: 17/07/2008 - Don't show the button if we don't have a frame
if (this.parent.isUndecorated() == false) {
this.cover.setVisible(true);
this.refresh();
}
}
/**
* resize and locate the cover window, and repaint it.
*/
protected void refresh() {
int x = 0;
int y = 0;
int width = 0;
int height = 0;
boolean isResizable = this.parent.isResizable();
switch (type){
case CLOSE:
switch (this.style){
case VISTA:
x = VISTA_BTNS_X_OFFSET;
y = VISTA_BTNS_Y_OFFSET;
width = VISTA_CLOSE_WIDTH;
height = VISTA_BTNS_HEIGHT;
break;
case XP:
if (isResizable){
x = 6;
y = 6;
} else {
x = 5;
y = 5;
}
width = closeIcon.getIconWidth() - 2;
height = closeIcon.getIconHeight();
break;
default: // Believe it or not
if (isResizable){
x = 6;
y = 6;
} else {
x = 5;
y = 5;
}
width = closeIcon.getIconWidth();
height = closeIcon.getIconHeight();
break;
}
break;
case MAXIMIZE:
switch (this.style){
case VISTA:
x = VISTA_BTNS_X_OFFSET + VISTA_CLOSE_WIDTH;
y = VISTA_BTNS_Y_OFFSET;
width = VISTA_MAXIMIZE_WIDTH;
height = VISTA_BTNS_HEIGHT;
break;
case XP:
x = 6 + closeIcon.getIconWidth();
y = 6;
width = maximizeIcon.getIconWidth() - 2;
height = maximizeIcon.getIconHeight();
break;
default:
x = 6 + closeIcon.getIconWidth() + 2;
y = 6;
width = maximizeIcon.getIconWidth();
height = maximizeIcon.getIconHeight();
break;
}
break;
case MINIMUMIZE:
switch (this.style){
case VISTA:
x = VISTA_BTNS_X_OFFSET + VISTA_CLOSE_WIDTH + VISTA_MAXIMIZE_WIDTH;
y = VISTA_BTNS_Y_OFFSET;
width = VISTA_MINIMIZE_WIDTH;
height = VISTA_BTNS_HEIGHT;
break;
case XP:
if (isResizable){
x = 6 + closeIcon.getIconWidth() + maximizeIcon.getIconWidth();
y = 6;
} else {
x = 5 + closeIcon.getIconWidth() + maximizeIcon.getIconWidth();
y = 5;
}
width = minimizeIcon.getIconWidth() - 2;
height = minimizeIcon.getIconHeight();
break;
default:
if (isResizable){
x = 6 + closeIcon.getIconWidth() + 2 + maximizeIcon.getIconWidth();
y = 6;
}else {
x = 5 + closeIcon.getIconWidth() + 2 + maximizeIcon.getIconWidth();
y = 5;
}
width = minimizeIcon.getIconWidth();
height = minimizeIcon.getIconHeight();
break;
}
break;
}
x = this.parent.getX() + this.parent.getSize().width - width - x;
y = this.parent.getY() + y;
this.cover.setBounds(x, y, width, height);
this.cover.repaint();
}
}