按下按钮时画线摆动
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();
}
}
和 JPanel
与 paintComponents()
:
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
,class 之外的任何人都不应该调用它。
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
现在出现
我在通过 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();
}
}
和 JPanel
与 paintComponents()
:
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
,class 之外的任何人都不应该调用它。 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
现在出现