簡體   English   中英

Java Swing 上的事件鏈

[英]Events chain on Java Swing

我基本上想做一個單窗口應用程序,用戶可以在其中繪制線段。 申請流程應該是:

  1. 用戶單擊應用程序的唯一按鈕以啟動該過程
  2. 用戶通過單擊線段的第一個點來選擇
  3. 用戶通過單擊線段的第二個點來選擇

我已經有了以下代碼:

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

        }
    }

我不明白如何:

  1. 僅在用戶按下按鈕后激活 panelCanvas.addMouseListener。
  2. 從 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);
    }
});

我最終通過強制用戶在繪制新線時遵循下一個流程解決了問題:

  1. 當用戶第一次嘗試單擊線條的第一個點時,會打開一個 JColor 框,以便可以輕松選擇線條顏色。
  2. 然后,用戶必須單擊他想要設置線的第一個點的第一個點。
  3. 該線的第二個點將位於用戶釋放單擊按鈕的坐標中。

請注意,這只是我正在尋找的一種方法(第一次點擊&釋放=第一點,第二次點擊&釋放=第二點),但我仍然認為這對於揮桿初學者來說可能是一個很好的例子。

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