Java 当我拖动swing中的可拖动圆圈时,它会闪烁

Java 当我拖动swing中的可拖动圆圈时,它会闪烁,java,swing,Java,Swing,我正在实现一个Swing程序,它将形状绘制到屏幕上,然后让用户拖动它们。我可以很好地画一个形状,但一旦我点击一个形状来拖动它,当它被拖动时,这个形状开始闪烁 这是我的GUI类和MouseAdapter类: public class GUI extends JFrame { private JMenu addShapeMenu = new JMenu("Add Shape"); private JLabel statusBar = new JLabel(); private

我正在实现一个Swing程序,它将形状绘制到屏幕上,然后让用户拖动它们。我可以很好地画一个形状,但一旦我点击一个形状来拖动它,当它被拖动时,这个形状开始闪烁

这是我的GUI类和MouseAdapter类:

public class GUI extends JFrame {
    private JMenu addShapeMenu = new JMenu("Add Shape");
    private JLabel statusBar = new JLabel();
    private List<Shape> _shapes;
    private Shape chosenShape;
    private boolean isShapeClicked = false;
    private List<String> shapeSubclasses = new ArrayList<>();

    public GUI() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException {
        super("DrawingBoard");
        setSize(500, 500);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        menuBar.add(addShapeMenu);

        getContentPane().setLayout(new BorderLayout());

        getLoadedShapes();
        for(String shape : shapeSubclasses)
        {
            Class drawableShape = Class.forName("gui.Drawable" + shape);
            addShapeMenu.add(((DrawableShape)drawableShape.newInstance()).getInstance().getMenuItem());
        }

        add(statusBar, BorderLayout.SOUTH);
        statusBar.setText("Add a shape.");

        MouseHandler mouseHandler = new MouseHandler();
        addMouseListener(mouseHandler);
        addMouseMotionListener(mouseHandler);

        setVisible(true);
    }

    public void paint(Graphics graphics)
    {
        super.paint(graphics);
        for(Shape shape : _shapes)
        try
        {
            Class painter = Class.forName("gui.Drawable" + shape.getClass().getSimpleName());
            ((DrawableShape)painter.newInstance()).getInstance().paint(getGraphics(), shape);
        }

        catch(Exception e)
        {
            JOptionPane.showMessageDialog(this, "Failed to load Drawable" + shape);
        }
    }

    private class MouseHandler extends MouseAdapter implements MouseMotionListener {
        public void mousePressed(MouseEvent event) {
            _shapes.forEach(shape -> {
                if(shape.isPointInside(event.getX(), event.getY()))
                    chosenShape = shape;
                isShapeClicked = true;
            });
        }

        public void mouseDragged(MouseEvent event) {
            if (isShapeClicked) {
                chosenShape.moveTo(event.getX(), event.getY());
                repaint();
            }
        }

        public void mouseReleased(MouseEvent event) {
            isShapeClicked = false;
                chosenShape = null;
        }
    }
}
DrawRectangle类类似。


  • paint
    方法中加载类不是一个好主意,因为这可能会花费宝贵的时间,这可能会导致屏幕更新延迟
  • 不要覆盖顶层容器的
    paint
    ,它们不是双缓冲的。相反,创建一个自定义组件,从
    JPanel
    扩展,并覆盖它的
    paintComponent
    方法,将您的自定义绘制放在to中(不要忘记先调用
    super.paintComponent

有关更多详细信息,请参见和

考虑提供一个演示您的问题的示例。这将减少混乱和更好的响应在
paint
方法中加载类不是一个好主意,因为这可能会花费宝贵的时间,这可能会导致屏幕更新延迟。我将我的paint方法移动到JPanel的paintComponent中,并且一切正常。谢谢
public void paint(Graphics graphics, Shape shape)
    {
        int radius = ((Circle)shape).getRadius();
        graphics.fillOval(shape.getX() - radius, shape.getY() - radius, radius * 2, radius * 2);
    }