按下按钮时画线摆动

Draw Line when Button is pressed Swing

我在通过 JButton 绘制到 Frame 的简单直线时遇到一些问题。 仅当我使用 JButton 执行此操作时才会出现问题。 如果我直接用[=12=里面的JPanel,就OK了。

JFrame:

import javax.swing.*;
import java.awt.*;

public class Fenetre extends JFrame {

    public Fenetre(){
        super("Test");
        init();
        pack();
        setSize(200,200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private void init() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());

        JButton button = new JButton("Draw line");

        button.addActionListener((e)->{
            Pane s = new Pane();
            panel.add(s);
            s.repaint();
        });

        panel.setBackground(new Color(149,222,205));

        add(button,BorderLayout.SOUTH);
        add(panel,BorderLayout.CENTER);
    }

    public static void main(String[] args){
        new Fenetre();
    }

}

JPanelpaintComponents():

import javax.swing.*;
import java.awt.*;

public class Pane extends JPanel {

    public void paintComponents(Graphics g){
        super.paintComponents(g);
        g.drawLine(0,20,100,20);
    }
}

许多问题立即向我袭来:

  1. 你应该使用 paintComponent,而不是 paintComponents(注意最后的 s),你在油漆链中的位置太高了。任何一种方法都不需要 public,class 之外的任何人都不应该调用它。
  2. Pane 不提供尺码提示,因此 "default" 尺码将为 0x0

相反,它应该看起来更像...

public class Pane extends JPanel {

    public Dimension getPreferredSize() {
        return new Dimension(100, 40);
    }

    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawLine(0,20,100,20);
    }
}

添加组件时,Swing 是懒惰的。它不会 运行 一个 layout/paint 通过,除非它必须或你要求它通过。这是一个优化,因为您可以在需要执行布局过程之前添加许多组件。

要请求布局传递,请在已更新的顶级容器上调用 revalidate。作为一般经验法则,如果您调用 revalidate,您还应该调用 repaint 来请求新的绘制过程。

public class Fenetre extends JFrame {

    public Fenetre(){
        super("Test");
        init();
        //pack();
        setSize(200,200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private void init() {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());

        JButton button = new JButton("Draw line");

        button.addActionListener((e)->{
            Pane s = new Pane();
            panel.add(s);
            panel.revalidate();
            panel.repaint();
            //s.repaint();
        });

        panel.setBackground(new Color(149,222,205));

        add(button,BorderLayout.SOUTH);
        add(panel,BorderLayout.CENTER);
    }

    public static void main(String[] args){
        new Fenetre();
    }

}

那至少应该让你的 panel 现在出现