paintComponent draws other components on top of my drawing

人走茶凉 提交于 2019-11-27 09:42:08

+1 to @MadProgrammer's answers.

  • You should have super.paintComponent(..) as the first call in your overriden paintComponent()
  • Do not extend JFrame unnecessarily
  • Create and minipulate Swing components via EDT
  • Dont call setPrefferedSize() rather override getPrefferedSize()

Here is an example which incorporates my advice's and @MadProgrammer's:

import java.awt.BasicStroke;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    JFrame frame;

    public Test() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final PaintPanel paintPanel = new PaintPanel();

        paintPanel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                paintPanel.addRect(e.getX(), e.getY());
            }
        });

        frame.setLayout(new FlowLayout());

        frame.add(paintPanel);
        frame.add(new JButton("Dummy"));

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String... args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }
}

class PaintPanel extends JPanel {

    public PaintPanel() {
        addRect(100, 100);
    }
    ArrayList<Rectangle> rects = new ArrayList<>();

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setPaintMode();

        for (Rectangle r : rects) {
            g2d.setStroke(new BasicStroke(1));
            g2d.fillRect(r.x, r.y, r.width, r.height);
        }
    }

    public void addRect(int x, int y) {
        rects.add(new Rectangle(x, y, 10, 10));
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }
}

You're not calling super.paintComponent.

The graphics context used for a paint cycle is shared between all the components begin painted, this means if you don't take care to clear it before painting onto, you will end up with what ever was painted before you.

One of the jobs of paintComponent is to prepare the graphics for painting

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