简体   繁体   English

Java Swing 上的事件链

[英]Events chain on Java Swing

I basically wanna make a single window application where the user will be able to draw segment lines.我基本上想做一个单窗口应用程序,用户可以在其中绘制线段。 The application flow should be:申请流程应该是:

  1. The user clicks the unique button of the app in order to start the process用户单击应用程序的唯一按钮以启动该过程
  2. The user selects by clicking the first point of the segment用户通过单击线段的第一个点来选择
  3. The user selects by clicking the second point of the segment用户通过单击线段的第二个点来选择

I already have the following piece of code:我已经有了以下代码:

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);

        }
    }

I don't get how to:我不明白如何:

  1. Activate the panelCanvas.addMouseListener only after the user has pressed the button.仅在用户按下按钮后激活 panelCanvas.addMouseListener。
  2. Get the mouse coordinates (after the click has been made) from the addLineButton.addActionListener so I can create two Point objects and after that make a call to lineEditor.setLine(pointA, pointB)从 addLineButton.addActionListener 获取鼠标坐标(点击后),这样我就可以创建两个 Point 对象,然后调用 lineEditor.setLine(pointA, pointB)

I wanna achieve something like:我想实现类似的东西:

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);
    }
});

I finally solved the problem by forcing the user to follow the next flow when drawing a new line:我最终通过强制用户在绘制新线时遵循下一个流程解决了问题:

  1. When the user firsts try to click on the first point of the line, a JColor box is opened so the line colour can be easily selected.当用户第一次尝试单击线条的第一个点时,会打开一个 JColor 框,以便可以轻松选择线条颜色。
  2. Then, the user has to click on the first point where he wants to set the first point of the line.然后,用户必须单击他想要设置线的第一个点的第一个点。
  3. The second point of the line will be located in the coordinates where the user releases the click button.该线的第二个点将位于用户释放单击按钮的坐标中。

Note that this's just an approach to what I was looking for (first click&release=first point, second click&release=second point), but still I think it could be a nice sample for swing beginners.请注意,这只是我正在寻找的一种方法(第一次点击&释放=第一点,第二次点击&释放=第二点),但我仍然认为这对于挥杆初学者来说可能是一个很好的例子。

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM