Swing:如何减少MouseInputAdapter的响应时间?

jizhihaoSAMA

我已经制作了一个可以允许用户绘制屏幕截图的工具。这是我的代码:

package GUI.Views;

import javax.swing.*;
import javax.swing.event.MouseInputAdapter;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

public class Canvas extends JPanel {
    public static int radius = 5;
    public class DrawPointListener extends MouseInputAdapter{
        private void draw(Point p, int radius){
            Graphics2D g2 = (Graphics2D)getGraphics();
            int x = (int)p.getX() - radius/2;
            int y = (int)p.getY() - radius/2;
            g2.fillOval(x, y, radius, radius);
        }

        @Override
        public void mousePressed(MouseEvent e) {
            draw(e.getPoint(), radius);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            draw(e.getPoint(), radius);
        }
    }

    private BufferedImage screenShot;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(this.screenShot, 0, 0, null);
    }


    public Canvas() {
        this.setVisible(true);
        this.screenShot = getScreenShot();
        this.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));

        DrawPointListener drawListener = new DrawPointListener();

        this.addMouseListener(drawListener);
        this.addMouseMotionListener(drawListener);
    }

    private BufferedImage getScreenShot() {
        try {
            return new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));

        } catch (AWTException e) {
            System.out.println("Error");
            return null;
        }
    }

    public static void main(String[] args) {
        JFrame f = new JFrame();
        Canvas canvas = new Canvas();
        f.setUndecorated(true);
        f.add(canvas);
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.setVisible(true);
    }
}

当您尝试"draw"在屏幕上缓慢运行时,代码可以正常工作,但是当您快速移动鼠标时,您会看到这些点不是连续的,如下所示:

在此处输入图片说明

我认为是因为存在时间间隔。Listener我该如何改善?

卡米克尔

您无法更改监听器的时间间隔。您不能保证为每个像素生成一个事件。

因此,您无需绘制单个点,而是需要在当前点和上一个点之间绘制一条线。

就像是:

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();
            }
        });
*/
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何测量Sails.js请求/响应时间

来自分类Dev

如何减少服务器响应时间?

来自分类Dev

Web API响应时间

来自分类Dev

如何在jmeter中获取网页的响应时间?

来自分类Dev

如何衡量服务器的请求和响应时间?

来自分类Dev

如何使用PHP获取服务器响应时间

来自分类Dev

如何动态/响应时间更改jQuery datepicker的月数

来自分类Dev

如何在MySQL中记录查询响应时间?

来自分类Dev

如何使用Facebook API查询页面响应时间?

来自分类Dev

如何使用Retrofit 2获得API请求/响应时间

来自分类Dev

如何使用ELK堆栈监视nginx响应时间?

来自分类Dev

如何测量和显示“处理中”按键的响应时间?

来自分类Dev

Jmeter:响应时间减少,吞吐量也减少

来自分类Dev

Python异步响应时间

来自分类Dev

如何使用耗时承诺来提高响应时间?

来自分类Dev

推入Git的响应时间

来自分类Dev

如何减少服务器响应时间?

来自分类Dev

NSXMLParser响应时间

来自分类Dev

Web API响应时间

来自分类Dev

如何分析响应时间图

来自分类Dev

WSO2 APIM群集-如何缩短响应时间?

来自分类Dev

减少服务器响应时间-Debian 7上的apache2

来自分类Dev

如何改进/最小化 api 的不同响应时间

来自分类Dev

如何理解jmeter结果的响应时间图?

来自分类Dev

如何使用 Xcode 检查 API 的响应时间(性能)?

来自分类Dev

平均 90% 响应时间和平均响应时间

来自分类Dev

减少查询响应时间,需要优化查询

来自分类Dev

某些任务的响应时间正在减少

来自分类Dev

测试响应时间