How to make background work in custom JComponent?

2019-02-17 02:13发布

问题:

In the following example, I have a custom JComponent being drawn on green background, but it does not appear. Why does this happen?

public class Test_Background {

    public static class JEllipse extends JComponent {

        private final Ellipse2D ellipse;

        public JEllipse(int width, int height) {
            ellipse = new Ellipse2D.Double(0, 0, width, height);

            setOpaque(true);
            setBackground(Color.GREEN);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension((int) ellipse.getBounds().getMaxX(),
                                 (int) ellipse.getBounds().getMaxY());
        }

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

            ((Graphics2D) g).draw(ellipse);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JEllipse e = new JEllipse(400, 300);

                JFrame f = new JFrame("Background Test");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(e);
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

回答1:

JComponent does not paint its background. You can either paint it yourself, or use JPanel which does paint its background



回答2:

As I remember it is only support this backgroun property, but does not draw it actually. Pum use g.fillRect (or fillEllipse if this is ellipse) to create your own background.



回答3:

There are several problems in your paint() method.

  • You are never calling Graphics.setColor(), so the color you are painting in is completely unknown.
  • You have declared this component to be opaque, which means that you are promising to paint the background yourself.

You want something more like this:

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(getBackground());
        g2.fillRect(0, 0, getWidth(), getHeight());
        g2.setColor(getForeground());
        g2.draw(ellipse);
    }

Or, you could extend from JPanel instead of JComponent, and it will paint the background for you, leaving you to do only the foreground:

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(getForeground());
        g2.draw(ellipse);
    }