如何禁用JFrame中几乎所有的组件



当我开始一些处理时,我想禁用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的一部分)。

这个解决方案需要额外的库,但它更加灵活和优雅。

相关内容

  • 没有找到相关文章

最新更新