为了账号安全,请及时绑定邮箱和手机立即绑定

java减少mouseMotionListener间隔之间的时间

java减少mouseMotionListener间隔之间的时间

GCT1015 2021-11-24 18:41:11
我想在 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);                    }                }            });    }}有没有办法改善这个或更好的方法?
查看完整描述

1 回答

?
萧十郎

TA贡献1815条经验 获得超13个赞

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

{

    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();

            }

        });

*/

    }

}

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


另一种方法是绘制到 aBufferedImage然后BufferedImage在面板上绘制。您可以查看自定义绘画方法以获取此方法的示例。


查看完整回答
反对 回复 2021-11-24
  • 1 回答
  • 0 关注
  • 121 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信