2011-12-25 151 views
3

我是一个新手绘画/图形,并想知道如何将JPanel添加到我的代码中,这样整个图形将在JPanel上,而不是在JFrame上。如何使用jpanel绘画(或重新绘制)

换句话说,我试图创建一个图形用户界面,可以让我做到这一点: 右侧显示上左侧的JPanel 线的漂亮动作,添加一个JTextArea (在JPanel上)将显示图形的协调。

  • 这是一个更大问题的简化,但我猜这里的代码更容易理解。

谢谢!

(如下图,动线或只需运行该代码)

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.geom.Line2D; 
import javax.swing.JFrame; 

public class Test extends JFrame implements Runnable 
{ 
    private Line2D line; 

public Test() 
{ 
    super("testing"); 
    this.setBounds(500, 500, 500, 500); 
    this.setVisible(true); 
} 

public void paint(Graphics g) 
{ 
    Graphics2D g2 = (Graphics2D) g; 
    g2.draw(line); 
} 

@Override 
public void run() 
{ 
    int x=50; 
    while (true) 
    { 
     try 
     { 
      Thread.sleep(50); 

      line = new Line2D.Float(100+x, 100+x, 250-x, 260+x%2); 
      x++; 
      repaint(); 
      if (x==5000) 
       break; 

     } catch (InterruptedException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

public static void main (String args[]) 
{ 
    Thread thread = new Thread (new Test()); 
    thread.start(); 
} 
} 

enter image description here

回答

5
  1. 无需实现Runnable的,建立一个ActionListener调用repaint()。从Swing Timer中调用它。
  2. 有两种方法可以做到这一点。
    • 扩展JComponentJPanel
    • 绘制在BufferedImage并添加到ImageIconJLabel
  3. 如果扩展组件,请使用JComponent(如果不需要添加更多子项)或使用JPanel(如果需要)。对于覆盖paintComponent(Graphics)而不是paint(Graphics)
  4. BufferedImage可能是这种用例的更好选择,因为它似乎是动画(假定有意识的持续)系列的线。
  5. Swing GUI应该在EDT上启动。
  6. 请勿拨打setBounds!相反,将首选大小设置为自定义组件,为文本区域的构造函数使用合理值,并将其与布局(以及适当的填充和边框)组合,然后在添加所有组件后在框架上调用pack()
  7. 如果JRE在Thread开始之前调用repaint(),则存在NPE。

..What是问题吗?哦,对,如果可以推断出问题是“如何将其他组件与自定义绘画组件结合?” - 使用嵌套布局。请参阅Nested Layout example

如果使用BufferedImage作为后备存储,您可以把它像这个例子形象,不同之处在于你会离开上面的JTable,还有JSplitPane

+0

谢谢!我扩展了JPanel,并使用了paintComponent,这个技巧是 – adhg 2011-12-26 19:22:08

+0

,今天我学到了2件东西。再次感谢 – adhg 2011-12-27 01:32:15

+0

不客气。 :-)在这两个方面。 ;) – 2011-12-27 01:47:28