Graphics.drawString() Draws Over My Old String

二次信任 提交于 2019-12-10 15:56:29

问题


I'm working on simple counter. My problem is that drawString() method draws new string over the old one. How to clear the old one before? Code...

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. I'm new to Java, so please don't be afraid to tell me what other things I should fix in my code...


回答1:


Several problems in your code:

  • Don't have a while (true) loop or Thread.sleep in a Swing GUI. Use a Swing Timer instead.
  • Override JPanel's paintComponent, not its paint method.
  • The first call in paintComponent(Graphics g) should be super.paintComponent(g), so your JPanel can do its house keeping and get rid of old graphics.

edit:

  • My bad, your while (true) and Thread.sleep(...) will work since they're in a background thread, but,...
  • Thread.sleep is a static method and should be called on the class, Thread, and
  • I still think a Swing Timer would be an easier way to do this.
  • Even easier still is to not even use a paint or paintComponent method, but rather simply set the text of a JLabel for your display.

e.g.,

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();
         }
      });
   }
}



回答2:


I think Graphics.clearRect is what you're looking for.




回答3:


I would do it like this:

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



回答4:


Aaah! This is normal. Imagine your panel as a blackboard. Each time you want to repaint what you have writed in, you will have to erase the blackboard first.

In Java, as well as in Graphics in general, things go in a similar way. In your paint method, do this:

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

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

When you can handle the topic better, do super.paint(Graphics) instead of clearRect().



来源:https://stackoverflow.com/questions/5842360/graphics-drawstring-draws-over-my-old-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!