How to disable almost all components in a JFrame?
When I start some processing, I want to disable the JButtons, JText, Lists, etc. in the GUI, only having one 开发者_StackOverflow中文版button to stop the processing.
What is a clean way to do this? I was setting component by component with setEnabled(false), but the code was too big.
Can I get all the components in an array and set all inside a for loop? How I do this? There is another way?
You can use the Disabled Glass Pane approach.
Or, use a JOptionPane with a message like "Processing....". When the processing is finished you close the dialog. Read the API for an example of how to create the option pane so that you have access to the actual dialog used. You will need the reference to the dialog so you can close it.
Edit:
See: How to Make Dialogs for examples.
you could try this class :
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.FocusManager;
public class Blocker extends EventQueue {
private Component[] restrictedComponents;
private Vector helperVector;
private boolean inBlockedState = false;
private EventQueue sysQ = Toolkit.getDefaultToolkit().getSystemEventQueue();
private boolean alreadyBlockedOnce = false;
private static Blocker instance = null;
public static synchronized Blocker Instance() {
if (instance == null) {
instance = new Blocker();
}
return instance;
}
private Blocker() {
restrictedComponents = null;
}
private void reset() {
if (inBlockedState) {
setBlockingEnabled(false);
}
restrictedComponents = null;
}
public void setRestrictedComponents(Component[] restrictedComponents) {
reset(); // puts the Blocker into an unblocked state, and clears the
// restrictedComponents array (see private method below)
helperVector = new Vector();
// global Vector variable
if (restrictedComponents != null) {
extractAllComponents(restrictedComponents);
}
// builds the blockedComponent array
if (helperVector.size() >= 1) {
this.restrictedComponents = new Component[helperVector.size()];
for (int k = 0; k < helperVector.size(); k++) {
this.restrictedComponents[k] = (Component) helperVector
.elementAt(k);
}
} else {
this.restrictedComponents = null;
}
}
private void extractAllComponents(Component[] array) {
for (int i = 0; i < array.length; i++) {
if (array[i] != null) {
helperVector.addElement(array[i]);
if (((Container) array[i]).getComponentCount() != 0) {
extractAllComponents(((Container) array[i]).getComponents());
}
}
}
}
private void adjustFocusCapabilities(boolean blocked) {
if (blocked) {
for (int i = 0; i < restrictedComponents.length; i++) {
this.restrictedComponents[i].setEnabled(false);
if (restrictedComponents[i] instanceof JComponent) {
((JComponent) restrictedComponents[i])
.setRequestFocusEnabled(false);
((JComponent) restrictedComponents[i]).setEnabled(false);
}
// removes the focus indicator from all components that are
// capable
// of painting their focus
if (restrictedComponents[i] instanceof AbstractButton) {
((AbstractButton) restrictedComponents[i])
.setFocusPainted(false);
((AbstractButton) restrictedComponents[i])
.setEnabled(false);
}
}
} else {
for (int k = 0; k < restrictedComponents.length; k++) {
this.restrictedComponents[k].setEnabled(true);
if (restrictedComponents[k] instanceof JComponent) {
((JComponent) restrictedComponents[k])
.setRequestFocusEnabled(true);
}
if (restrictedComponents[k] instanceof AbstractButton) {
((AbstractButton) restrictedComponents[k])
.setFocusPainted(true);
}
}
}
}
private Component getSource(AWTEvent event) {
Component source = null;
// each of these five MouseEvents will still be valid (regardless
// of their source), so we still want to process them.
if ((event instanceof MouseEvent)
&& (event.getID() != MouseEvent.MOUSE_DRAGGED)
&& (event.getID() != MouseEvent.MOUSE_ENTERED)
&& (event.getID() != MouseEvent.MOUSE_EXITED)
&& (event.getID() != MouseEvent.MOUSE_MOVED)
&& (event.getID() != MouseEvent.MOUSE_RELEASED)) {
MouseEvent mouseEvent = (MouseEvent) event;
source = SwingUtilities.getDeepestComponentAt(mouseEvent
.getComponent(), mouseEvent.getX(),
mouseEvent.getY());
} else if (event instanceof KeyEvent
&& event.getSource() instanceof Component) {
source = SwingUtilities.findFocusOwner((Component) (event
.getSource()));
}
return source;
}
private boolean isSourceBlocked(Component source) {
boolean blocked = false;
if ((restrictedComponents != null) && (source != null)) {
int i = 0;
while (i < restrictedComponents.length
&& (restrictedComponents[i].equals(source) == false))
i++;
blocked = i < restrictedComponents.length;
}
return blocked;
}
protected void dispatchEvent(AWTEvent event) {
boolean blocked = false;
if (inBlockedState) {
// getSource is a private helper method
blocked = isSourceBlocked(getSource(event));
}
if (blocked
&& (event.getID() == MouseEvent.MOUSE_CLICKED || event.getID() == MouseEvent.MOUSE_PRESSED)) {
Toolkit.getDefaultToolkit().beep();
}
else if (blocked && event instanceof KeyEvent
&& event.getSource() instanceof Component) {
DefaultFocusManager dfm = new DefaultFocusManager();
FocusManager.getCurrentManager();
Component currentFocusOwner = getSource(event);
boolean focusNotFound = true;
do {
dfm.focusNextComponent(currentFocusOwner);
currentFocusOwner = SwingUtilities
.findFocusOwner((Component) event.getSource());
if (currentFocusOwner instanceof JComponent) {
focusNotFound = (((JComponent) currentFocusOwner)
.isRequestFocusEnabled() == false);
}
} while (focusNotFound);
} else {
super.dispatchEvent(event);
}
}
public void setBlockingEnabled(boolean block) {
// this methods must be called from the AWT thread to avoid
// toggling between states while events are being processed
if (block && !inBlockedState && restrictedComponents != null) {
adjustFocusCapabilities(true);
// "adjustFocusCapabilities" is a private helper function that
// sets the focusEnabled & focusPainted flags for the
// appropriate components. Its boolean parameter signifies
// whether we are going into a blocked or unblocked state
// (true = blocked, false = unblocked)
if (!alreadyBlockedOnce) {
// here is where we replace the SystemQueue
sysQ.push(this);
alreadyBlockedOnce = true;
}
inBlockedState = true;
} else if (!block && inBlockedState) {
adjustFocusCapabilities(false);
inBlockedState = false;
}
}
}
you can call it with ('this' refers to your JFrame):
Blocker.instance().setRestrictedComponents(this.getComponents());
One more approach would be to use JXLayer (soon to be part of Swing as JLayer) with LockableUI.
This solution requires additional library but it is infinitely more flexible and elegant.
精彩评论