我目前正在开发我的第一个项目,一个使用Java Swing和AWT的简单画图应用程序.在实现绘制功能时,我遇到了准确捕获鼠标移动的问题,特别是在快速移动鼠标时.
我已经设计了应用程序来更新绘图坐标以响应鼠标事件(PaintPanel类中的MouseDraged和MouseMoved方法),从而触发重绘来呈现绘图.然而,尽管我做出了努力,我还是注意到,快速的鼠标移动有时会导致跳过点,导致绘制的线条出现间隙.
下面是我的PaintPanel类,它管理绘画功能:
public class PaintPanel extends JPanel implements MouseMotionListener{
public Point mouseCoordinates;
boolean painting = false;
public PaintPanel() {
this.setPreferredSize(new Dimension(1000,550));
this.setBackground(Color.white);
this.addMouseMotionListener(this);
}
public void paintComponent(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if(painting == false) {
super.paintComponent(g2D);
}
if(mouseCoordinates != null) {
g2D.setColor(UtilePanel.col);
g2D.fillOval((int)mouseCoordinates.getX(),(int)mouseCoordinates.getY(),UtilePanel.brushSize, UtilePanel.brushSize);
this.setCursor( this.getToolkit().createCustomCursor(
new BufferedImage( 1, 1, BufferedImage.TYPE_INT_ARGB ),
new Point(),
null ) );
}
}
@Override
public void mouseDragged(MouseEvent e) {
mouseCoordinates = e.getPoint();
painting = true;
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
mouseCoordinates = e.getPoint();
repaint();
}
}
下面是UtilePanel类(如果它有帮助):
public class UtilePanel extends JPanel {
static Color col=Color.black;
static int brushSize = 5;
public UtilePanel(){
this.setPreferredSize(new Dimension (1000,150));
JPanel container = new JPanel();
container.setLayout(new GridLayout(1,0));
this.setLayout(new GridLayout(0,1));
Brushes brushes = new Brushes();
Shapes shapes = new Shapes();
LoadImage loadImage = new LoadImage();
container.add(brushes);
container.add(shapes);
container.add(loadImage);
this.add(new JPanel());
this.add(container);
this.add(new JPanel());
setBorder(BorderFactory.createEtchedBorder(0));
}
public class Brushes extends JPanel{
JRadioButton Size1;
JRadioButton Size2;
JRadioButton Size3;
JRadioButton Size4;
ButtonGroup group;
JButton color;
public Brushes() {
Size1 = new JRadioButton();
Size2 = new JRadioButton();
Size3 = new JRadioButton();
Size4 = new JRadioButton();
group = new ButtonGroup();
color = new JButton();
color.setBackground(col);
color.setBorder(BorderFactory.createEtchedBorder(0));
color.setPreferredSize(new Dimension(20,20));
Size1.setSelected(true);
JColorChooser colorchooser= new JColorChooser();
color.addActionListener(e->{
col = JColorChooser.showDialog(null, "Pick a color ",Color.black);
color.setBackground(col);
});
Size1.addActionListener(e->{
brushSize = 5;
});
Size2.addActionListener(e->{
brushSize = 10;
});
Size3.addActionListener(e->{
brushSize = 15;
});
Size4.addActionListener(e->{
brushSize = 20;
});
group.add(Size1);
group.add(Size2);
group.add(Size3);
group.add(Size4);
this.add(Size1);
this.add(Size2);
this.add(Size3);
this.add(Size4);
this.add(color);
this.setLayout(new FlowLayout());
}
}
public class Shapes extends JPanel{
public Shapes() {
ShapeButton circule = new ShapeButton ("circule");
ShapeButton rect = new ShapeButton ("Rectangle");
ShapeButton triangle = new ShapeButton ("Tri");
ShapeButton line = new ShapeButton ("Line");
this.setLayout(new FlowLayout());
ButtonGroup bg = new ButtonGroup();
bg.add(rect);
bg.add(triangle);
bg.add(circule);
bg.add(line);
this.add(circule);
this.add(rect);
this.add(triangle);
this.add(line);
}
class ShapeButton extends JRadioButton {
public ShapeButton(String s) {
setIcon((new ImageIcon(creatImage(new Color(0x00FFFFFF, true),s))));
setSelectedIcon(new ImageIcon(creatImage(Color.gray,s)));
}
}
public BufferedImage creatImage(Color color,String shape) {
BufferedImage bi = new BufferedImage(40,40, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) bi.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(5));
g.setColor(color);
g.fillRect(0,0,40,40);
g.setColor(Color.black);
switch(shape) {
case "circule":
g.drawOval(5, 5, 30,30);
break;
case "Rectangle":
g.drawRect(5,5,30,30);
break;
case "Tri":
int[] X= {5,16,30};
int[] Y= {30,5,30};
g.drawPolygon(X,Y,3);
break;
case "Line":
g.drawLine(5,30,30,5);
break;
}
//g.dispose();
return bi;
}
}
public class LoadImage extends JPanel{
public LoadImage() {
JButton loadButton = new JButton("Import Image");
loadButton.setPreferredSize(new Dimension(100,50));
JFileChooser f = new JFileChooser();
loadButton.addActionListener(e->{
int resp = f.showOpenDialog(null);
if(resp == JFileChooser.APPROVE_OPTION) {
File file = new File(f.getSelectedFile().getAbsolutePath());
System.out.println(file.getAbsolutePath());
}
});
this.add(loadButton);
}
}
}
此外,我try 加入一个游戏循环来持续轮询鼠标输入,希望它能提高捕捉鼠标移动的准确性.然而,即使在游戏循环到位的情况下,问题仍然存在.
我不确定我的绘画方法是否正确,或者是否有更好的方法来这样做.
有没有人能就如何改进鼠标事件捕获以确保精确呈现,特别是在快速鼠标移动期间提供见解或建议?
您的帮助我们将不胜感激.谢谢!