我在通过JButton
画一条简单的线到Frame
时遇到了一些问题。仅当我使用JButton
执行此操作时才会出现此问题。如果我直接使用Frame
内的JPanel
,一切都很好。
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();
}
}
还有paintComponents()
JPanel
:
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);
}
}
许多问题立即出现在我面前:
- 你应该使用
paintComponent
,而不是paintComponents
(注意最后的s
),你在油漆链中的地位太高了。也不需要public
任何一种方法,类外的人都不应该调用它。 -
Pane
不提供大小调整提示,因此它的"默认"大小将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 是懒惰的。 它不会运行布局/绘画通道,直到它必须或您要求它运行。 这是一种优化,因为您可以在需要执行布局通道之前添加许多组件。
若要请求布局阶段,请在已更新的顶级容器上调用 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
现在出现