如何在Java中禁用GUI按钮

3

我有一个与GUI相关的小代码:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.BoxLayout;
import javax.swing.JSeparator;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class IPGUI extends JFrame implements ActionListener 
{
    private static JPanel contentPane;
    private static boolean btn1Clicked = false;
    private static boolean btn2Clicked = false;
    private static boolean btn3Clicked = false;
    private static boolean btn4Clicked = false;

    //Create the frame
    public IPGUI() 
    {
        //Sets frame properties
        setTitle("IP Extractor");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 250, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        //Creates new JPanel with boxlayout
        JPanel panel = new JPanel();
        contentPane.add(panel, BorderLayout.CENTER);
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

        //////////////////New Button//////////////////

        JButton btnConvertDocuments = new JButton("1. Convert Documents");
        btnConvertDocuments.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnConvertDocuments.setMaximumSize(new Dimension(160, 0));
        btnConvertDocuments.setPreferredSize(new Dimension(0, 50));

        panel.add(btnConvertDocuments);

        btnConvertDocuments.setActionCommand("w");
        btnConvertDocuments.addActionListener((ActionListener) this);

        if (btn1Clicked == true)
        {
            btnConvertDocuments.setEnabled(false);
        }

        JSeparator separator_3 = new JSeparator();
        panel.add(separator_3);

        //////////////////New Button//////////////////

        JButton btnExtractImages = new JButton("2. Extract Images");
        btnExtractImages.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnExtractImages.setMaximumSize(new Dimension(160, 0));
        btnExtractImages.setPreferredSize(new Dimension(0, 50));

        panel.add(btnExtractImages);

        btnExtractImages.setActionCommand("x");
        btnExtractImages.addActionListener((ActionListener) this);

         if (btn2Clicked == true)
         {
             btnExtractImages.setEnabled(false);
         }

        JSeparator separator_2 = new JSeparator();
        panel.add(separator_2);

        //////////////////New Button//////////////////

        JButton btnParseRIDValues = new JButton("3. Parse rId Values");
        btnParseRIDValues.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnParseRIDValues.setMaximumSize(new Dimension(160, 0));
        btnParseRIDValues.setPreferredSize(new Dimension(0, 50));

        panel.add(btnParseRIDValues);

        btnParseRIDValues.setActionCommand("y");
        btnParseRIDValues.addActionListener((ActionListener) this);

        if (btn3Clicked == true)
        {
            btnParseRIDValues.setEnabled(false);
        }

        JSeparator separator_1 = new JSeparator();
        panel.add(separator_1);

        //////////////////New Button//////////////////

        JButton btnParseImageInfo = new JButton("4. Parse Image Info.");
        btnParseImageInfo.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnParseImageInfo.setMaximumSize(new Dimension(160, 0));
        btnParseImageInfo.setPreferredSize(new Dimension(0, 50));

        panel.add(btnParseImageInfo);

        btnParseImageInfo.setActionCommand("z");
        btnParseImageInfo.addActionListener((ActionListener) this);

        if (btn4Clicked == true)
        {
            btnParseImageInfo.setEnabled(false);
        }
    }

    public void actionPerformed(ActionEvent event) 
    {
        String command = event.getActionCommand();

        if (command.equals("w"))
        {
            FileConverter fc = new FileConverter();
            btn1Clicked = true;
        }
        else if (command.equals("x"))
        {
            ImageExtractor ie = new ImageExtractor();
            btn2Clicked = true;
        }
        else if (command.equals("y")) 
        {
            XMLIDParser xip = new XMLIDParser();
            btn3Clicked = true;
        }
        else if (command.equals("z")) 
        {
            XMLTagParser xtp = new XMLTagParser();
            btn4Clicked = true;
        }
    }    
}

我想要特别关注的是这个条件语句:

 if (btn1Clicked == true)
        {
            btnConvertDocuments.setEnabled(false);
        }

所以我的想法是该命令应该这样操作:一旦按钮被点击,执行操作的方法将被调用,btnClicked应该设置为true,那么该按钮就应该被禁用。有人能解释我在哪里出错了吗?或者我这里的想法正确吗?非常感谢您提供任何帮助!

你没有说明它没有做你想要的事情。我知道这很明显,但当你点击按钮时会发生什么?有任何错误吗? - DaMainBoss
它仅仅是不能禁用按钮,用户可以重复点击该按钮(这不是我想要的)。但是,我已经修复了它。谢谢你 :). - This 0ne Pr0grammer
8个回答

10

你应该将语句btnConvertDocuments.setEnabled(false);放在actionPerformed(ActionEvent event)方法中。你上面的条件判断只会在构造函数中IPGUI对象被实例化时调用一次。

if (command.equals("w")) {
    FileConverter fc = new FileConverter();
    btn1Clicked = true;
    btnConvertDocuments.setEnabled(false);
}

我尝试过了,但问题在于btnConvertDocuments是一个局部变量。我可以将其变为静态变量,只是想知道这样做是否有害? - This 0ne Pr0grammer
然后将 btnConvertDocuments 设为实例变量。不要将其设为静态变量。 - user802421

4

如果从Listener调用GUI输出,那么禁用JComponent(s)是不可能的,在所有情况下,所有事件都在EDT中,包括setEnabled/setVisible

只有当EDT中的所有事件结束时,JComponent(s)才被禁用/可见。

有三种方法:

1/ 最安全的方法是查找 GlassPane,它可以防止所有MouseEvents(而不是KeyEvents),最好的代码是 camickr's

2/ 使用多线程和SwingWorker延迟分离具体事件,例如Action from JComponent -> disable JComponent(s) in GUI -> then required Action,但是在这种情况下,您必须使用myAction#putProperty("String","String")来识别所有操作(如果可能)。

3/ 将 Enabled/Visible 放入 invokeLater() 中,所有来自 Listener 的 Action 必须包装在 invokeAndWait() 中。

4/ 在 Runnable()#Thread 内部。


3

不要使用布尔值,为什么不在单击按钮时将其设置为false,因此您可以在actionPerformed方法中执行该操作。这更有效率。

if (command.equals("w"))
{
    FileConverter fc = new FileConverter();
    btnConvertDocuments.setEnabled(false);
}

2
一旦您创建了框架,带有条件的代码部分将不会被执行。换句话说,在执行测试 if (btn1Clicked == true) 时,按钮不仅尚未被点击,甚至还没有显示给用户。
放弃布尔值,并将包含 btnConvertDocuments.setEnabled(false) 的行移动到您的 actionListener 中。使按钮成为实例变量,不要使它们成为静态变量。(或者,您可以将按钮保留为局部变量,并为每个按钮分配其自己的匿名内部类侦听器。)

2

您可以创建一个带有启用按钮的框架,进行一些测试以查看btn1Clicked是否为true,这就是全部操作。

然后您可以使用actionPerformed方法对按钮不做任何操作。因此,如果没有任何相关操作,您的按钮状态将永远不会再次被评估。


2

您为什么不采取以下这样的做法:

public class IPGUI extends JFrame implements ActionListener 
{
    private static JPanel contentPane;

    private JButton btnConvertDocuments;
    private JButton btnExtractImages;
    private JButton btnParseRIDValues;
    private JButton btnParseImageInfo;

    public IPGUI() 
    {
        ...

        btnConvertDocuments = new JButton("1. Convert Documents");

        ...

        btnExtractImages = new JButton("2. Extract Images");

        ...

        //etc.
    }

    public void actionPerformed(ActionEvent event) 
    {
        String command = event.getActionCommand();

        if (command.equals("w"))
        {
            FileConverter fc = new FileConverter();
            btnConvertDocuments.setEnabled( false );
        }
        else if (command.equals("x"))
        {
            ImageExtractor ie = new ImageExtractor();
            btnExtractImages.setEnabled( false );
        }

        // etc.
    }    
}

您禁用代码的if语句,除非您不断调用IPGUI构造函数,否则不会被调用。

非常感谢您,先生。并且,没有特别的原因,只是我编写代码的方式。我本来想给您答案的,但是有一个用户在之前已经说了,我很抱歉。再次感谢您。 - This 0ne Pr0grammer

2
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.BoxLayout;
import javax.swing.JSeparator;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;


public class IPGUI extends JFrame implements ActionListener 
{
    private static JPanel contentPane;

    private JButton btnConvertDocuments;
    private JButton btnExtractImages;
    private JButton btnParseRIDValues;
    private JButton btnParseImageInfo;

    //Create the frame
    public IPGUI() 
    {
        //Sets frame properties
        setTitle("IP Extractor");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 250, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        //Creates new JPanel with boxlayout
        JPanel panel = new JPanel();
        contentPane.add(panel, BorderLayout.CENTER);
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

        //////////////////New Button//////////////////

        JButton btnConvertDocuments = new JButton("1. Convert Documents");
        btnConvertDocuments.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnConvertDocuments.setMaximumSize(new Dimension(160, 0));
        btnConvertDocuments.setPreferredSize(new Dimension(0, 50));

        panel.add(btnConvertDocuments);

        btnConvertDocuments.setActionCommand("w");
        btnConvertDocuments.addActionListener((ActionListener) this);

        JSeparator separator_3 = new JSeparator();
        panel.add(separator_3);

        //////////////////New Button//////////////////

        btnExtractImages = new JButton("2. Extract Images");
        btnExtractImages.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnExtractImages.setMaximumSize(new Dimension(160, 0));
        btnExtractImages.setPreferredSize(new Dimension(0, 50));

        panel.add(btnExtractImages);

        btnExtractImages.setActionCommand("x");
        btnExtractImages.addActionListener((ActionListener) this);

        JSeparator separator_2 = new JSeparator();
        panel.add(separator_2);

        //////////////////New Button//////////////////

        JButton btnParseRIDValues = new JButton("3. Parse rId Values");
        btnParseRIDValues.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnParseRIDValues.setMaximumSize(new Dimension(160, 0));
        btnParseRIDValues.setPreferredSize(new Dimension(0, 50));

        panel.add(btnParseRIDValues);

        btnParseRIDValues.setActionCommand("y");
        btnParseRIDValues.addActionListener((ActionListener) this);

        JSeparator separator_1 = new JSeparator();
        panel.add(separator_1);

        //////////////////New Button//////////////////

        JButton btnParseImageInfo = new JButton("4. Parse Image Info.");
        btnParseImageInfo.setAlignmentX(Component.CENTER_ALIGNMENT);
        btnParseImageInfo.setMaximumSize(new Dimension(160, 0));
        btnParseImageInfo.setPreferredSize(new Dimension(0, 50));

        panel.add(btnParseImageInfo);

        btnParseImageInfo.setActionCommand("z");
        btnParseImageInfo.addActionListener((ActionListener) this);
    }

    public void actionPerformed(ActionEvent event) 
    {
        String command = event.getActionCommand();

        if (command.equals("w"))
        {
            FileConverter fc = new FileConverter();
            btnConvertDocuments.setEnabled(false);
        }
        else if (command.equals("x"))
        {
            ImageExtractor ie = new ImageExtractor();
            btnExtractImages.setEnabled(false);
        }
        else if (command.equals("y")) 
        {
            XMLIDParser xip = new XMLIDParser();
            btnParseRIDValues.setEnabled(false);
        }
        else if (command.equals("z")) 
        {
            XMLTagParser xtp = new XMLTagParser();
            btnParseImageInfo.setEnabled(false);        
        }
    }


}

感谢大家的帮助,我想到了以下解决方案。再次感谢大家的意见,非常感激!


0

不如在点击按钮时将其设置为false,而不是使用布尔值,这样你可以在actionPerformed方法中完成。这样更有效率。

if (command.equals("w"))
{
    FileConverter fc = new FileConverter();
    btnConvertDocuments.setEnabled(false);
}

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