有多個問題,其中@trashgod在評論中提到了一些問題。
要調用重繪上,您沒有添加到內容窗格中的實例 - 你有一個不同的有(實際上,你有完全不同的東西在那裏 - new PaintComponent()
)。
不要刪除super.paintComponent (g);
,除非你自己清理區域(如果它不透明,幾乎填滿整個組件背景),否則在重新繪製時會出現這些組件的視覺故障。
你是垃圾郵件重繪操作,這是非常不好的,讓重繪給轉時間進行重新繪製之間至少有一定的延遲。最好的情況是,如果只在實際顯示不同的東西時才重新繪製組件。如果您需要隨時更新視圖 - 至少將其限制爲每秒30-60幀(重繪)。此外,某些內部Swing優化可能會「吃」一些重新調用的調用,因此預計您可能看不到多少paintComponent
調用是您調用該組件時重新調用的次數。
您與Swing組件事件指派線程(EDT不久),這可能會導致問題的在外打工。確保始終使用它來創建Swing組件並調用它們上的任何方法。 SwingUtilities
有幫助。
需要花費很長時間(或未知時間)才能完成的繁重操作應在EDT外執行,否則,由於執行了所有UI更新,因此在您等待該操作完成時,UI會簡單地掛起在EDT上,而不是其他地方。
考慮到所有我上面說的,這就是你們的榜樣應該什麼樣子:
public class Try extends JPanel
{
@Override
public void paintComponent (final Graphics g)
{
super.paintComponent (g);
final Graphics2D g2d = (Graphics2D) g;
g2d.drawString (Long.toString (System.currentTimeMillis()), 25, 35);
System.out.println ("repainted");
}
public static void main (final String[] args)
{
SwingUtilities.invokeLater (new Runnable()
{
@Override
public void run()
{
final JFrame f = new JFrame();
final Try t = new Try();
f.getContentPane().add (t);
f.setSize (500, 600);
f.setVisible (true);
new Thread (new Runnable()
{
@Override
public void run()
{
try
{
while (true)
{
t.repaint();
Thread.sleep (25);
}
}
catch (final InterruptedException e)
{
//
}
}
}).start();
}
});
}
}
。希望澄清這一點給你。
還有SwingWorker
類有助於在Swing中執行長時間運行的任務,但我沒有在這裏使用它來保持示例儘可能簡單。
另外一個備註 - 您不需要在EDT中調用repaint()
,因爲它將重繪請求自己發送給EDT,因此該方法在任何線程上都可以安全使用(就像我在本例中那樣)。
也許你的意思是'contentPane.add(新嘗試())'。另外,_don_t_阻止EDT; _do_參見[*在Swing *併發(http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)和[*如何使用Swing計時器*](http://docs.oracle.com/ JavaSE的/教程/ uiswing /雜項/ timer.html)。 – trashgod
不要刪除'super.paintComponent方法()'線,按照[Swing的風俗畫教程](https://docs.oracle.com/javase/tutorial/uiswing/painting/step1.html)知道如何它的工作原理 – Frakcool