(Swing) JFrame inkl. Lock-Option

Status
Nicht offen für weitere Antworten.

hdi

Top Contributor
Hi,

@mods
ich hoffe dass ihr das nicht als totale Unwichtigkeit anseht, vorallem weil es kein Tutorial ist oder überhaupt irgndeine Frage beantwortet.. Es ist einfach nur ein Stück Code den jeder verwenden kann.
Wenn euch das nicht in die FAQ passt, dann einfach löschen.

Die folgende Klasse stellt ein JFrame bereit, dass ziemlich einfach für Nutzereingaben gesperrt und entsperrt werden kann. Es legt dabei eine Schicht über das Frame, die Eingaben abblockt, und zeigt optional auch eine Message für den User an:

Java:
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();
		}
	}
}

Benutzen tut man das ganze dann zB so:

Java:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;

import javax.swing.JButton;
import javax.swing.JFrame;

public class LockableJFrameTest {

	public static void main(String[] args) {

		final LockableJFrame lockFrame = new LockableJFrame(
				"LockableJFrameTest");
		lockFrame.setLockAppearance(new Color(255, 150, 150, 100), Color.WHITE,
				new Font("Arial", Font.BOLD, 22));
		lockFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		lockFrame.setSize(500, 500);

		// show and LOCK
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				lockFrame.setVisible(true);
				lockFrame.lock("Loading elements...");
			}
		});

		// ...
		doSomeStuff(lockFrame);

		// UNLOCK
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				lockFrame.unlock();
			}
		});
	}

	private static void doSomeStuff(final JFrame f) {
		f.setLayout(new FlowLayout());
		for (int i = 0; i <= 359; i++) {
			EventQueue.invokeLater(new Runnable() {
				@Override
				public void run() {
					JButton b = new JButton();
					b.setSize(2, 2);
					f.add(b);
					f.validate();
				}
			});
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
 

javimka

Top Contributor
Das ist wirklich ein super Beispiel, das sieht auch super aus :toll:

Ich hätte noch einen kleinen Vorschlag. Du rufst setEnable(false) auf deinem Frame auf. Dadurch friert das Frame total ein, es kann auch nicht mehr verschoben, minimiert oder geschlossen werden. Wenn der Vorgang im Hintergrund dann doch länger dauert, könnte das etwas ärgerlich sein.
Falls du das ändern willst, könntest du folgendes in den Konstruktor der Lockpane aufnehmen:
Java:
            addMouseListener(new MouseAdapter() { });
            addMouseMotionListener(new MouseMotionAdapter() { });
            addKeyListener(new KeyAdapter() { });
Dann könntest du die setEnable löschen und auch das "implements KeyListener", das du ja nirgendwo angehängt hast.
 

André Uhres

Top Contributor
Die folgende Klasse stellt ein JFrame bereit, dass ziemlich einfach für Nutzereingaben gesperrt und entsperrt werden kann. Es legt dabei eine Schicht über das Frame, die Eingaben abblockt, und zeigt optional auch eine Message für den User an
Das wurde schonmal besser erfunden: Disabled Glass Pane Java Tips Weblog

(Mit deiner Version werden z.B. Tastenkürzel von Swingkomponenten nicht gesperrt: versuch's mal mit Alt+H bei einem JColorChooser.)
 

hdi

Top Contributor
Also soweit ich das sehe ist mein Code genau das gleiche wie dein Link.
Ich hatte nur einen superdummen Fehler gemacht: Hab im Konstruktor vergessen den KeyListener zu adden :oops:
 

hdi

Top Contributor

joa.. ich frage mich nur warum du mir den Link nicht in diesem Thread gegeben hast. Da habe ich doch extra gesagt dass ich da mal n Tutorial gefunden habe aber es nicht mehr finde. Statt dessen lässt du mich das selber zusammenbauen, und wenn ich es dann mit anderen teilen möchte, kommt so ein Kommentar. Wenn also mein Code überflüssig ist dann nehmt doch zumindest den anderen in die FAQ auf. Eine Rubrik "Hilfsklassen" wäre doch mal ne Idee, oder nicht? Dann würden sich manche Leute Arbeit sparen, zB ich :pueh:
 

javimka

Top Contributor
Ein grosser Vorteil dieses Tutorial ist, dass es in diesem Forum ist und nicht auf irgendeiner Webseite. Ausserdem ist es deutsch, ausführlicher und man kann den Code sehen :)
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben