简体   繁体   中英

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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