Java Swing 上的事件链
Events chain on Java Swing
我基本上想制作一个 window 应用程序,用户可以在其中绘制分段线。申请流程应该是:
- 用户单击应用程序的唯一按钮以启动进程
- 用户通过点击线段的第一个点进行选择
- 用户通过点击线段的第二个点进行选择
我已经有了以下代码:
public class LineEditor extends JComponent{
private class Point{
int x, y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
private class Line{
Point a, b;
public Line(Point a, Point b){
this.a = a;
this.b = b;
}
}
private ArrayList<Line> lines = new ArrayList<Line>();
public void setLine(Point a, Point b){
lines.add(new Line(a, b));
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : lines) {
g.setColor(line.color);
g.drawLine(line.a.x, line.a.y, line.b.x, line.b.y);
}
}
public static void main(String[] args){
int height = 500, width = 500;
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Properties of the main window
frame.setAlwaysOnTop(true);
final LineEditor lineEditor = new LineEditor();
lineEditor.setPreferredSize(new Dimension(width, height));
JPanel panelCanvas = new JPanel();
panelCanvas.setPreferredSize(new Dimension(width, height));
JPanel secondaryPanel = new JPanel();
JButton addLineButton = new JButton("Add new line");
secondaryPanel.add(addLineButton);
frame.getContentPane().add(lineEditor, BorderLayout.CENTER);
frame.getContentPane().add(panelCanvas, BorderLayout.CENTER);
frame.getContentPane().add(secondaryPanel, BorderLayout.NORTH);
panelCanvas.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
}
});
addLineButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// x
}
});
frame.pack();
frame.setVisible(true);
}
}
我不知道如何:
- 仅在用户按下按钮后激活 panelCanvas.addMouseListener。
- 从 addLineButton.addActionListener 获取鼠标坐标(点击后),这样我就可以创建两个 Point 对象,然后调用 lineEditor.setLine(pointA, pointB)
我想实现这样的目标:
addLineButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Wait for the first user click
int x1 = mouseListener.getX();
int y1 = mouseListener.getY();
Point a = new Point(x1, y1);
// Wait for the second user click
int x2 = mouseListener.getX();
int y2 = mouseListener.getY();
Point b = new Point(x2, y2);
lineEditor.setLine(a, b);
}
});
我终于解决了这个问题,方法是在绘制新线时强制用户遵循下一个流程:
- 当用户第一次尝试点击线条的第一个点时,会打开一个 JColor 框,以便轻松选择线条颜色。
- 然后,用户必须单击要设置线的第一个点的第一个点。
- 线的第二个点将位于用户释放点击按钮的坐标。
请注意,这只是我正在寻找的一种方法(第一次点击&释放=第一点,第二次点击&释放=第二点),但我仍然认为这对于挥杆初学者来说可能是一个很好的示例。
public class LineEditor extends JComponent{
private static class Point{
final int x, y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
private static class Line{
final Point a, b;
final Color color;
public Line(Point a, Point b, Color color) {
this.a = a;
this.b = b;
this.color = color;
}
}
private final LinkedList<Line> lines = new LinkedList<Line>();
public void addLine(int xa, int ya, int xb, int yb, Color color) {
lines.add(new Line(new Point(xa, ya), new Point(xb, yb), color));
repaint();
}
public void clearScreen() {
if(lines.size() > 0){
lines.remove(lines.getLast());
repaint();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : lines) {
g.setColor(line.color);
g.drawLine(line.a.x, line.a.y, line.b.x, line.b.y);
}
}
public static void main(String[] args) {
int width, height;
width = 500;
height = 500;
JFrame backgroundFrame = new JFrame();
backgroundFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final LineEditor lineEditor = new LineEditor();
lineEditor.setPreferredSize(new Dimension(width, height));
backgroundFrame.getContentPane().add(lineEditor, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel();
JButton clearScreen = new JButton("Remove last line");
buttonsPanel.add(clearScreen);
backgroundFrame.getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
backgroundFrame.addMouseListener(new MouseAdapter() {
int ax, ay, bx, by;
Color color;
Boolean colorSetted = false;
@Override
public void mouseEntered(MouseEvent e) {
if(!colorSetted){
JColorChooser colorChooser =new JColorChooser();
this.color = colorChooser.showDialog(null, "Select a color", Color.BLACK);
colorSetted = true;
}
}
@Override
public void mousePressed(MouseEvent e) {
ax = e.getX();
ay = e.getY();
System.out.println("Mouse pressed: " + ax + ", " + ay);
}
@Override
public void mouseReleased(MouseEvent e) {
bx = e.getX();
by = e.getY();
System.out.println("Mouse released: " + bx + ", " + by);
lineEditor.addLine(ax, ay, bx, by, color);
colorSetted = false;
}
});
clearScreen.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
lineEditor.clearScreen();
}
});
backgroundFrame.pack();
backgroundFrame.setVisible(true);
}
}
我基本上想制作一个 window 应用程序,用户可以在其中绘制分段线。申请流程应该是:
- 用户单击应用程序的唯一按钮以启动进程
- 用户通过点击线段的第一个点进行选择
- 用户通过点击线段的第二个点进行选择
我已经有了以下代码:
public class LineEditor extends JComponent{
private class Point{
int x, y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
private class Line{
Point a, b;
public Line(Point a, Point b){
this.a = a;
this.b = b;
}
}
private ArrayList<Line> lines = new ArrayList<Line>();
public void setLine(Point a, Point b){
lines.add(new Line(a, b));
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : lines) {
g.setColor(line.color);
g.drawLine(line.a.x, line.a.y, line.b.x, line.b.y);
}
}
public static void main(String[] args){
int height = 500, width = 500;
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Properties of the main window
frame.setAlwaysOnTop(true);
final LineEditor lineEditor = new LineEditor();
lineEditor.setPreferredSize(new Dimension(width, height));
JPanel panelCanvas = new JPanel();
panelCanvas.setPreferredSize(new Dimension(width, height));
JPanel secondaryPanel = new JPanel();
JButton addLineButton = new JButton("Add new line");
secondaryPanel.add(addLineButton);
frame.getContentPane().add(lineEditor, BorderLayout.CENTER);
frame.getContentPane().add(panelCanvas, BorderLayout.CENTER);
frame.getContentPane().add(secondaryPanel, BorderLayout.NORTH);
panelCanvas.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
int x = e.getX();
int y = e.getY();
}
});
addLineButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// x
}
});
frame.pack();
frame.setVisible(true);
}
}
我不知道如何:
- 仅在用户按下按钮后激活 panelCanvas.addMouseListener。
- 从 addLineButton.addActionListener 获取鼠标坐标(点击后),这样我就可以创建两个 Point 对象,然后调用 lineEditor.setLine(pointA, pointB)
我想实现这样的目标:
addLineButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// Wait for the first user click
int x1 = mouseListener.getX();
int y1 = mouseListener.getY();
Point a = new Point(x1, y1);
// Wait for the second user click
int x2 = mouseListener.getX();
int y2 = mouseListener.getY();
Point b = new Point(x2, y2);
lineEditor.setLine(a, b);
}
});
我终于解决了这个问题,方法是在绘制新线时强制用户遵循下一个流程:
- 当用户第一次尝试点击线条的第一个点时,会打开一个 JColor 框,以便轻松选择线条颜色。
- 然后,用户必须单击要设置线的第一个点的第一个点。
- 线的第二个点将位于用户释放点击按钮的坐标。
请注意,这只是我正在寻找的一种方法(第一次点击&释放=第一点,第二次点击&释放=第二点),但我仍然认为这对于挥杆初学者来说可能是一个很好的示例。
public class LineEditor extends JComponent{
private static class Point{
final int x, y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
private static class Line{
final Point a, b;
final Color color;
public Line(Point a, Point b, Color color) {
this.a = a;
this.b = b;
this.color = color;
}
}
private final LinkedList<Line> lines = new LinkedList<Line>();
public void addLine(int xa, int ya, int xb, int yb, Color color) {
lines.add(new Line(new Point(xa, ya), new Point(xb, yb), color));
repaint();
}
public void clearScreen() {
if(lines.size() > 0){
lines.remove(lines.getLast());
repaint();
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : lines) {
g.setColor(line.color);
g.drawLine(line.a.x, line.a.y, line.b.x, line.b.y);
}
}
public static void main(String[] args) {
int width, height;
width = 500;
height = 500;
JFrame backgroundFrame = new JFrame();
backgroundFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final LineEditor lineEditor = new LineEditor();
lineEditor.setPreferredSize(new Dimension(width, height));
backgroundFrame.getContentPane().add(lineEditor, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel();
JButton clearScreen = new JButton("Remove last line");
buttonsPanel.add(clearScreen);
backgroundFrame.getContentPane().add(buttonsPanel, BorderLayout.SOUTH);
backgroundFrame.addMouseListener(new MouseAdapter() {
int ax, ay, bx, by;
Color color;
Boolean colorSetted = false;
@Override
public void mouseEntered(MouseEvent e) {
if(!colorSetted){
JColorChooser colorChooser =new JColorChooser();
this.color = colorChooser.showDialog(null, "Select a color", Color.BLACK);
colorSetted = true;
}
}
@Override
public void mousePressed(MouseEvent e) {
ax = e.getX();
ay = e.getY();
System.out.println("Mouse pressed: " + ax + ", " + ay);
}
@Override
public void mouseReleased(MouseEvent e) {
bx = e.getX();
by = e.getY();
System.out.println("Mouse released: " + bx + ", " + by);
lineEditor.addLine(ax, ay, bx, by, color);
colorSetted = false;
}
});
clearScreen.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
lineEditor.clearScreen();
}
});
backgroundFrame.pack();
backgroundFrame.setVisible(true);
}
}