簡體   English   中英

JFrame repaint(); 如何使用線程信息更新JFrame?

[英]JFrame repaint(); How to update the JFrame with Thread info?

我試圖在JFrame上設置一個簡單的時間行情記錄器。 我能夠顯示counter的初始值,但是任何后續更改都不會在JFrame上更新。 任何對我做錯了答案的輕推都將不勝感激。 我認為這是repaint()未被調用的問題,但是我要么以錯誤告終,要么如果嘗試將其放入,一無所獲。

package com.game.ryan;
import java.awt.Dimension;
import javax.swing.JFrame;
class Screen extends JFrame{


private Dimension d = new Dimension(800,600);
private JFrame f;

public Screen(){
    f = new JFrame();
    f.setIgnoreRepaint(false);
    f.setResizable(false);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setMinimumSize(d);
    f.setLocationRelativeTo(null);
    f.add(new MyPanel());
    f.pack();
    f.setVisible(true);
}

public static void main(String[] args){
    Screen s = new Screen();
}

}

我也有:

package com.game.ryan;

import java.awt.Graphics;

import javax.swing.JPanel;

public class MyPanel extends JPanel{

private OneThread ot = new OneThread();
private int counter = ot.getThreadCounter();

public MyPanel(){
    Thread t1 = new Thread(new OneThread());
    t1.start();

}

public void paintComponent(Graphics g){
    g.drawString("TIME: ", 10, 20);
    g.drawString(Integer.toString(counter), 50, 20);        
}
}

最后

package com.game.ryan;

public class OneThread implements Runnable{

private int counter = 45;

public OneThread(){

}

@Override
public void run() {

    for(int x = 0; x >= 0; x++){
        try{
            Thread.sleep(1000);
            counter++;
            x++;
            System.out.println(counter);

        }catch(Exception e){
            e.printStackTrace();
        }
    }       
}

public int getThreadCounter(){
    return counter;
}
}

我在控制台上的計數器越來越多,所以我猜那部分工作正常。

預期結果是計數器可以正確顯示在JFrame中(每1000ms更新一次)。

您可能希望重新考慮您的設計:

  • 基本變量擁有一個值,僅此而已。 如果將原語保存的值分配給另一個變量,則以后更改原始變量將不會影響其他變量保存的值。 例如,您的代碼中的任何內容都不會更改JPanel所擁有的counter變量所擁有的值。
  • 請注意,即使您的計划成功了,您也將擁有兩個完全獨立的OneThread對象,並且更改其中一個的狀態不會影響另一個。
  • 最好讓GUI監聽對變量的更改,然后讓線程更改變量的狀態,然后將此更改通知所有偵聽器。 PropertyChangeListener可以很好地解決此問題。
  • 請注意,Swing Timer會比后台線程更容易實現。

我看不到您告訴用戶界面應該更新的任何地方。

您還需要走很長的路要復制API中已經可用的內容。

擺動和螺紋需要仔細考慮。 Swing使用單線程模型來管理UI的所有更新。 期望使用UI的所有迭代都將在線程(又稱為事件調度線程)的上下文中完成。

這意味着任何時候您想要從任何其他線程創建或更新UI時,都需要將調用同步回EDT。

盡管有多種方法可以實現此目的,但在您的情況下,最簡單的javax.swing.Timer是使用javax.swing.Timer

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class LabelClock {

    public static void main(String[] args) {
        new LabelClock();
    }

    protected static final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm.ss");
    private JLabel clock;

    public LabelClock() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                clock = new JLabel();
                tick();

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(clock);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                Timer timer = new Timer(500, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        tick();
                    }
                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();
            }
        });
    }

    protected void tick() {
        clock.setText(DATE_FORMAT.format(new Date()));
    }

}

暫無
暫無

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

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