I am trying to display a JComponent inside a JPanel. I am using null layout because location of the components can be changed during runtime and I have to control them.
But the following code does not work. The JComponent only becomes visible on display if I explicity call the "paintComponent" method, which I think is not good practice.
My JComponent Class
public class MyIcon extends JComponent
{
private double xPos;
private double yPos;
private double radius = 30;
public MyIcon(double xPos, double yPos)
{
this.xPos = xPos;
this.yPos = yPos;
this.setBounds((int)xPos, (int)yPos, (int)radius, (int)radius);
this.setPreferredSize(new Dimension((int)radius, (int)radius ) );
}
public Dimension getPreferredSize()
{
return ( new Dimension( (int)radius, (int)radius ) );
}
public Dimension getMinimumSize()
{
return new Dimension((int)radius, (int)radius);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.drawOval( (int)xPos, (int)yPos, (int)radius, (int)radius);
g2d.fillOval((int)xPos, (int)yPos, (int)radius, (int)radius);
System.out.println("Icon.paintComponnet() called");
}
}
My Panel Class
public class MyPanel extends JPanel
{
private MyIcon myIcon;
private Graphics2D graphics;
private int width = 700;
private int height = 500;
public MyPanel()
{
myIcon = new MyIcon(20,30);
init();
}
private void init()
{
setLayout(null);
setBackground(Color.WHITE);
setPreferredSize( new Dimension(width, height) );
setBorder(BorderFactory.createLineBorder(Color.BLACK));
add( myIcon );
myIcon.repaint();
}
public void paintComponent(Graphics g)
{
graphics = (Graphics2D) g;
super.paintComponent(g);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
System.out.println("MyPanel.paintComponnet() called");
// why my Icon only gets painted if I explicitly call for it ?
//myIcon.paintComponent(g);
}
}
My Frame Class
public class Editor {
public static void main(String[] args)
{
Editor editor = new Editor();
}
private MyPanel myPanel;
private JFrame frame;
private JToolBar toolBar;
public Editor()
{
myPanel = new MyPanel();
init();
}
private void init()
{
frame = new JFrame("Editor");
Container content = frame.getContentPane();
frame.setSize(800, 600);
frame.setLayout(new BorderLayout(15,15));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
content.add(myPanel,BorderLayout.WEST);
frame.pack();
frame.setVisible(true);
}
}
Maybe a good approach would be that the Icon class would not extend JComponent
but would be just a simple object.
Then, you rename the current Icon.paintComponent
you have to something like drawIcon
and call the drawIcon
method from the MyPanel.paintComponent
directly and passing the reference to the Graphics object.
This way you don't have to wonder about using a null layout and you can control the place to display the icon to by just using the Graphics(2d)
APIs.
来源:https://stackoverflow.com/questions/12873056/drawing-a-jcomponent-inside-a-jpanel