import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LockableJFrame extends JFrame {
private LockPane lockPane;
public LockableJFrame() {
super();
setupGlassPane();
}
public LockableJFrame(String title) {
super(title);
setupGlassPane();
}
private void setupGlassPane() {
this.lockPane = new LockPane();
setGlassPane(lockPane);
}
/**
* Must be called on EDT! Locks this frame so that user events are not
* handled, and puts a transparent layer on the frame to show the user that
* the frame is disabled.
*/
public void lock() {
this.lock(null);
}
/**
* Must be called on EDT! Locks this frame so that user events are not
* handled, and puts a transparent layer on the frame to show the user that
* the frame is disabled. In addition, a message is displayed.
*
* @param msg
* the message to display.
*/
public void lock(String msg) {
this.setEnabled(false);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
LockPane lockPane = (LockPane) getGlassPane();
lockPane.setMsg(msg);
lockPane.setVisible(true);
lockPane.requestFocusInWindow();
}
/**
* Must be called on EDT! Unlocks the frame.
*/
public void unlock() {
getGlassPane().setVisible(false);
this.setEnabled(true);
setCursor(Cursor.getDefaultCursor());
}
public void setLockAppearance(Color backgrndColor, Color msgColor,
Font msgFont) {
lockPane.setBackground(backgrndColor);
lockPane.setMsgColor(msgColor);
lockPane.setMsgFont(msgFont);
}
private class LockPane extends JPanel implements KeyListener {
private String msg;
private Font msgFont;
private Color msgColor;
public LockPane() {
setOpaque(false);
setFocusTraversalKeysEnabled(false);
loadDefaultAppearance();
addKeyListener(this);
}
private void loadDefaultAppearance() {
setBackground(new Color(100, 100, 150, 100));
msgFont = new Font("SansSerif", Font.PLAIN, 14);
msgColor = Color.WHITE;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setMsgColor(Color msgColor) {
this.msgColor = msgColor;
}
public void setMsgFont(Font msgFont) {
this.msgFont = msgFont;
}
/*
* Returns the position of a String within this component so that it is
* centered both horizontally and vertically.
*/
private Point getCenter(String s, FontMetrics m, int width, int height) {
int x = (width - m.stringWidth(s)) / 2;
int y = (height - m.getHeight()) / 2 + m.getAscent();
Point center = new Point(x, y);
return center;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
if (msg != null) {
// calculate positions
g.setFont(msgFont);
FontMetrics m = g.getFontMetrics();
Point msgCenter = getCenter(msg, m, width, height);
Point boxPos = new Point(msgCenter.x - 10, msgCenter.y
- m.getAscent() - 10);
// draw message box
Color backgrnd = getBackground();
int red = backgrnd.getRed();
int green = backgrnd.getGreen();
int blue = backgrnd.getBlue();
int alpha = backgrnd.getAlpha();
g.setColor(new Color(red, green, blue,
alpha <= 205 ? alpha + 50 : 255));
g.fillRoundRect(boxPos.x, boxPos.y, m.stringWidth(msg) + 20, m
.getHeight() + 20, 10, 10);
g.setColor(msgColor);
g.drawRoundRect(boxPos.x, boxPos.y, m.stringWidth(msg) + 20, m
.getHeight() + 20, 10, 10);
// draw message text
g.setColor(msgColor);
g.drawString(msg, msgCenter.x, msgCenter.y);
}
}
@Override
public void keyPressed(KeyEvent e) {
e.consume();
}
@Override
public void keyReleased(KeyEvent e) {
e.consume();
}
@Override
public void keyTyped(KeyEvent e) {
e.consume();
}
}
}