在jpanel上保持绘制的字符串

时间:2013-04-02 02:58:33

标签: java swing awt

我试图一次一个地在屏幕上打印一组int的内容但是将前面的元素保留在屏幕上,我该怎么做?这是我到目前为止打印每个元素,但不保留屏幕上的前一个元素

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

class test extends JFrame  
{  
  JPanel panel;  
  public static void main(String[] args)  
  {  
      test obj = new test();  
      obj.makeAnim();  
  }  
  public void makeAnim() {  
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
      setTitle("Animate");
      setResizable(false);  
      setSize(400,400);  

      Animate arr1 = new Animate();  
      Animate arr2 = new Animate();  
      //arr1.add(arr2);  
      getContentPane().add(arr1);  
      setVisible(true);  
      new Thread(arr1).start();  
      //new Thread(arr2).start();  
  }  
}  
class Animate extends JPanel implements Runnable  
{  
  int j = 1;
  int [] a = {1,2,3,5,6,7,2,1,10,99};  
  String temp; 

  public Animate()  
  {  
     setPreferredSize(new Dimension(400,400));  
  }  
  public void run()  
  {  
   for (int i = 0; i < 10; i++) {  

        temp = Integer.toString(a[i]);
        j++;
        repaint();  

        try {  
            Thread.sleep(2000);  
        } catch (Exception ex) {}  
    }  
  }  
  public void paintComponent(Graphics g)  
  {  

    super.paintComponent(g); 
    g.setColor(Color.red);
    g.setFont(new Font("Courier",Font.PLAIN, 20));
    g.drawString(temp, (50+(j*10)), 50);


  }  
}  

1 个答案:

答案 0 :(得分:2)

您面临许多问题。

Swing中的绘画是无状态的,这意味着以前在一个周期中绘制的东西,不会出现在下一个循环中,除非你在物理上绘画。

请查看Performing Custom PaintingPainting in AWT and Swing了解详情。

除非你同步线程和绘制例程(这是不可取的),否则你永远不应该改变paint方法可能依赖于Event Dispatching Thread的任何变量的状态。

您应该使用Thread

,而不是使用javax.swing.Timer

您可能会发现Concurrency in SwingInitial Threads信息

您不应该依赖“魔术”数字(例如字符宽度偏移),您应该依靠底层系统为您提供有用的提示。在这种情况下,您需要查看FontMetrics

您还应避免使用setPreferredSize并覆盖getPreferredSize

下面是我如何解决同样问题的一个例子......

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

class TestPaint02 extends JFrame {

    JPanel panel;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                TestPaint02 obj = new TestPaint02();
                obj.makeAnim();
            }
        });
    }

    public void makeAnim() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Animate");
        setResizable(false);
        setSize(400, 400);

        Animate arr1 = new Animate();
        getContentPane().add(arr1);
        setVisible(true);
    }

    public class Animate extends JPanel {

        int i = 0;
        int[] a = {1, 2, 3, 5, 6, 7, 2, 1, 10, 99};

        public Animate() {
            Timer timer = new Timer(2000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    i++;
                    repaint();
                    if (i >= a.length) {
                        ((Timer) e.getSource()).stop();
                    }
                }
            });
            timer.setRepeats(true);
            timer.setInitialDelay(0);
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.red);
            g.setFont(new Font("Courier", Font.PLAIN, 20));
            FontMetrics fm = g.getFontMetrics();
            int x = 50;
            int y = 50;
            for (int loop = 0; loop < i; loop++) {
                g.drawString(String.valueOf(a[loop]), x, y);
                x += fm.stringWidth(String.valueOf(a[loop]));
            }
        }
    }
}