java - mouseMoved(MouseEvent e) 跟不上程序逻辑

标签 java swing graphics mouseevent java-2d

我写了一个无用的程序,它给你的鼠标指针添加了一条红色的轨迹。但是,如果鼠标移动得太快,轨迹就会扭曲。我认为我的问题出在我的 paintComponent(Graphics g) 方法或 mouseMoved(MouseEvent e) 方法中。有什么想法可以让 Swing 绘制出更平滑的路径吗?

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.MouseInputAdapter;

public class TrailTest {

    //needs SwingUtilities.invokeLater but this a test class
    public static void main(String[] args) {
        JFrame f = new JFrame();
        TrailPanel p = new TrailPanel();
        p.setOpaque(false);
        p.addMouseMotionListener(new MouseInputAdapter() {

            @Override
            public void mouseMoved(MouseEvent e) {
                //can't add enough points? or my rendering policy is bad?
                p.put(e.getPoint());
                p.repaint();
            }

        });
        f.add(p);
        f.setSize(500, 500);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    private static class TrailPanel extends JPanel {

        private static final long serialVersionUID = 214019134136464119L;

        private ConcurrentHashMap<Point, Integer> m;

        public TrailPanel() {
            m = new ConcurrentHashMap<>();
            Thread t = new Thread(() -> {
                while (true) {
                    m.replaceAll((k, v) -> v - 10);
                    m.entrySet().removeIf(entry -> entry.getValue() < 0);
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    repaint();
                }
            });
            t.start();
        }

        public void put(Point p) {
            m.put(p, 1020);
        }

        //problem is with the rendering policy????? idk, help :(
        public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setStroke(new BasicStroke(3));
            for (Entry<Point, Integer> entry : m.entrySet()) {
                Point p = entry.getKey();
                try {
                    g2d.setColor(new Color(255, 0, 0, entry.getValue() / 4));
                } catch (IllegalArgumentException ex) {}
                g2d.drawArc((int) p.getX(), (int) p.getY(), 1, 1, 0, 360);
            }
        }
    }
}

最佳答案

多亏了安德鲁·汤普森的想法,我的工作速度非常快。我创建了另一个 HashMap ,它将一个 Point 映射到另一个 Point。然后在我的 paintComponent(Graphics g) 方法中,我在它们之间画了一条线。这样,点之间的空间就消失了。

注意:该解决方案使用 LinkedHashMap,因为 LinkedHashMap 在执行操作时保留插入顺序。

工作代码:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.MouseInputAdapter;

public class TrailTest {

    public static void main(String[] args) {
        JFrame f = new JFrame();
        TrailPanel p = new TrailPanel();
        p.setOpaque(false);
        p.addMouseMotionListener(new MouseInputAdapter() {

            // must remember to connect the current with the last one
            private Point lastPoint = null;

            @Override
            public void mouseMoved(MouseEvent e) {
                final Point mouseLocation = e.getPoint();
                if (lastPoint != null) {
                    p.put(mouseLocation);
                    p.connect(mouseLocation, lastPoint);
                }
                lastPoint = mouseLocation;
                p.repaint();
            }
        });
        f.add(p);
        f.setSize(500, 500);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    private static class TrailPanel extends JPanel {

        private static final long serialVersionUID = 214019134136464119L;

        private ConcurrentHashMap<Point, Integer> points;
        private LinkedHashMap<Point, Point> lines;

        public TrailPanel() {
            points = new ConcurrentHashMap<>();
            lines = new LinkedHashMap<>();
            Thread t = new Thread(() -> {
                while (true) {
                    points.replaceAll((k, v) -> v - 10);
                    points.entrySet().removeIf(entry -> entry.getValue() < 0);
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    repaint();
                }
            });
            t.start();
        }

        public void connect(Point p1, Point p2) {
            lines.put(p1, p2);
        }

        public void put(Point p) {
            points.put(p, 1020);
        }

        public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setStroke(new BasicStroke(3));

            for (Entry<Point, Integer> entry : points.entrySet()) {
                Point p = entry.getKey();
                try {
                    g2d.setColor(new Color(255, 0, 0, entry.getValue() / 4));
                } catch (IllegalArgumentException ex) {}
                //might want to comment drawArc if you want to make it look better by a liiiiitle.
                g2d.drawArc((int) p.getX(), (int) p.getY(), 1, 1, 0, 360);
                g2d.drawLine((int) p.getX(), (int) p.getY(), (int) lines.get(p).getX(), (int) lines.get(p).getY());
            }
        }
    }
}

关于java - mouseMoved(MouseEvent e) 跟不上程序逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51111689/

相关文章:

java - 错误 : base operand of ‘->’ has non-pointer type ‘JNIEnv’

java - 无法弄清楚如何读取txt文件中的分数并输出到Java中的不同txt文件

java - 使用 ComboBox 更新 JTable 中的特定单元格

java - 弹出菜单不显示

java - 当我向堆栈推送较少数据时,为什么堆栈会溢出?

Java 小程序 : free up Graphics resources

java - Files.createSymbolicLink() 采用 FileAttribute<?> 数组作为参数;它在任何操作系统上都有意义吗?

java - 来自第 3 方的 WSDL 具有硬编码 IP

java - 在多个 JPanel 中绘图

android - 目前有安卓版的图片编辑SDK吗