如何使JDialog处于非活动状态

5
我想让基于JDialog的窗口变为非活动状态,这样所有的控件都会显示为禁用状态(灰色)。setEnabled(false)只是使得无法点击任何控件,但是没有任何控件变成灰色。请帮助我解决这个问题。
编辑:以下是示例代码。
import javax.swing.JButton;
import javax.swing.JDialog;


public class Analyzer extends JDialog{

public Analyzer() {
    JButton but = new JButton("test");
    setLayout(null);
    but.setBounds(10,10,100,100);

    add(but);
    setSize( 200, 200);
    setVisible(true);
    setEnabled(false);
}

public static void main(String[] args) {
    new Analyzer();
}

}

1
这不是我们正在寻找的示例。我们想看看您尝试解决这个问题的方法。您是否考虑使用递归来遍历JDialog的容器/组件树,启用或禁用所有找到的组件? - Hovercraft Full Of Eels
是的,我正在考虑这种解决方案,但它似乎有点混乱。也许有更好的方法来做到这一点? - Aleksandr Kravets
1
在对话框上调用setEnabled(false)应该会将其禁用,但它将无法移动,并且其按钮和组件仍然“看起来”启用。 - Hovercraft Full Of Eels
谢谢大家。决定不浪费时间。使用组件迭代。 - Aleksandr Kravets
1
@HovercraftFullOfEels:这就是我在问题中提到的 =) - Aleksandr Kravets
显示剩余5条评论
2个回答

8

我知道两种做法,一种是递归禁用对话框的组件,另一种是禁用整个对话框(包括拖动对话框的能力):

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class DisableEg extends JPanel {
   public static final String DISABLE_DIALOG_COMPONENTS = "Disable Dialog Components";
   public static final String ENABLE_DIALOG_COMPONENTS = "Enable Dialog Components";
   public static final String DISABLE_DIALOG = "Disable Dialog";
   public static final String ENABLE_DIALOG = "Enable Dialog";
   private static final int LOC_SHIFT = 150;
   private Analyzer analyzer;

   public DisableEg(JFrame frame) {
      analyzer = new Analyzer(frame);
      analyzer.pack();
      analyzer.setLocationRelativeTo(frame);
      Point location = analyzer.getLocation();
      location = new Point(location.x - LOC_SHIFT, location.y - LOC_SHIFT);
      analyzer.setLocation(location);
      analyzer.setVisible(true);

      add(new JButton(new AbstractAction(DISABLE_DIALOG_COMPONENTS) {

         @Override
         public void actionPerformed(ActionEvent evt) {
            AbstractButton btn = (AbstractButton) evt.getSource();
            if (btn.getText().equals(DISABLE_DIALOG_COMPONENTS)) {
               btn.setText(ENABLE_DIALOG_COMPONENTS);
               analyzer.setComponentEnabled(false);
            } else {
               btn.setText(DISABLE_DIALOG_COMPONENTS);
               analyzer.setComponentEnabled(true);
            }
         }
      }));
      add(new JButton(new AbstractAction(DISABLE_DIALOG) {

         @Override
         public void actionPerformed(ActionEvent evt) {
            AbstractButton btn = (AbstractButton) evt.getSource();
            if (btn.getText().equals(DISABLE_DIALOG)) {
               btn.setText(ENABLE_DIALOG);
               analyzer.setEnabled(false);
            } else {
               btn.setText(DISABLE_DIALOG);
               analyzer.setEnabled(true);
            }
         }
      }));
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Disable Example");
      DisableEg mainPanel = new DisableEg(frame);

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class Analyzer extends JDialog {

   public Analyzer(JFrame frame) {
      super(frame, "Analyzer Dialog", false);
      JButton but = new JButton("test");
      setLayout(new FlowLayout());

      add(but);
      setPreferredSize(new Dimension(200, 200));
   }

   public void setComponentEnabled(boolean enabled) {
      setComponentEnabled(enabled, getContentPane());

      // !! if you have menus to disable, you may need instead
      // setComponentEnabled(enabled, this); // !!
   }

   private void setComponentEnabled(boolean enabled, Component component) {
      component.setEnabled(enabled);
      if (component instanceof Container) {
         Component[] components = ((Container) component).getComponents();
         if (components != null && components.length > 0) {
            for (Component heldComponent : components) {
               setComponentEnabled(enabled, heldComponent);
            }
         }
      }
   }

}

4

通常的做法是使用glassPane,但Java 7引入了JLayer,也可以完成此操作。


如果我正确理解了OP的问题,那么这种方法行不通,因为他希望组件显示为禁用状态。据我所知,通常的做法是使用递归。 - Hovercraft Full Of Eels
1
这种方式非常舒适,GlassPane可以着色,如此简单而且不可通过鼠标访问,很好的线程 +1(@Pete伟大的代码++++++++) - mKorbel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接