8

在我的 JPanel 中,我有许多组件,包括其他 JPanel、JLabels、JTextAreas 和 JButton。因为我想实现一个教程模式,其中出现另一个窗口并且我的主 JPanel 中的所有内容都被禁用,因为新窗口一个一个地解释了每个“功能”......我想知道如何禁用我里面的所有组件原始JPanel。我知道你可以使用:

component.setEnabled(false);

但我不想为我的 JPanel 中的每个组件编写它。我想知道是否可以使用 for 循环或其他方式禁用我的 JPanel 中的所有组件?

注意:嵌套的 JPanel 中也有组件,就像顺序一样

主 JPanel ---> 嵌套 JPanel ---> 组件

我还希望最终组件也被禁用......

谢谢!感谢所有帮助!

4

7 回答 7

11

我使用了以下功能:

void setPanelEnabled(JPanel panel, Boolean isEnabled) {
    panel.setEnabled(isEnabled);

    Component[] components = panel.getComponents();

    for (Component component : components) {
        if (component instanceof JPanel) {
            setPanelEnabled((JPanel) component, isEnabled);
        }
        component.setEnabled(isEnabled);
    }
}
于 2015-09-09T13:58:12.007 回答
8

查看Disabled Panel以获得一些解决方案。

一种使用禁用的 GlassPane 类型的方法,另一种递归禁用组件,同时跟踪组件的当前状态,以便以后可以正确启用。

于 2013-10-11T19:36:51.830 回答
3

JPanel 是一个容器。容器有一个 getComponents() 方法。您应该递归地遍历组件树。
如果当前孩子也是一个容器(instanceof),您可以进行另一个递归调用,否则您只需调用 setEnabled(false)。

于 2013-10-11T18:34:15.823 回答
3

简单快捷的方法:)

for (Component cp : yourPanle.getComponents() ){
        cp.setEnabled(false);
 }
于 2016-10-07T04:40:55.640 回答
2

不久前我实现了一个解决方案JXLayer,它使用它的锁定效果功能在容器上提供一个“阻塞”层。

它基于JXLayer 3.x并使用来自JHLabs的过滤器来生成它的“灰度”效果

import com.jhlabs.image.GrayscaleFilter;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.LayoutManager;
import java.awt.RenderingHints;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JPanel;
import org.jdesktop.jxlayer.JXLayer;
import org.jdesktop.jxlayer.QualityHints;
import org.jdesktop.jxlayer.plaf.BetterBufferedImageOpEffect;
import org.jdesktop.jxlayer.plaf.LayerUI;
import org.jdesktop.jxlayer.plaf.ext.LockableUI;

public class CoreXPane extends JPanel {

    private JXLayer<JPanel> layer;
    private FadedLockUI fadedLockUI;
    private JPanel pnlBody;

    public CoreXPane(LayoutManager layout) {

        super.setLayout(new BorderLayout());
        super.addImpl(getLayer(), BorderLayout.CENTER, 0);

        setLayout(layout);

    }

    public CoreXPane() {

        this(new BorderLayout());

    }

    @Override
    public void setEnabled(boolean enabled) {

        getLockUI().setLocked(!enabled);
        getBodyPane().setEnabled(enabled);
        super.setEnabled(enabled);

    }

    @Override
    protected void addImpl(Component comp, Object constraints, int index) {

        getBodyPane().add(comp, constraints, index);

    }

    @Override
    public void remove(int index) {

        getBodyPane().remove(index);

    }

    @Override
    public void removeAll() {

        getBodyPane().removeAll();

    }

    protected FadedLockUI getLockUI() {

        if (fadedLockUI == null) {

            fadedLockUI = new FadedLockUI();

        }

        return fadedLockUI;

    }

    @Override
    public void invalidate() {

        getLockUI().invalidate();

        super.invalidate();

    }

    @Override
    public void revalidate() {

        getLockUI().revalidate();
        super.revalidate();

    }

    @Override
    public void repaint() {

        getLockUI().repaint();

        super.repaint();

    }

    protected void getLayers(List<LayerUI> layers) {

        layers.add(getLockUI());

    }

    protected JXLayer<JPanel> getLayer() {

        if (layer == null) {

            List<LayerUI> layers = new ArrayList<LayerUI>(4);
            getLayers(layers);

            JComponent wrapper = getBodyPane();
            for (LayerUI ui : layers) {

                wrapper = new JXLayer(wrapper, ui);

            }

            layer = (JXLayer<JPanel>) wrapper;

        }

        return layer;

    }

    @Override
    public void setLayout(LayoutManager mgr) {

        getBodyPane().setLayout(mgr);

    }

    @Override
    public LayoutManager getLayout() {

        return getBodyPane().getLayout();

    }

    public JPanel getBodyPane() {

        if (pnlBody == null) {

            pnlBody = new JPanel();
            pnlBody.setLayout(new BorderLayout());

        }

        return pnlBody;

    }

    @Override
    public void setOpaque(boolean isOpaque) {

        super.setOpaque(isOpaque);
        getBodyPane().setOpaque(isOpaque);

    }

    public static class FadedLockUI extends LockableUI {

        public static Map<RenderingHints.Key, Object> mapRenderHints = new QualityHints();

        public FadedLockUI() {

            setLockedEffects(new BufferedImageOpEffect(new GrayscaleFilter()));

            mapRenderHints.put(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); // okay
            mapRenderHints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // bad
            mapRenderHints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); // okay
            mapRenderHints.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            mapRenderHints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            mapRenderHints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            mapRenderHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

        }

        @Override
        protected Map<RenderingHints.Key, Object> getRenderingHints(JXLayer<? extends JComponent> l) {
            return mapRenderHints;
        }

        public void repaint() {
            setDirty(true);
        }

        public void invalidate() {
            setDirty(true);
        }

        public void revalidate() {
            setDirty(true);
        }
    }
}

查看LockableUI了解更多详情

于 2013-10-11T22:42:17.020 回答
1

我刚刚创建了一个小类,它递归地禁用给定容器内的所有内容,然后重新启用之前禁用的每个组件(以相反的顺序)。它还允许从禁用中排除任意组件,这是我添加的一个功能,因为 JLabels 在禁用时看起来不必要地难看。

奇迹般有效。由于这个问题经常出现,而且我今天早些时候碰巧看到了这篇文章,所以这是课程:

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Purpose: To recursively disable (and later re-enable) all components of a container, e.g. if you want to clearly show
 * that a program is busy or if you want to prevent clicks and other inputs that piled up meanwhile to affect a window
 * once the program becomes responsive again. Though the solution for that would be simpler: Just disable the window and
 * then, in a SwingUtilities.invokeLater(), re-enable it. This makes sure that before this happens, all input events are
 * eaten.
 */
final public class EverythingDisablerAndReenabler { // v[1, 2016-12-05 14!30 UTC] by dreamspace-president.com

    final private Container rootContainerForWhatShouldBeDisabled;
    final private Class<?>[] componentClassesToBeIgnored;
    final private List<Component> componentsToReenable = new ArrayList<>();

    private boolean disableHasBeenCalled = false; // Order is strictly upheld via IllegalStateException!

    /**
     * @param rootContainerForWhatShouldBeDisabled NOT NULL! The Container whose components are to be recursively
     *                                             disabled. The container itself will not be disabled.
     * @param componentClassesToBeIgnored          null or an array of classes (e.g. containing JLabel.class) that
     *                                             should be excluded from disabling. Adding a Container here does not
     *                                             affect the recursive process.
     * @throws IllegalArgumentException if the container argument is null. In case someone wonders why I don't use
     *                                  {@link NullPointerException} here: Null can be a perfectly legal argument in
     *                                  other places, but here, it is not. If an argument does not check out, the choice
     *                                  of Exception, of course, is IllegalArgument, not NullPointer.
     */
    public EverythingDisablerAndReenabler(final Container rootContainerForWhatShouldBeDisabled, final Class<?>[] componentClassesToBeIgnored) {

        if (rootContainerForWhatShouldBeDisabled == null) {
            throw new IllegalArgumentException();
        }
        this.rootContainerForWhatShouldBeDisabled = rootContainerForWhatShouldBeDisabled;
        this.componentClassesToBeIgnored = componentClassesToBeIgnored;
    }

    /**
     * Disables everything recursively, except the excluded types.
     *
     * @throws IllegalStateException if called twice in a row.
     */
    public void disable() {

        if (disableHasBeenCalled) {
            throw new IllegalStateException();
        }
        disableHasBeenCalled = true;
        componentsToReenable.clear();
        disableEverythingInsideThisHierarchically(rootContainerForWhatShouldBeDisabled);
    }

    /**
     * @throws IllegalStateException if called twice in a row or if disable() had not been called yet.
     */
    public void reenable() {

        if (!disableHasBeenCalled) {
            throw new IllegalStateException();
        }
        disableHasBeenCalled = false;

        for (int i = componentsToReenable.size() - 1; i >= 0; i--) {
            componentsToReenable.get(i).setEnabled(true);
        }
        componentsToReenable.clear();
    }

    private void disableEverythingInsideThisHierarchically(final Container container) {

        final Component[] components = container.getComponents();
        for (Component component : components) {

            if (component != null) {

                // RECURSION FIRST
                if (component instanceof Container) {
                    disableEverythingInsideThisHierarchically((Container) component);
                }

                // AND THEN DEAL WITH THE ELEMENTS
                if (component.isEnabled()) {
                    boolean found = false;
                    if (componentClassesToBeIgnored != null) {
                        for (Class<?> cls : componentClassesToBeIgnored) {
                            if (component.getClass() == cls) {
                                found = true;
                                break;
                            }
                        }
                    }
                    if (!found) {
                        component.setEnabled(false);
                        componentsToReenable.add(component);
                    }
                }
            }
        }
    }


}
于 2016-12-05T14:31:57.500 回答
0
private void disableComponents(Container panel) {

    for (Component c : panel.getComponents()) {
        if (c instanceof Container)
            disableComponents((Container) c);

        c.setEnabled(false);

        if (c instanceof JTextField || c instanceof JTextArea)
            ((JTextComponent) c).setText("");
        if (c instanceof JXDatePicker)
            ((JXDatePicker) c).setDate(null);
        if (c instanceof JComboBox)
            ((JComboBox) c).setSelectedIndex(-1);
        if (c instanceof JCheckBox)
            ((JCheckBox) c).setSelected(false);
    }
}

 private void enableComponents(Container panel) {

    for (Component c : panel.getComponents()) {
        if (c instanceof Container)
            enableComponents((Container) c);
        c.setEnabled(true);
    }
}

disableComponents(this);您可以从您的 JPanel中调用 like 。

于 2020-10-13T06:27:13.067 回答