问题
I'm a newbie to the paint/graphics and wonder how to add a JPanel to my code in such way that the entire graphics will be on a JPanel and not on the JFrame.
In other words, I'm trying to create a GUI that will allow me to do this: on the RIGHT side show the nice movement of the lines on a JPanel on the LEFT side, add a JTextArea (on a JPanel) that will show the coordination of the graphics.
- This is a simplification of a bigger problem but I guess the code here is easier to understand.
Thank you!!!
(picture below, moving lines or simply run the code)
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();
}
}

回答1:
- Instead of implementing
Runnable
, establish anActionListener
that callsrepaint()
. Call it from a SwingTimer
. - There are 2 ways to do this.
- Extend a
JComponent
orJPanel
- Draw in a
BufferedImage
and add that to anImageIcon
in aJLabel
.
- Extend a
- If extending a component, use
JComponent
if you do not need to add further children, orJPanel
if you do. For either, overridepaintComponent(Graphics)
instead ofpaint(Graphics)
. - The
BufferedImage
might be a better choice for this use-case, since it seems to be animating a (supposedly intentionally persistant) series of lines. - Swing GUIs should be started on the EDT.
- Don't call
setBounds
! Instead, set a preferred size to the custom component, use sensible values for the constructor of the text area, and combine them with layouts (and appropriate padding and borders), then callpack()
on the frame after all components are added. - There is an NPE if the JRE calls
repaint()
prior to theThread
starting.
..What was the question? Oh right, if it can be inferred that the question is "How to combine other components with a custom painted component?" - use a nested layout. see the Nested Layout example.

If using a BufferedImage
as backing store, you might place it like the image in that example, except that you would leave out the JTable
above that, as well as the JSplitPane
.
回答2:
Read the Swing tutorial on Custom Painting for the proper way to do this.
来源:https://stackoverflow.com/questions/8631670/how-to-use-jpanel-with-paint-or-repaint