如何禁用JPanel中的所有组件

时间:2013-10-11 18:28:50

标签: java swing jpanel components

在我的JPanel中,我有很多组件,包括其他JPanel,JLabel,JTextAreas和JButton。因为我想实现一个教程模式,其中出现另一个窗口,我的主JPanel中的所有内容都被禁用,因为新窗口逐个解释每个'功能'...我想要知道如何禁用我内部的所有组件原始JPanel。我知道你可以使用:

component.setEnabled(false);

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

注意:嵌套的JPanel中也有组件,例如订单

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

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

谢谢!感谢所有帮助!

7 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分:7)

我使用了以下功能:

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);
    }
}

答案 2 :(得分:4)

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

答案 3 :(得分: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了解详情

答案 4 :(得分:2)

轻松快捷的方式:)

for (Component cp : yourPanle.getComponents() ){
        cp.setEnabled(false);
 }

答案 5 :(得分:0)

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

像魅力一样工作。由于问题经常出现,我今天早些时候看到这篇文章,这里是班级:

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);
                    }
                }
            }
        }
    }


}

答案 6 :(得分:0)

100002

您可以在JPanel中像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); } } 一样拨打电话。