在计算时在JTextArea中显示文本

我正在编写的应用程序包括JButton和JTextArea。 单击该按钮会导致计算时间过长,从而导致JTextArea中显示文本。 即使计算时间很长,我也可以随时随地获得中间结果(例如,想想一个近似于pi的100位数的应用程序 – 每隔几秒我就可以编写另一个数字)。 问题是,即使我写(在ActionListener类中,因为按钮调用了计算)来将JTextArea的文本设置为某些东西,它在计算完成时也不显示,我只能看到结束结果,计算结束后。

为什么会这样,我该如何解决?

先谢谢你。

你的问题是你在主Swing线程EDT中进行了长时间的计算,这将冻结整个GUI,直到进程完成为止。 一个解决方案是使用后台线程进行计算,并使用一种简单的方法来使用SwingWorker创建主Swing线程(EDT)的线程背景,并将中间结果发布/处理到JTextArea中。 有关SwingWorkers和EDT的更多信息,请查看此处: Swing中的并发性

此外,如果你提供一个体面的sscce,我们甚至可以给你一个更详细的响应,甚至可能使用示例代码。

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 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 { 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 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(); } }); } } 

您可能还想显示某种旋转gif或“进度条”以显示正在计算答案; 对用户的反馈很好。

(一旦你使用了一个swingworker,那么gui就不会冻结,gui可以在计算过程中做自己的事情)