gpt4 book ai didi

java减少mouseMotionListener间隔之间的时间

转载 作者:行者123 更新时间:2023-11-30 10:10:19 25 4
gpt4 key购买 nike

我想在 java 中创建一个简单的绘图程序,目前它只使用 Graphics.fillOval()mouseMotionListener() 绘制一条线。问题是,如果您快速移动鼠标,线条会变得不那么精确,椭圆形(在本例中为圆形)会散开。

代码如下:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Drawing
{
private JFrame window;
private Graphics g;
public Drawing()
{
window=new JFrame();
window.setTitle("Paint_window");
window.setSize(1000,700);
window.setVisible(true);
window.setDefaultCloseOperation(window.EXIT_ON_CLOSE);
g=window.getGraphics();
window.addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent e)
{
if(SwingUtilities.isLeftMouseButton(e)
{
g.fillOval((int)e.getX(),(int)e.getY(),10,10);
}
}
});
}
}

是否有改进或更好的方法?

最佳答案

g=window.getGraphics();

首先,您不应该使用组件的 getGraphics()。您所做的任何绘制都只是暂时的,并且会在 Swing 第一次确定组件需要重新绘制时被删除。在上面的示例中,只需尝试调整框架的大小即可看到这一点。

进行自定义绘画的正确方法是覆盖 JPanel 的 paintComponent(...) 方法并将面板添加到框架中。参见 Custom Painting获取更多信息。

The problem is, that if you move the mouse quickly the line gets less precise and the ovals (circles in this case) spread apart

您将无法为鼠标移动的每个像素生成一个事件。

相反,您需要能够在拖动鼠标时生成的连续点之间“画一条线”。

因此您需要将每个点存储在一个 ArrayList 中,并在自定义绘制代码中遍历所有点并绘制一条线。

帮助您入门的基本示例:

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;

class DrawingPanel extends JPanel
{
private ArrayList<ArrayList<Point>> previous = new ArrayList<ArrayList<Point>>();
private ArrayList<Point> current = new ArrayList<Point>();
private BasicStroke basicStroke;

public DrawingPanel(int strokeSize)
{
basicStroke = new BasicStroke(strokeSize, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);

MouseAdapter ma = new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent e)
{
current.add( new Point(e.getX(), e.getY()) );
}

@Override
public void mouseDragged(MouseEvent e)
{
current.add( new Point(e.getX(), e.getY()) );
repaint();
}

@Override
public void mouseReleased(MouseEvent e)
{
if (current.size() > 1)
{
previous.add( current );
}

current = new ArrayList<Point>();
}
};

addMouseMotionListener( ma );
addMouseListener( ma );
}

@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);

Graphics2D g2 = (Graphics2D) g;
g2.setStroke( basicStroke );

// Paint lines from previous drags

for (int i = 0; i < previous.size(); i++)
{
drawLines(g, previous.get(i));
}

// Paint line from current drag

drawLines(g, current);
}

private void drawLines(Graphics g, ArrayList<Point> points)
{
for (int i = 0; i < points.size() - 1; i++)
{
int x = (int) points.get(i).getX();
int y = (int) points.get(i).getY();
int x2 = (int) points.get(i + 1).getX();
int y2 = (int) points.get(i + 1).getY();
g.drawLine(x, y, x2, y2);
}
}

private static void createAndShowGUI()
{
JFrame frame = new JFrame("Drawing Panel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawingPanel(15));
frame.setSize(400, 400);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}

public static void main(String[] args) throws Exception
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}

使用上述方法,您将在每次重新绘制组件时重新绘制线条。

另一种方法是绘制到 BufferedImage,然后在面板上绘制 BufferedImage。你可以看看Custom Painting Approaches有关此方法的示例。

关于java减少mouseMotionListener间隔之间的时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52871760/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com