2017-02-16 93 views
0

重繪不調用的paintComponent。
我試圖從Try類的另一個方法調用它,但它沒有解決。重繪不調用的paintComponent

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.*; 

public class Try extends JPanel { 
    int i =0; 

    @Override 
    public void paintComponent(Graphics g){ 
     //super.paintComponent(g); 
     System.out.println("hey"); 
    } 

    public static void main(String[] args) { 
     JFrame f=new JFrame(); 
     Try t = new Try(); 
     f.setSize(500,600);//400 width and 500 height 

     Container contentPane = f.getContentPane(); 
     contentPane.add(new PaintComponent()); 
     f.setVisible(true);//making the frame visible 

     while(true){ 
      t.repaint(); 
     } 
    } 
} 
+5

也許你的意思是'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

+0

不要刪除'super.paintComponent方法()'線,按照[Swing的風俗畫教程](https://docs.oracle.com/javase/tutorial/uiswing/painting/step1.html)知道如何它的工作原理 – Frakcool

回答

0

有多個問題,其中@trashgod在評論中提到了一些問題。

  1. 要調用重繪上,您沒有添加到內容窗格中的實例 - 你有一個不同的有(實際上,你有完全不同的東西在那裏 - new PaintComponent())。

  2. 不要刪除super.paintComponent (g);,除非你自己清理區域(如果它不透明,幾乎填滿整個組件背景),否則在重新繪製時會出現這些組件的視覺故障。

  3. 你是垃圾郵件重繪操作,這是非常不好的,讓重繪給轉時間進行重新繪製之間至少有一定的延遲。最好的情況是,如果只在實際顯示不同的東西時才重新繪製組件。如果您需要隨時更新視圖 - 至少將其限制爲每秒30-60幀(重繪)。此外,某些內部Swing優化可能會「吃」一些重新調用的調用,因此預計您可能看不到多少paintComponent調用是您調用該組件時重新調用的次數。

  4. 您與Swing組件事件指派線程(EDT不久),這可能會導致問題的在外打工。確保始終使用它來創建Swing組件並調用它們上的任何方法。 SwingUtilities有幫助。

  5. 需要花費很長時間(或未知時間)才能完成的繁重操作應在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,因此該方法在任何線程上都可以安全使用(就像我在本例中那樣)。

+0

感謝@Mikle的例子 – kev

相關問題