拖动时,可拖动的圆圈在闪烁时闪烁

时间:2014-12-01 00:39:25

标签: java swing

我正在实现一个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;
        }
    }
}

我的DrawableCircle类有一个方法paint:

public void paint(Graphics graphics, Shape shape)
    {
        int radius = ((Circle)shape).getRadius();
        graphics.fillOval(shape.getX() - radius, shape.getY() - radius, radius * 2, radius * 2);
    }

DrawRectangle类是类似的。

1 个答案:

答案 0 :(得分:2)

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

有关详细信息,请参阅Performing Custom PaintingPainting in AWT and Swing