触发按钮事件时不绘制

Draw is not made when a button event is triggered

我正在尝试编写一个愚蠢的程序。我得到了这个名为 Canvas 的 JPanel,它应该按照给定的特定方向绘制线条,如您所见 here,目前我只是在创建按钮操作,而该按钮应该从第一列的第一个点到第二列的最后一个点(第四个)画一条线。 现在这些文本字段没有进入这个,因为它们暂时没有功能。

public class Canvas extends JPanel {
    static final int SCREEN_WIDTH = 300;
    static final int SCREEN_HEIGHT = 300;
    private Graphics g2d;
    
    public Canvas() {
        this.setPreferredSize(new Dimension(SCREEN_WIDTH,SCREEN_HEIGHT));
        this.setBackground(new Color(66, 64, 64));
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g2d = g;
        trazarLinea('a', 1, new Color(75, 201, 201));  // This draw the lines seen in the  
        trazarLinea('b', 3, new Color(240, 20, 255));  // image as example.
        trazarLinea('c', 1, new Color(235, 64, 52));
        trazarLinea('d', 2  , new Color(128, 64, 123));
        dibujarCirculos(); // This draw the orange circles seen in the image when the program is 
                           // executed.
    }
    
    public void dibujarCirculos() {
        g2d.setColor(new Color(230, 160, 30));
        g2d.fillOval(20, 20, 20, 20);
        g2d.fillOval(20, 97, 20, 20);
        g2d.fillOval(20, 182, 20, 20);
        g2d.fillOval(20, 255, 20, 20);
        g2d.fillOval(270, 20, 20, 20);
        g2d.fillOval(270, 97, 20, 20);
        g2d.fillOval(270, 182, 20, 20);
        g2d.fillOval(270, 255, 20, 20);
    }
    
    /* This method makes lines with an initial and final position,
       but it just work when the program is executed the first time,
       so I'm using another method that makes one line.
    */
    public void trazarLinea(char posi, int posf, Color c) {
        final int X1 = 27;
        final int Y2 = 275;
        int y1 = 0, y2 = 0;
        ((Graphics2D) g2d).setStroke(new BasicStroke(6));
        g2d.setColor(c);
        
        switch (posi) {
            case 'a':
                y1 = 30;
            break;
            case 'b':
                y1 = 109;
            break;
            case 'c':
                y1 = 194;
            break;
            case 'd':
                y1 = 264;
            break;
            default:
                y1 = 30;
        }

        switch (posf) {
            case 1:
                y2 = 30;
            break;
            case 2:
                y2 = 109;
            break;
            case 3:
                y2 = 194;
            break;
            case 4:
                y2 = 264;
            break;
            default:
                y2 = 30;
        }
        
        g2d.drawLine(X1, y1, Y2, y2);
    }
    
    /* The revalidate and repaint are here because I had them in the other Window class
       but that doesn't seem to work.
    */
    public void drawL() {
        final int X1 = 27;
        final int Y2 = 275;
        ((Graphics2D) g2d).setStroke(new BasicStroke(6));
        g2d.setColor(new Color(240, 20, 255));
        g2d.drawLine(X1, 30, Y2, 264);
        revalidate();
        repaint();
    }
}

在下面的 class 中,我有一个按钮,一旦我点击它,它就会画出那条线。 有些人告诉我重新验证并重新绘制 canvas 但这不起作用。

public class Window extends JFrame {
    
    private JTextField txt_ubicacion;
    private JTextField txt_color;
    private JPanel panel_1;
    private Canvas canva;

    Ventana() { 
        this.setPreferredSize(new Dimension(575, 330));
        this.setTitle("Relación de puntos - canvas");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        setResizable(true);
        panel_1 = new JPanel();
        getContentPane().add(panel_1, BorderLayout.NORTH);
        iniciarComponentes();
        this.pack();
        this.setLocationRelativeTo(null);
    }

    public void iniciarComponentes() {
    // I've cut some things here.

        canva = new Canvas();
        canva.setLayout(null);
        GroupLayout gl_panel_1 = new GroupLayout(panel_1);
        panel_1.setLayout(gl_panel_1);
        
        JButton boton_dibujar = new JButton("Dibujar");
        boton_dibujar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                canva.drawL();
            }
        });
        boton_dibujar.setFocusPainted(false);
        boton_dibujar.setBackground(new Color(0, 139, 139));
        boton_dibujar.setFont(new Font("JetBrains Mono Medium", Font.PLAIN, 11));
        boton_dibujar.setBounds(10, 207, 104, 23);
        panel_izquierdo.add(boton_dibujar);
    }
    
    @Override
    public void paint(Graphics g) {
        super.paint(g); // I read that those repaints should be made in the same class, but I 
                        // don't really know how could I do that here or somewhere.
    }
    
    public static void main(String[] args) {
        new Window();
    }
}

总结:当我点击一个按钮时,它应该在 JPanel 中出现一行,但没有发生,也没有显示任何错误。

  1. 不要打电话给你的 class Canvas。有一个 AWT class 具有该名称。
  2. 不要打电话给你的 class Window。有一个 AWT class 具有该名称。

Class 名称应该更具描述性。

所有绘画都必须在 paintComponent(...) 方法中完成。所以你需要:

  1. 删除“g2d”实例变量。您可以将 paintComponent() 方法的 Graphics 对象传递给您创建的任何方法来进行绘画。

  2. 创建一个实例变量,如“isButtonPressed”。然后你还需要一个像setButtonPressed(boolean)这样的方法,这样你就可以改变这个变量的属性。此方法将简单地设置实例变量的值,然后调用 repaint()。

然后在 paintComponent() 方法中添加如下逻辑:

if (isButtonPressed)
    trazarLinea(g);

在您的按钮的 ActionListener 中,您有如下代码:

canva.setButtonPressed(true);

阅读 Custom Painting 上的 Swing 教程。它演示了如何通过单击鼠标更改组件的状态。在您的情况下,您使用 JButton 执行此操作。