当我开始一些处理时,我想禁用GUI中的JButtons、JText、Lists等,只有一个按钮可以停止处理。
什么是干净的方法?我用setEnabled(false)逐个组件地设置,但代码太大了。
我可以获取数组中的所有组件,并将其设置在for循环中吗?我是怎么做到的?还有别的办法吗?
您可以使用"禁用玻璃窗格"方法。
或者,使用JOptionPane并显示类似"Processing…."的消息。处理完成后,关闭对话框。阅读API,获取如何创建选项窗格的示例,以便您可以访问所使用的实际对话框。您将需要对话框的引用,以便关闭它。
编辑:
有关示例,请参阅:如何制作对话框。
你可以试试这个类:
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;
}
}
}
你可以用("这个"指的是你的JFrame)来称呼它:
Blocker.instance().setRestrictedComponents(this.getComponents());
还有一种方法是使用带有LockableUI的JXLayer(不久将作为JLayer成为Swing的一部分)。
这个解决方案需要额外的库,但它更加灵活和优雅。