猿问

java减少mouseMotionListener间隔之间的时间

我想在 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);

                    }

                }

            });

    }

}

有没有办法改善这个或更好的方法?


GCT1015
浏览 122回答 1
1回答

萧十郎

g=window.getGraphics();首先,您不应该使用组件的 getGraphics()。您所做的任何绘制都只是暂时的,并且会在 Swing 第一次确定需要重新绘制组件时被擦除。在上面的示例中,只需尝试调整框架大小即可看到这一点。进行自定义绘制的正确方法是覆盖paintComponent(...)JPanel的方法并将面板添加到框架中。有关更多信息,请参阅自定义绘画。问题是,如果你快速移动鼠标,线条变得不那么精确,椭圆(在这种情况下是圆圈)散开您将无法为鼠标移动的每个像素生成一个事件。相反,您需要能够在拖动鼠标时生成的连续点之间“画一条线”。因此,您需要将每个点存储在一个 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{&nbsp; &nbsp; private ArrayList<ArrayList<Point>> previous = new ArrayList<ArrayList<Point>>();&nbsp; &nbsp; private ArrayList<Point> current = new ArrayList<Point>();&nbsp; &nbsp; private BasicStroke basicStroke;&nbsp; &nbsp; public DrawingPanel(int strokeSize)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; basicStroke = new BasicStroke(strokeSize, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);&nbsp; &nbsp; &nbsp; &nbsp; MouseAdapter ma = new MouseAdapter()&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void mousePressed(MouseEvent e)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current.add( new Point(e.getX(), e.getY()) );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void mouseDragged(MouseEvent e)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current.add( new Point(e.getX(), e.getY()) );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; repaint();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void mouseReleased(MouseEvent e)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (current.size() > 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; previous.add( current );&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; current = new ArrayList<Point>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; addMouseMotionListener( ma );&nbsp; &nbsp; &nbsp; &nbsp; addMouseListener( ma );&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; protected void paintComponent(Graphics g)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; super.paintComponent(g);&nbsp; &nbsp; &nbsp; &nbsp; Graphics2D g2 = (Graphics2D) g;&nbsp; &nbsp; &nbsp; &nbsp; g2.setStroke( basicStroke );&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; Paint lines from previous drags&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < previous.size(); i++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; drawLines(g, previous.get(i));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; Paint line from current drag&nbsp; &nbsp; &nbsp; &nbsp; drawLines(g, current);&nbsp; &nbsp; }&nbsp; &nbsp; private void drawLines(Graphics g, ArrayList<Point> points)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < points.size() - 1; i++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int x = (int) points.get(i).getX();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int y = (int) points.get(i).getY();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int x2 = (int) points.get(i + 1).getX();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int y2 = (int) points.get(i + 1).getY();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; g.drawLine(x, y, x2, y2);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; private static void createAndShowGUI()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; JFrame frame = new JFrame("Drawing Panel");&nbsp; &nbsp; &nbsp; &nbsp; frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);&nbsp; &nbsp; &nbsp; &nbsp; frame.add(new DrawingPanel(15));&nbsp; &nbsp; &nbsp; &nbsp; frame.setSize(400, 400);&nbsp; &nbsp; &nbsp; &nbsp; frame.setLocationByPlatform( true );&nbsp; &nbsp; &nbsp; &nbsp; frame.setVisible( true );&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) throws Exception&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; EventQueue.invokeLater( () -> createAndShowGUI() );/*&nbsp; &nbsp; &nbsp; &nbsp; EventQueue.invokeLater(new Runnable()&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void run()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; createAndShowGUI();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });*/&nbsp; &nbsp; }}使用上述方法,您将在每次重新绘制组件时重新绘制线条。另一种方法是绘制到 aBufferedImage然后BufferedImage在面板上绘制。您可以查看自定义绘画方法以获取此方法的示例。
随时随地看视频慕课网APP

相关分类

Java
我要回答