如何在快速的鼠标光标拖动上绘制重复的椭圆的连续曲线? [英] How to draw a continuous curve of repeated ovals on speedy mouse cursor dragging?

查看:114
本文介绍了如何在快速的鼠标光标拖动上绘制重复的椭圆的连续曲线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此代码用于在JPanel上绘制.在paintComponent(Graphics)中,我试图通过重复的Graphics2D#fillOval(x, y, with, height)绘制曲线.

This code is for drawing on a JPanel. In the paintComponent(Graphics) I am trying to draw curves via repeated Graphics2D#fillOval(x, y, with, height).

该应用程序运行正常,当我缓慢拖动鼠标光标时;它根据需要绘制一条连续曲线.但是,当我加快拖动鼠标光标的速度时,结果是分开的点而不是连续的曲线.

The app is working OK, and when I drag the mouse cursor slowly; it draws a continuous curve as I need. But when I speed up dragging the mouse cursor, the result is separated dots and not a continuous curve.

那么,即使我加快拖动速度,如何使它绘制连续的曲线呢?

So how to make it draw a continuous curve even if I speed up dragging?

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;

public class Painter extends JPanel {

    int x, y;
    ArrayList<Point> points;

    public Painter() {

        setBackground(Color.white);
        points = new ArrayList<>();

        MouseHandler listener = new MouseHandler();
        this.addMouseMotionListener(listener);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(600, 600);
    }

    private class MouseHandler extends MouseAdapter implements MouseMotionListener {

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

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

        Graphics2D g2d = (Graphics2D) g;
        for (Point point : points) {
            g2d.fillOval(point.x, point.y, 15, 15);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setContentPane(new Painter());
                f.pack();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
            }
        });
    }
}

推荐答案

正如您对之前的类似问题的评论中所述:

As mentioned in comment to your previous similar question:

  • 不要在paintComponent方法中绘制离散的椭圆.
  • 相反,通过在相邻点之间绘制线来连接paintComponent中List中保持的点.
  • 如果需要使线变粗,请使用更粗的线来更改Graphics2D对象的Stroke属性.
  • 但是请谨慎使用Strokes,因为通常您不希望属性更改沿绘画链传播.这意味着有时您将需要复制Graphics对象,并在新的Graphics对象上设置Stroke并用它进行绘画,然后将其处理.
  • 创建笔触的最简单方法是使用BasicStroke类,例如,new BasicStroke(6f)将使您获得漂亮的粗曲线.
  • Don't draw discrete ovals in your paintComponent method.
  • Instead connect the points hold in the List in the paintComponent by drawing lines between adjacent points.
  • If you need to make the line thicker, change the Stroke property of the Graphics2D object, using one that has a wider thickness.
  • Be careful with Strokes however since often you don't want the property change to propagate down the paint chain. This means that sometimes you will want to copy the Graphics object and set the Stroke on the new Graphics object and paint with that, then dispose of it.
  • The simplest way to create a Stroke is to use the BasicStroke class, e.g., new BasicStroke(6f) will get you a nice thick curve.

例如:

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

import javax.swing.*;

public class Painter2 extends JPanel {

    private static final float STROKE_WIDTH = 15f;
    private static final Stroke STROKE = new BasicStroke(STROKE_WIDTH, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
    int x, y;
    ArrayList<Point> points;

    public Painter2() {

        setBackground(Color.white);
        points = new ArrayList<>();

        MouseHandler listener = new MouseHandler();
        this.addMouseMotionListener(listener);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(600, 600);
    }

    private class MouseHandler extends MouseAdapter implements MouseMotionListener {

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

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

        Graphics2D g2d = (Graphics2D) g;
        g2d.setStroke(STROKE);
        for (int i = 1; i < points.size(); i++) {
            int x1 = points.get(i - 1).x;
            int y1 = points.get(i - 1).y;
            int x2 = points.get(i).x;
            int y2 = points.get(i).y;
            g2d.drawLine(x1, y1, x2, y2);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setContentPane(new Painter2());
                f.pack();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
            }
        });
    }
}

或更妙的是:

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class Painter2 extends JPanel {

    private static final float STROKE_WIDTH = 15f;
    private static final Stroke STROKE = new BasicStroke(STROKE_WIDTH, BasicStroke.CAP_ROUND,
            BasicStroke.JOIN_ROUND);
    private static final Color CURVES_COLOR = Color.BLUE;
    private static final Color TEMP_CURVE_COLOR = Color.PINK;
    private List<List<Point>> curvesList = new ArrayList<>();
    private List<Point> tempCurve = null;

    public Painter2() {
        setBackground(Color.white);
        MouseHandler listener = new MouseHandler();
        addMouseListener(listener);
        addMouseMotionListener(listener);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(600, 600);
    }

    private class MouseHandler extends MouseAdapter implements MouseMotionListener {
        @Override
        public void mousePressed(MouseEvent e) {
            tempCurve = new ArrayList<>();
            tempCurve.add(e.getPoint());
            repaint();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            tempCurve.add(e.getPoint());
            repaint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            tempCurve.add(e.getPoint());
            curvesList.add(tempCurve);
            tempCurve = null;
            repaint();
        }
    }

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

        Graphics2D g2 = (Graphics2D) g.create();
        g2.setStroke(STROKE);
        g2.setColor(CURVES_COLOR);
        for (List<Point> curve : curvesList) {
            drawCurve(g2, curve);
        }

        if (tempCurve != null) {
            g2.setColor(TEMP_CURVE_COLOR);
            drawCurve(g2, tempCurve);
        }

        g2.dispose();
    }

    private void drawCurve(Graphics2D g2, List<Point> ptList) {
        for (int i = 1; i < ptList.size(); i++) {
            int x1 = ptList.get(i - 1).x;
            int y1 = ptList.get(i - 1).y;
            int x2 = ptList.get(i).x;
            int y2 = ptList.get(i).y;
            g2.drawLine(x1, y1, x2, y2);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setContentPane(new Painter2());
                f.pack();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setVisible(true);
            }
        });
    }
}

这篇关于如何在快速的鼠标光标拖动上绘制重复的椭圆的连续曲线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆