我正在实现一个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类是类似的。
答案 0 :(得分:2)
paint
方法中加载类不是一个好主意,因为这可能会花费宝贵的时间,这可能会导致屏幕更新延迟paint
,它们不是双缓冲的。相反,创建一个自定义组件,从JPanel
扩展并覆盖它的paintComponent
方法,将自定义绘图放入(不要忘记先调用super.paintComponent
)。有关详细信息,请参阅Performing Custom Painting和Painting in AWT and Swing