Drawing a JComponent inside a JPanel

梦想的初衷 提交于 2019-12-22 20:46:50

问题


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);
     }
}

回答1:


  • I'd be use paintIcon() for Class that returns Icon Object

  • public void paintIcon(Component c, Graphics g, int x, int y) {

  • for example




回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!