Showing text in JTextArea while calculating

后端 未结 2 621
孤街浪徒
孤街浪徒 2020-12-11 11:17

An application I am writing consists, among others, a JButton and a JTextArea. A click on the button leads to a long calculation, resulting in a text shown in the JTextArea.

相关标签:
2条回答
  • 2020-12-11 11:45

    you may also want to display some sort of spinning gif or "progress bar" to show that the answer is being calculated; feedback to the user is good.

    (once you are using a swingworker, then the gui won't freeze and the gui can do its own thing while the calculation is taking place)

    0 讨论(0)
  • 2020-12-11 12:03

    Your problem is that you're doing a long calculation in the main Swing thread, the EDT, and this will freeze your entire GUI until the process has completed itself. A solution is to use a background thread for your calculation, and an easy way to do this it to use a SwingWorker to create a thread background to the main Swing thread, the EDT, and publish/process the interim results into the JTextArea. For more on SwingWorkers and the EDT, please look here: Concurrency in Swing

    Also, if you provide a decent sscce we can probably give you a more detailed response perhaps even with sample code.

    An example SSCCE:

    import java.awt.event.*;
    import java.text.DecimalFormat;
    import java.util.List;
    import javax.swing.*;
    
    public class InterimCalc {
       private JPanel mainPanel = new JPanel();
       private JTextField resultField = new JTextField(10);
       private JButton doItBtn = new JButton("Do It!");
       private DecimalFormat dblFormat = new DecimalFormat("0.0000000000");
       private SwingWorker<Void, Double> mySwingWorker = null;
    
       public InterimCalc() {
          mainPanel.add(doItBtn);
          mainPanel.add(resultField);
          displayResult(0.0);
    
          doItBtn.addActionListener(new DoItListener());
       }
    
       public void displayResult(double result) {
          resultField.setText(dblFormat.format(result));
       }
    
       public JPanel getMainPanel() {
          return mainPanel;
       }
    
       private class DoItListener implements ActionListener {
    
          public void actionPerformed(ActionEvent e) {
             if (mySwingWorker != null && !mySwingWorker.isDone()) {
                mySwingWorker.cancel(true);
             }
             displayResult(0.0);
             mySwingWorker = new MySwingWorker();
             mySwingWorker.execute();
          }
       }
    
       private class MySwingWorker extends SwingWorker<Void, Double> {
    
          private static final int INTERIM_LENGTH = 10000; // how many loops to do before displaying
    
          @Override
          protected Void doInBackground() throws Exception {
             boolean keepGoing = true;
             long index = 1L;
             double value = 0.0;
             while (keepGoing) {
                for (int i = 0; i < INTERIM_LENGTH; i++) {
                   int multiplier = (index % 2 == 0) ? -1 : 1;
                   value += (double)multiplier / (index);
                   index++;
                }
                publish(value);
             }
             return null;
          }
    
          @Override
          protected void process(List<Double> chunks) {
             for (Double dbl : chunks) {
                displayResult(dbl);
             }
          }
    
       }
    
       private static void createAndShowUI() {
          JFrame frame = new JFrame("Decay Const");
          frame.getContentPane().add(new InterimCalc().getMainPanel());
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {
                createAndShowUI();
             }
          });
       }
    }
    
    0 讨论(0)
提交回复
热议问题