2011-04-30 42 views
4

我正在處理簡單的計數器。我的問題是drawString()方法在舊的字符串上繪製新的字符串。如何清除舊的?代碼...Graphics.drawString()繪製我的舊字符串

package foobar; 

import java.awt.Color; 
import java.awt.Graphics; 
import javax.swing.JPanel; 

public class board extends JPanel implements Runnable { 

    Thread animator; 
    int count; 

    public board() { 
     this.setBackground(Color.WHITE); 
     count = 0; 
     animator = new Thread(this); 
     animator.start(); 
    } 

    @Override 
    public void run() { 
     while(true) { 
      ++count; 
      repaint(); 
      try { 
       animator.sleep(1000); 
      } catch (InterruptedException e) {} 
     } 
    } 

    @Override 
    public void paint(Graphics Graphics) { 
     Graphics.drawString(Integer.toString(count), 10, 10); 
    } 
} 

P.S.我是新來的Java,所以請不要害怕告訴我什麼其他事情,我應該修復我的代碼...

+2

嘗試Java! **好**選擇;-)現在,請耐心等待。以後,事情會變得非常容易。 Keith you putz! – 2011-04-30 14:41:23

回答

7

代碼中的幾個問題:

  • 不要有一個Swing GUI的一段時間(true)循環和Thread.sleep。改用Swing Timer。
  • 重寫JPanel的paintComponent,而不是其繪畫方法。
  • paintComponent(Graphics g)中的第一個調用應該是super.paintComponent(g),這樣您的JPanel就可以完成它的內部維護並擺脫舊的圖形。

編輯:

  • 我的壞,你的一段時間(真)和了Thread.sleep(...)工作,因爲他們是在一個後臺線程,但是,...
  • Thread.sleep是一個靜態方法,應該在類Thread上調用,並且我仍然認爲Swing Timer會是一個更簡單的方法。
  • 更簡單的是甚至不使用paint或paintComponent方法,而只是簡單地爲顯示設置JLabel的文本。

例如,

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 

public class Board2 extends JPanel { 
    private static final int TIMER_DELAY = 1000; 

    private int counter = 0; 
    private JLabel timerLabel = new JLabel("000"); 

    public Board2() { 
     add(timerLabel); 
     new Timer(TIMER_DELAY, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      counter++; 
      timerLabel.setText(String.format("%03d", counter)); 
     } 
     }).start(); 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("Board2"); 
     frame.getContentPane().add(new Board2()); 
     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(); 
     } 
     }); 
    } 
} 
1

我認爲Graphics.clearRect是你在找什麼。

+2

Keith you putz!這不是一個JComponent,而是一個JPanel。 Nah,這是超級方法,需要在paintComponent中。希望你和你的一切順利。問候,皮特 – 2011-04-30 14:31:21

+0

@ Hovercraft充分的鰻魚:我同意這一點。但是,在第一步中執行'clearRect'是一種很好的做法,可以**理解事物的工作方式。 – 2011-04-30 14:45:10

+1

@jmendeth:我不確定。在JComponent中執行圖形時需要它,但如果調用超級方法,JPanel會爲您執行此操作,因此我認爲最好使用恰當的工具來處理這種情況。但是我還沒有給基思一個很長的時間,因爲我從未見過他(從我以前的太陽論壇時代開始)。 – 2011-04-30 14:47:50

1

我會做這樣的:

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    //draw all the other stuff 
} 
1

啊哈!這個是正常的。設想你的面板爲黑板。每次你想重畫你所寫的東西時,你必須先先把黑板擦掉

在Java以及一般的圖形中,事情都以類似的方式進行。在你的繪製方法,這樣做:

Graphics.clearRect(0,0, getWidth(),getHeight()); 
     //CLEAR the entire component first. 

Graphics.drawString(...); //now that the panel is blank, draw the string. 

當你能處理好話題,做super.paint(Graphics)而不是clearRect()