簡體   English   中英

如何從另一個線程設置 JTextPane?

[英]How do I set a JTextPane out of another Thread?

我現在正在學習多線程。

我有一個“主”類,我在其中構建了一個帶有文本字段、開始和停止按鈕的 JFrame。

我還有另一個類/線程,當我單擊框架的開始按鈕時,我想從中將當前時間打印到我的文本字段中。 一切正常,但當我啟動線程時,文本字段中的文本不會改變,即使 Eclipse 說我的代碼沒問題。

我究竟做錯了什么?

第一類:

public class Uhr extends JFrame {

    private JPanel contentPane;
    public JTextPane tpZeit;
    Thread t;
    
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Uhr frame = new Uhr();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Uhr() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        tpZeit = new JTextPane();
        tpZeit.setText("test");
        tpZeit.setBounds(43, 50, 212, 43);
        contentPane.add(tpZeit);

        JButton btnstart = new JButton("GO");
        btnstart.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                
                tpZeit.setText("started");
                if (t == null) {
                     t = new Thread(new Uhrsteuerung());
                }
                if(!t.isAlive()) {
                     t = new Thread(new Uhrsteuerung());
                     t.start();
                }

                }
        });
        btnstart.setBounds(10, 227, 89, 23);
        contentPane.add(btnstart);

        JButton btnstop = new JButton("Stop");
        btnstop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                
                t.interrupt();
            }
        });
        btnstop.setBounds(248, 227, 89, 23);
        contentPane.add(btnstop);
    }
}

帶有附加線程的類:

public class Uhrsteuerung extends Uhr implements Runnable {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    String time;
    boolean x ;

    @Override
    public synchronized void run() {
        // TODO Auto-generated method stub
        x = true;
        while (x) {
            try {
                time = sdf.format(System.currentTimeMillis());
                System.out.println(time);
                tpZeit.setText(time);
                repaint();
                Thread.sleep(1000);

            } catch (InterruptedException ex) {
                x = false;
            }
        }
    }
}

Java 的 Swing 類的所有代碼都必須在事件調度線程 (EDT) 上執行。 Swing 提供了一些特殊的類來幫助您做到這一點。

要在 EDT 之外執行代碼,請使用 SwingWorker 類。 SwingWorker 將在后台執行任務(不使用 EDT),然后返回在 EDT 上執行的正確同步的結果。 https://docs.oracle.com/en/java/javase/16/docs/api/java.desktop/javax/swing/SwingWorker.html

它的應用非常簡單。 定義您自己的擴展 SwingWorker 的類。

class PrimeNumbersTask extends SwingWorker<List<Integer>, Integer> {
  // ...

如果需要更新一個組件,最好把組件傳入,方便以后參考。

class PrimeNumbersTask extends SwingWorker<List<Integer>, Integer> {
  private JTextArea textArea;
  public PrimeNumbersTask( JTextArea textArea ) {
    this.textArea = textArea;
  }
  // ...

通過覆蓋方法doInBackground()來完成您的工作。 不要觸及此方法中的 Swing 類。 如果您想提供漸進式結果而不是等待整個任務完成,請使用publish()方法將較小的數據塊發送到 EDT。

 @Override
 public List<Integer> doInBackground() {
     while (!done && ! isCancelled()) {
             // do stuff
             publish(number);
             setProgress(100 * numbers.size() / numbersToFind);
         }
     }
     return numbers;
 }

最后覆蓋方法process()以更新您的 Swing 類。

 @Override
 protected void process(List<Integer> chunks) {
     for (int number : chunks) {
         textArea.append(number + "\n");
     }
 }

在 EDT 中,您可以調用execute()來啟動您的后台任務。

 JTextArea textArea = new JTextArea();
 // manipulate and set up GUI...
 PrimeNumbersTask task = new PrimeNumbersTask(textArea);
 task.execute();

如果您在 Google 上搜索 SwingWorker,還有更多文檔,這就是如何使用它的基礎知識。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM