Swing:我通过鼠标拖动绘制的任何线条只会在我下次拖动鼠标时显示
Swing: Any line I draw by mouse drag only shows up the next time I drag the mouse
我仍在学习 Java 的基础知识,如果这个问题很基础,我很抱歉。我试图做的是将点和线存储到 ArrayLists
中,然后让 paintComponent()
方法遍历它们并在每次调用时绘制它们。由于我对我的点使用相同的 ArrayList
,所以每次按下鼠标时我都会清除它,因此新行不会与前一行连接。
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.util.ArrayList;
public class SwingPaintDemo2 {
public static void main(String[] args) {
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(300,300);
f.add(new MyPanel());
f.setBackground(Color.WHITE);
f.setVisible(true);
}
}
class MyPanel extends JPanel {
private int x;
private int y;
private int x2;
private int y2;
private ArrayList<Point> points = new ArrayList<Point>();
private ArrayList<Curves> curvedLines = new ArrayList<Curves>();
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
points.add(new Point(e.getX(), e.getY()));
repaint();
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
points.clear();
points.add(new Point(e.getX(), e.getY()));
}
@Override
public void mouseReleased(MouseEvent e) {
ArrayList<Point> newPoints = new ArrayList<Point>();
for (int i = 0; i < points.size(); i++) {
newPoints.add(points.get(i));
}
curvedLines.add(new Curves(newPoints));
}
});
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
for (int c = 0; c < points.size() - 1; c++) {
x = (int) points.get(c).getX();
y = (int) points.get(c).getY();
x2 = (int) points.get(c + 1).getX();
y2 = (int) points.get(c + 1).getY();
g.drawLine(x, y, x2, y2);
}
for (int t = 0; t < curvedLines.size(); t++) {
ArrayList<Point> iterator = curvedLines.get(t).points;
for (int c = 0; c < iterator.size() - 1; c++) {
x = (int) iterator.get(c).getX();
y = (int) iterator.get(c).getY();
x2 = (int) iterator.get(c + 1).getX();
y2 = (int) iterator.get(c + 1).getY();
g.drawLine(x, y, x2, y2);
}
}
}
class Curves {
private ArrayList<Point> points;
public Curves(ArrayList<Point> points) {
this.points = new ArrayList<Point>();
this.points = points;
}
}
}
问题是,当我拖动鼠标时,没有画线,但是当我再次拖动鼠标时线出现了,它的点仍然被存储。是什么导致了这种明显的延迟?
在我最初的评论中,您被要求将上一个问题中给出的工作代码与您在此处 post 编辑的代码进行比较,以了解有何不同。
区别在于你在paintComponent()方法中添加了if/else语句。
I added the if/else statement because the paintComponenet wouldn't draw anything
这没有任何意义。当你添加一个 if/else 语句时,它意味着只能完成一种类型的绘画,要么画曲线,要么画点,但你永远不能同时做。
你总是想两者兼顾:
- 绘制添加到 mouseDragged() 事件中的点
- 绘制所有已添加到曲线的旧点。
所以去掉 if/else 语句。
此外,将来当您 post 编码 post 适当的 SSCCE 时,我们可以执行该代码。 post此处编写的代码没有 main() 方法或 JFrame,因此无法编译和测试。
根据 camickr 的建议,它对我来说很好用
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SwingPaintDemo2 {
public static void main(String[] args) {
new SwingPaintDemo2();
}
public SwingPaintDemo2() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MyPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class MyPanel extends JPanel {
private int x;
private int y;
private int x2;
private int y2;
private ArrayList<Point> points = new ArrayList<Point>();
private ArrayList<Curves> curvedLines = new ArrayList<Curves>();
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
points.add(new Point(e.getX(), e.getY()));
repaint();
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
points.clear();
points.add(new Point(e.getX(), e.getY()));
}
@Override
public void mouseReleased(MouseEvent e) {
ArrayList<Point> newPoints = new ArrayList<Point>();
for (int i = 0; i < points.size(); i++) {
newPoints.add(points.get(i));
}
curvedLines.add(new Curves(newPoints));
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
for (int c = 0; c < points.size() - 1; c++) {
x = (int) points.get(c).getX();
y = (int) points.get(c).getY();
x2 = (int) points.get(c + 1).getX();
y2 = (int) points.get(c + 1).getY();
g.drawLine(x, y, x2, y2);
}
for (int t = 0; t < curvedLines.size(); t++) {
ArrayList<Point> iterator = curvedLines.get(t).points;
for (int c = 0; c < iterator.size() - 1; c++) {
x = (int) iterator.get(c).getX();
y = (int) iterator.get(c).getY();
x2 = (int) iterator.get(c + 1).getX();
y2 = (int) iterator.get(c + 1).getY();
g.drawLine(x, y, x2, y2);
}
}
}
class Curves {
private ArrayList<Point> points;
public Curves(ArrayList<Point> points) {
this.points = new ArrayList<Point>();
this.points = points;
}
}
}
}
我仍在学习 Java 的基础知识,如果这个问题很基础,我很抱歉。我试图做的是将点和线存储到 ArrayLists
中,然后让 paintComponent()
方法遍历它们并在每次调用时绘制它们。由于我对我的点使用相同的 ArrayList
,所以每次按下鼠标时我都会清除它,因此新行不会与前一行连接。
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.util.ArrayList;
public class SwingPaintDemo2 {
public static void main(String[] args) {
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(300,300);
f.add(new MyPanel());
f.setBackground(Color.WHITE);
f.setVisible(true);
}
}
class MyPanel extends JPanel {
private int x;
private int y;
private int x2;
private int y2;
private ArrayList<Point> points = new ArrayList<Point>();
private ArrayList<Curves> curvedLines = new ArrayList<Curves>();
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
points.add(new Point(e.getX(), e.getY()));
repaint();
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
points.clear();
points.add(new Point(e.getX(), e.getY()));
}
@Override
public void mouseReleased(MouseEvent e) {
ArrayList<Point> newPoints = new ArrayList<Point>();
for (int i = 0; i < points.size(); i++) {
newPoints.add(points.get(i));
}
curvedLines.add(new Curves(newPoints));
}
});
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
for (int c = 0; c < points.size() - 1; c++) {
x = (int) points.get(c).getX();
y = (int) points.get(c).getY();
x2 = (int) points.get(c + 1).getX();
y2 = (int) points.get(c + 1).getY();
g.drawLine(x, y, x2, y2);
}
for (int t = 0; t < curvedLines.size(); t++) {
ArrayList<Point> iterator = curvedLines.get(t).points;
for (int c = 0; c < iterator.size() - 1; c++) {
x = (int) iterator.get(c).getX();
y = (int) iterator.get(c).getY();
x2 = (int) iterator.get(c + 1).getX();
y2 = (int) iterator.get(c + 1).getY();
g.drawLine(x, y, x2, y2);
}
}
}
class Curves {
private ArrayList<Point> points;
public Curves(ArrayList<Point> points) {
this.points = new ArrayList<Point>();
this.points = points;
}
}
}
问题是,当我拖动鼠标时,没有画线,但是当我再次拖动鼠标时线出现了,它的点仍然被存储。是什么导致了这种明显的延迟?
在我最初的评论中,您被要求将上一个问题中给出的工作代码与您在此处 post 编辑的代码进行比较,以了解有何不同。
区别在于你在paintComponent()方法中添加了if/else语句。
I added the if/else statement because the paintComponenet wouldn't draw anything
这没有任何意义。当你添加一个 if/else 语句时,它意味着只能完成一种类型的绘画,要么画曲线,要么画点,但你永远不能同时做。
你总是想两者兼顾:
- 绘制添加到 mouseDragged() 事件中的点
- 绘制所有已添加到曲线的旧点。
所以去掉 if/else 语句。
此外,将来当您 post 编码 post 适当的 SSCCE 时,我们可以执行该代码。 post此处编写的代码没有 main() 方法或 JFrame,因此无法编译和测试。
根据 camickr 的建议,它对我来说很好用
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SwingPaintDemo2 {
public static void main(String[] args) {
new SwingPaintDemo2();
}
public SwingPaintDemo2() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new MyPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class MyPanel extends JPanel {
private int x;
private int y;
private int x2;
private int y2;
private ArrayList<Point> points = new ArrayList<Point>();
private ArrayList<Curves> curvedLines = new ArrayList<Curves>();
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
points.add(new Point(e.getX(), e.getY()));
repaint();
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
points.clear();
points.add(new Point(e.getX(), e.getY()));
}
@Override
public void mouseReleased(MouseEvent e) {
ArrayList<Point> newPoints = new ArrayList<Point>();
for (int i = 0; i < points.size(); i++) {
newPoints.add(points.get(i));
}
curvedLines.add(new Curves(newPoints));
repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
for (int c = 0; c < points.size() - 1; c++) {
x = (int) points.get(c).getX();
y = (int) points.get(c).getY();
x2 = (int) points.get(c + 1).getX();
y2 = (int) points.get(c + 1).getY();
g.drawLine(x, y, x2, y2);
}
for (int t = 0; t < curvedLines.size(); t++) {
ArrayList<Point> iterator = curvedLines.get(t).points;
for (int c = 0; c < iterator.size() - 1; c++) {
x = (int) iterator.get(c).getX();
y = (int) iterator.get(c).getY();
x2 = (int) iterator.get(c + 1).getX();
y2 = (int) iterator.get(c + 1).getY();
g.drawLine(x, y, x2, y2);
}
}
}
class Curves {
private ArrayList<Point> points;
public Curves(ArrayList<Point> points) {
this.points = new ArrayList<Point>();
this.points = points;
}
}
}
}