2014-03-29 46 views
2

我想创建一个JPanel并在其上逐一绘制。我希望看到它们相继添加。问题是,我总是要等到一切完成后才用paintComponent的方法。有没有办法实现我的愿望?提前致谢!一步一步在JPanel上绘图

package javapaintui; 

import java.awt.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 

class JavaPaintUI extends JFrame { 

    private JPanel jPanel2; 

    public JavaPaintUI() { 
     initComponents(); 
    } 

    private void initComponents() { 
     jPanel2 = new Panel2(); 
     this.setContentPane(jPanel2); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     pack(); 
    } 

    class Panel2 extends JPanel { 

     Panel2() { 
      setPreferredSize(new Dimension(420, 420)); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      g.drawString("BLAH", 20, 20); 
      try { 
       Thread.sleep(5000); 
      } catch (InterruptedException ex) { 
       Logger.getLogger(JavaPaintUI.class.getName()).log(Level.SEVERE, null, ex); 
      } 
      g.drawRect(200, 200, 200, 200); 
     } 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new JavaPaintUI().setVisible(true); 
      } 
     }); 
    } 
} 
+0

要添加到下面由HFoE回答,这里是一个'定时器'[示例](http://stackoverflow.com/a/22652258/2587435)重复添加随机对象。 –

回答

4

永远不会在Swing应用程序的事件分派线程中使用Thread.sleep(...)。当你把它放到睡眠状态时,对于paintComponent方法来说这是100倍。解决方案是使用摆动计时器。

例如,

import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.RenderingHints; 
import java.awt.Shape; 
import java.awt.Stroke; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Random; 

import javax.swing.*; 

class JavaPaintUI extends JFrame { 
    private static final Color FILL_COLOR = Color.BLUE; 
    private static final Color BORDER_COLOR = Color.RED; 
    public static final Stroke STROKE = new BasicStroke(4f); 

    private JPanel jPanel2; 

    public JavaPaintUI() { 
     initComponents(); 
    } 

    private void initComponents() { 
     jPanel2 = new Panel2(); 
     this.setContentPane(jPanel2); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     pack(); 
    } 

    class Panel2 extends JPanel { 
     private static final int TIMER_DELAY = 2000; 
     private Random random = new Random(); 
     private List<Shape> shapeList = new ArrayList<>(); 

     Panel2() { 
     setPreferredSize(new Dimension(420, 420)); 
     new Timer(TIMER_DELAY, new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent evt) { 
       int width = random.nextInt(100); 
       int height = random.nextInt(100); 
       int x = random.nextInt(getWidth() - width); 
       int y = random.nextInt(getHeight() - height); 
       shapeList.add(new Rectangle(x, y, width, height)); 
       repaint(); 
      } 
     }).start(); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawString("BLAH", 20, 20); 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
       RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setStroke(STROKE); 
     for (Shape shape : shapeList) { 
      g2.setColor(FILL_COLOR); 
      g2.fill(shape); 
      g2.setColor(BORDER_COLOR); 
      g2.draw(shape); 
     } 
     } 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new JavaPaintUI().setVisible(true); 
     } 
     }); 
    } 
} 

编辑
你问:

现在的问题是,我打算画一个二叉树。绘图机制以这种方式工作:我将树的根传递给绘图函数,绘图函数将遍历它,并在面板上绘制一棵树。我使用drawString,drawOval和drawLine函数,这似乎很难以这种方式实现。你可能有解决方案吗?

其实我已经给你完美的解决方案。 shapeList List<Shape>变量将接受实现Shape接口的任何内容,这意味着您可以将Line2D,Ellipse2D和类似对象以及text添加到它。

+0

谢谢你,这工作正常!现在的问题是,我打算绘制一棵二叉树。绘图机制以这种方式工作:我将树的根传递给绘图函数,绘图函数将遍历它,并在面板上绘制一棵树。我使用drawString,drawOval和drawLine函数,这似乎很难以这种方式实现。你可能有解决方案吗? –

+0

@Slashmaster:请参阅编辑回答。 –