7

我有一个 JPanel,其中包含一个 JToolbar(包括几个没有文本的按钮)和一个 JTable,我需要启用/禁用(使内部小部件不可点击)。我试过这个:

 JPanel panel = ....;
 for (Component c : panel.getComponents()) c.setEnabled(enabled);

但它不起作用。是否有更好、更通用的解决方案来启用/禁用 JPanel 中的所有内部组件?

从这里的示例http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html开始,我已经使用 JLayer 部分解决了我的问题:

layer = new JLayer<JComponent>(myPanel, new BlurLayerUI(false));
.....
((BlurLayerUI)layer.getUI()).blur(...); // switch blur on/off


class BlurLayerUI extends LayerUI<JComponent> {
  private BufferedImage mOffscreenImage;
  private BufferedImageOp mOperation;

  private boolean blur;

  public BlurLayerUI(boolean blur) {
      this.blur = blur;
      float ninth = 1.0f / 9.0f;
        float[] blurKernel = {
          ninth, ninth, ninth,
          ninth, ninth, ninth,
          ninth, ninth, ninth
        };
        mOperation = new ConvolveOp(
                new Kernel(3, 3, blurKernel),
                ConvolveOp.EDGE_NO_OP, null);
        }

  public void blur(boolean blur) {
      this.blur=blur;
    firePropertyChange("blur", 0, 1);
   }

  @Override
  public void paint (Graphics g, JComponent c) {
      if (!blur) {
            super.paint (g, c);
            return;
        }

      int w = c.getWidth();
    int h = c.getHeight();



    if (w == 0 || h == 0) {
      return;
    }

    // Only create the offscreen image if the one we have
    // is the wrong size.
    if (mOffscreenImage == null ||
            mOffscreenImage.getWidth() != w ||
            mOffscreenImage.getHeight() != h) {
      mOffscreenImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    }

    Graphics2D ig2 = mOffscreenImage.createGraphics();
    ig2.setClip(g.getClip());
    super.paint(ig2, c);
    ig2.dispose();

    Graphics2D g2 = (Graphics2D)g;
    g2.drawImage(mOffscreenImage, mOperation, 0, 0);
  }

  @Override
  public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {
    if ("blur".equals(pce.getPropertyName())) {
      l.repaint();
    }
  }

}

我还有两个问题:

  1. 在上面的链接中,事件仅与鼠标相关。如何管理键盘事件?

  2. 如何创建“灰色”效果来代替模糊?

4

4 回答 4

44

它需要递归调用。

禁用所有容器

import java.awt.*;
import javax.swing.*;

public class DisableAllInContainer {

    public void enableComponents(Container container, boolean enable) {
        Component[] components = container.getComponents();
        for (Component component : components) {
            component.setEnabled(enable);
            if (component instanceof Container) {
                enableComponents((Container)component, enable);
            }
        }
    }

    DisableAllInContainer() {
        JPanel gui = new JPanel(new BorderLayout());

        final JPanel container = new JPanel(new BorderLayout());
        gui.add(container, BorderLayout.CENTER);

        JToolBar tb = new JToolBar();
        container.add(tb, BorderLayout.NORTH);
        for (int ii=0; ii<3; ii++) {
            tb.add(new JButton("Button"));
        }

        JTree tree = new JTree();
        tree.setVisibleRowCount(6);
        container.add(new JScrollPane(tree), BorderLayout.WEST);

        container.add(new JTextArea(5,20), BorderLayout.CENTER);

        final JCheckBox enable = new JCheckBox("Enable", true);
        enable.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent ae) {
                enableComponents(container, enable.isSelected());
            }
        });
        gui.add(enable, BorderLayout.SOUTH);

        JOptionPane.showMessageDialog(null, gui);
    }

    public static void main(String[] args)  {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                new DisableAllInContainer();
            }
        });
    }}
于 2012-06-11T19:42:38.100 回答
5

我使用了以下功能:

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

    Component[] components = panel.getComponents();

    for(int i = 0; i < components.length; i++) {
        if(components[i].getClass().getName() == "javax.swing.JPanel") {
            setPanelEnabled((JPanel) components[i], isEnabled);
        }

        components[i].setEnabled(isEnabled);
    }
}
于 2015-09-09T14:02:05.817 回答
2

你可以覆盖整个Container / JComponent

  1. GlassPane默认情况下阻止 MouseEvents,但不是 Keyboard,需要使用 ToolKit 中的所有键事件

  2. JLayer(Java7) 基于JXLayer(Java6)

  3. 看不到为什么不适合你的原因

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class AddComponentsAtRuntime {

    private JFrame f;
    private JPanel panel;
    private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;

    public AddComponentsAtRuntime() {
        JButton b = new JButton();
        //b.setBackground(Color.red);
        b.setBorder(new LineBorder(Color.black, 2));
        b.setPreferredSize(new Dimension(600, 20));
        panel = new JPanel(new GridLayout(0, 1));
        panel.add(b);
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(panel, "Center");
        f.add(getCheckBoxPanel(), "South");
        f.setLocation(200, 200);
        f.pack();
        f.setVisible(true);
    }

    private JPanel getCheckBoxPanel() {
        checkValidate = new JCheckBox("validate");
        checkValidate.setSelected(false);
        checkReValidate = new JCheckBox("revalidate");
        checkReValidate.setSelected(true);
        checkRepaint = new JCheckBox("repaint");
        checkRepaint.setSelected(true);
        checkPack = new JCheckBox("pack");
        checkPack.setSelected(true);
        JButton addComp = new JButton("Add New One");
        addComp.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JButton b = new JButton();
                //b.setBackground(Color.red);
                b.setBorder(new LineBorder(Color.black, 2));
                b.setPreferredSize(new Dimension(400, 10));
                panel.add(b);
                makeChange();
                System.out.println(" Components Count after Adds :" + panel.getComponentCount());
            }
        });
        JButton removeComp = new JButton("Remove One");
        removeComp.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int count = panel.getComponentCount();
                if (count > 0) {
                    panel.remove(0);
                }
                makeChange();
                System.out.println(" Components Count after Removes :" + panel.getComponentCount());
            }
        });
        JButton disabledComp = new JButton("Disabled All");
        disabledComp.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                for (Component c : panel.getComponents()) {
                    c.setEnabled(false);
                }
            }
        });
        JButton enabledComp = new JButton("Enabled All");
        enabledComp.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                for (Component c : panel.getComponents()) {
                    c.setEnabled(true);
                }
            }
        });
        JPanel panel2 = new JPanel();
        panel2.add(checkValidate);
        panel2.add(checkReValidate);
        panel2.add(checkRepaint);
        panel2.add(checkPack);
        panel2.add(addComp);
        panel2.add(removeComp);
        panel2.add(disabledComp);
        panel2.add(enabledComp);
        return panel2;
    }

    private void makeChange() {
        if (checkValidate.isSelected()) {
            panel.validate();
        }
        if (checkReValidate.isSelected()) {
            panel.revalidate();
        }
        if (checkRepaint.isSelected()) {
            panel.repaint();
        }
        if (checkPack.isSelected()) {
            f.pack();
        }
    }

    public static void main(String[] args) {
        AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
    }
}
于 2012-06-11T18:56:50.080 回答
0

@Kesavamoorthi 如果你想让它更通用:

void setPanelEnabled(java.awt.Container cont, Boolean isEnabled) {
    cont.setEnabled(isEnabled);

    java.awt.Component[] components = cont.getComponents();

    for (int i = 0; i < components.length; i++) {
        if (components[i] instanceof java.awt.Container) {
            setPanelEnabled((java.awt.Container) components[i], isEnabled);
        }
        components[i].setEnabled(isEnabled);
    }
}
于 2018-10-15T09:00:21.640 回答