禁用剩余按钮,单击一个按钮

时间:2014-08-11 05:33:56

标签: java swing jbutton

我在Swing应用程序中禁用/启用按钮时遇到一个小问题。 这是一个非常基本的问题,但我是这个概念的新手。

我有一个要求,例如,有2个按钮可以执行2个单独的操作。

  1. 最初跑步B1& B2应该是可见/已启用。
  2. 如果B1单击,则应禁用B2 /不可见。完成B1工作后,B1和& B2应该是可见/已启用。
  3. 如果B2单击,则应禁用B1 /不可见。 B2工作完成后,B1& B2应该是可见/已启用。
  4. 但是,我的问题是,在处理完B1 / B2后SetEnable / SetVisible工作正常。它应该在启动前禁用,在完成任务后启用

    在这种情况下,任何人都可以提供帮助吗?

    以下是我的代码

    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.WindowConstants;
    
    public class FinCSV implements ActionListener {
    
      JFrame frame = new JFrame("ICON");
      JPanel panel = new JPanel(new GridLayout(2, 1, 4, 4));
      JButton primaryButton = new JButton(" Primary Process");
      JButton secondaryButton = new JButton(" Secondary Process");
    
      public static void main(String[] args)
            throws Exception {
        FinCSV msql = new FinCSV();
        msql.initGUI();
      }
    
      public void initGUI() {
        this.primaryButton.setActionCommand("Primary");
        this.secondaryButton.setActionCommand("Secondary");
        this.primaryButton.addActionListener(this);
        this.secondaryButton.addActionListener(this);
    
        this.primaryButton.setFont(new Font("Serif", Font.BOLD, 22));
        this.secondaryButton.setFont(new Font("Serif", Font.BOLD, 22));
    
        panel.add(this.primaryButton);
        panel.add(this.secondaryButton);
        frame.setContentPane(panel);
        frame.setSize(650, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      }
    
      public void actionPerformed(ActionEvent e) {
    
        if (e.getActionCommand().equals("Primary")) {
             secondaryButton.setVisible(false);
            // secondaryButton.setEnabled(false);
            for (int i = 0; i < 10000; i++) {
                System.out.println("[ " + (i + 1) + " ] Inside Primary Process");
            }
              secondaryButton.setVisible(true);
             // secondaryButton.setEnabled(true);
        } else if (e.getActionCommand().equals("Secondary")) {
            primaryButton.setVisible(false);
             // primaryButton.setEnabled(false);
            for (int i = 0; i < 10000; i++) {
                System.out.println("[ " + (i + 1) + " ] Inside Secondary Process");
            }
            primaryButton.setVisible(true);
          // primaryButton.setEnabled(true);
        }
      }
    }
    

3 个答案:

答案 0 :(得分:2)

不要做任何可能阻止事件调度线程的事情。这里的问题是您在actionPerformed方法

中执行长时间运行的过程
//...
for (int i = 0; i < 10000; i++) {
    System.out.println("[ " + (i + 1) + " ] Inside Primary Process");
}
//..

这阻止它允许EDT处理新的绘制请求(比如绘制禁用的按钮)

请查看Concurrency in Swing了解详情

考虑使用SwingWorker实际执行工作并在完成后重新启用状态。

请查看Worker Threads and SwingWorker了解详情

例如......

import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;

public class FinCSV implements ActionListener {

    JFrame frame = new JFrame("ICON");
    JPanel panel = new JPanel(new GridLayout(2, 1, 4, 4));
    JButton primaryButton = new JButton(" Primary Process");
    JButton secondaryButton = new JButton(" Secondary Process");

    public static void main(String[] args)
            throws Exception {
        FinCSV msql = new FinCSV();
        msql.initGUI();
    }

    public void initGUI() {
        this.primaryButton.setActionCommand("Primary");
        this.secondaryButton.setActionCommand("Secondary");
        this.primaryButton.addActionListener(this);
        this.secondaryButton.addActionListener(this);

        this.primaryButton.setFont(new Font("Serif", Font.BOLD, 22));
        this.secondaryButton.setFont(new Font("Serif", Font.BOLD, 22));

        panel.add(this.primaryButton);
        panel.add(this.secondaryButton);
        frame.setContentPane(panel);
        frame.setSize(650, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public void actionPerformed(ActionEvent e) {

        if (e.getActionCommand().equals("Primary")) {
            secondaryButton.setVisible(false);
            PrimaryWorker worker = new PrimaryWorker(secondaryButton);
            worker.execute();
        } else if (e.getActionCommand().equals("Secondary")) {
            primaryButton.setVisible(false);
            SecondaryWorker secondaryWorker = new SecondaryWorker(primaryButton);
            secondaryWorker.execute();
        }
    }

    public abstract class StateWorker<T, V> extends SwingWorker<T, V> {

        private JButton btn;

        public StateWorker(JButton btn) {
            this.btn = btn;
        }

        @Override
        protected void done() {
            btn.setVisible(true);
        }

    }

    public class PrimaryWorker extends StateWorker<Integer, Integer> {

        public PrimaryWorker(JButton btn) {
            super(btn);
        }

        @Override
        protected Integer doInBackground() throws Exception {
            int sum = 0;
            for (int i = 0; i < 10000; i++) {
                System.out.println("[ " + (i + 1) + " ] Inside Primary Process");
                sum += i;
                publish(i);
            }
            return sum;
        }

    }

    public class SecondaryWorker extends StateWorker<Integer, Integer> {

        public SecondaryWorker(JButton btn) {
            super(btn);
        }

        @Override
        protected Integer doInBackground() throws Exception {
            int sum = 0;
            for (int i = 0; i < 10000; i++) {
                System.out.println("[ " + (i + 1) + " ] Inside Secondary Process");
                sum += i;
                publish(i);
            }
            return sum;
        }

    }
}

另请参阅安德鲁在主要评论部分中关于使用JRadioButton

的评论

答案 1 :(得分:0)

将完整的操作代码保存到Thread中,然后尝试

 Thread th1 = new Thread() {
                    public void run() {
//                         Keep you code here
                    }
  };
  th1.start();

答案 2 :(得分:-1)

这是因为您在代码的主线程内部处理了。

如果你想做一些繁重的事情,但仍然希望代码的其他部分能够顺利运行,那么你应该使用Threads。

但是,对于你的代码,你可以使用InvokeLater让你的主线程在第一个可用时间之后运行你的代码的一部分 - 我认为这是你没有接到这个电话的每个函数调用(他们必须完成控制应该回到主运行程序,我相信它是下一个周期的更新GUI。请自行阅读InvokeLater帮助部分)

如果您想要禁用/隐藏按钮,这就是您的代码的工作方式。

import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class FinCSV implements ActionListener {

    JFrame frame = new JFrame("ICON");
    JPanel panel = new JPanel(new GridLayout(2, 1, 4, 4));
    JButton primaryButton = new JButton(" Primary Process");
    JButton secondaryButton = new JButton(" Secondary Process");

    public static void main(String[] args)
            throws Exception {
        FinCSV msql = new FinCSV();
        msql.initGUI();
    }

    public void initGUI() {
        this.primaryButton.setActionCommand("Primary");
        this.secondaryButton.setActionCommand("Secondary");
        this.primaryButton.addActionListener(this);
        this.secondaryButton.addActionListener(this);

        this.primaryButton.setFont(new Font("Serif", Font.BOLD, 22));
        this.secondaryButton.setFont(new Font("Serif", Font.BOLD, 22));

        panel.add(this.primaryButton);
        panel.add(this.secondaryButton);
        frame.setContentPane(panel);
        frame.setSize(650, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if (e.getActionCommand().equals("Primary")) {
            secondaryButton.setVisible(false);
            primaryButton.setEnabled(false);
            run_btn_1();

        } else if (e.getActionCommand().equals("Secondary")) {
            primaryButton.setVisible(false);
            secondaryButton.setEnabled(false);
            run_btn_2();
        }
    }

    public void run_btn_1() {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    System.out.println("[ " + (i + 1) + " ] Inside Primary Process");
                }
                secondaryButton.setVisible(true);
                primaryButton.setEnabled(true);
            }
        });
    }

    public void run_btn_2() {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    System.out.println("[ " + (i + 1) + " ] Inside Secondary Process");
                }
                primaryButton.setVisible(true);
                secondaryButton.setEnabled(true);
            }
        });
    }
}

所以,你需要做的就是在这里放点东西:

java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                //your code if you want to run it in next gui update
            }
        });

<强> EDITED

使用线程:

public void run_btn_1() {
new Thread(new Runnable() {

    @Override
    public void run() {

        //loop
        secondaryButton.setVisible(true);
        primaryButton.setEnabled(true);

    }
}).start();
}

public void run_btn_2() {
new Thread(new Runnable() {

    @Override
    public void run() {

        // loop
        primaryButton.setVisible(true);
        secondaryButton.setEnabled(true);
    }
}).start();
}