Java Swing JButton 禁用不给出不良结果

问题描述 投票:0回答:1

这是我第一次使用 Java Swing,很抱歉错过了很多上下文。这是使用 Netbeans 7.0.x——商业理性。代码是使用 Netbeans 中的“设计”功能生成的。生成了大部分 gui 代码,如果不是全部的话。



我已经尝试了几个调用

setEnabled
的区域来禁用
upload
按钮,直到文件传输完成。出于测试目的,我添加了一个双重 for 循环来执行一些浮点运算;我在 for 循环之前和之后都有弹出消息来反映一些“文件上传繁忙的工作”。我在感兴趣的按钮上调用
setEnabled
函数的任何地方都没有给出“变灰”或“禁用”按钮的预期结果——直到
guiController.submitUpload()
调用在
swingworker.doInBackground()
的主体内完成。现在我注释掉了
done()
函数。



期望的结果:单击

buttonX
时,按钮变灰或禁用它——也就是说,我不应该再次单击它——看到
submitUpload()
中的第一个弹出窗口,然后看到第二个弹出窗口向上。
submitUpload()
函数运行它的业务逻辑,并完成。完成后,
buttonX
应该重新启用或禁用它。理想情况下,我想禁用此按钮并将其变灰,
buttonX
.


我已经在 SO 中尝试了很多结果,并且已经阅读了文档:

https://docs.oracle.com/javase/tutorial/uiswing/components/button.html
https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html



有人可以帮我解决我遗漏的问题吗?

=========================
panelFile.java
//private variable
SwingWorker sw = ...;

buttonX.addActionListener(new java.awt.event.ActionListener(){
    public void actionPerformed(java.awt.event.ActionEvent evt) {

        //tried disabling here
        //buttonX.setEnabled(false);
        buttonXActionPerformed(evt);
        //renable
    }
}
.
.
.

private void bottonXActionPerformed(java.awt.event.ActionEvent evt) {

    //also tried disabling here 
    
    sw = new SwingWorker<void, void> () {
         @Override
         public void doInBackground
             {
            try
                {
                if (guiController != null)
                    {
                    guiController.submitUpload();
                    }
                }
            catch (Exception e)
                {
                logger.log(Level.SEVERE, e.toString(), e);
                }
            sw = null;
            return null;
            }
        /*
        @Override
        public void done()
            {
            buttonX.setEnabled(true);
            }         
         */
        };
    
    sw.execute();
}
=========================
guiController.java


public void submitUpload(){
    //do stuff
   
    //for testing I have pop-ups
    // I should only see this popup once, until the "upload completes"
    JOptionPane.showMessageDialog(getFrame(),
                                  "BEFORE",
                                  "test disable",
                                  JOptionPane.INFORMATION_MESSAGE);

    //busy loop here

    JOptionPane.showMessageDialog(getFrame(),
                                  "AFTER",
                                  "test disable",
                                  JOptionPane.INFORMATION_MESSAGE);


}
java swing jbutton actionlistener swingworker
1个回答
0
投票

所以是的,在执行 SwingWorker 之前,在您调用它的地方调用

JButton#setEnabled(false)
,然后在工作人员完成后重新启用它。这 will 工作。如果它对您不起作用,那么您在未显示的代码中遇到了 Swing 线程问题。

这是我的概念验证示例MRE

import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class FooPanel01 extends JPanel {
  private JButton longActionButton = new JButton("Start Long Action");
  private JTextArea output = new JTextArea(15, 40);
  
  public FooPanel01() {
    longActionButton.addActionListener(e -> longActionPerformed());
    JPanel buttoPanel = new JPanel();
    buttoPanel.add(longActionButton);

    JScrollPane scrollPane = new JScrollPane(output);
    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    setLayout(new BorderLayout());
    add(buttoPanel, BorderLayout.PAGE_START);
    add(scrollPane, BorderLayout.CENTER);
  }

  private void longActionPerformed() {
    longActionButton.setEnabled(false);
    output.append("Long Action started..." + System.lineSeparator());
    new MyWorker().execute();
  }

  private class MyWorker extends SwingWorker<Void, String> {
    @Override
    protected Void doInBackground() throws Exception {
      // Do some long running task
      // here emulated with Thread.sleep
      for (int i = 0; i < 6; i++) {
        Thread.sleep((long) (Math.random() * 1000));
        publish("Processing step " + i);
      }
      return null;
    }

    @Override
    protected void process(List<String> chunks) {
      for (String chunk : chunks) {
        output.append(chunk + System.lineSeparator());
      }
    }

    @Override
    protected void done() {
      longActionButton.setEnabled(true);
      output.append("Long Action finished..." + System.lineSeparator());
      try {
        // always call  this in the done() method to trap exceptions
        get();
      } catch (InterruptedException | ExecutionException e) {
        e.printStackTrace();
      }
    }
  }
  
  public static void main(String[] args) throws IOException {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        JFrame frame = new JFrame("GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new FooPanel01());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    });

  }

}
© www.soinside.com 2019 - 2024. All rights reserved.