JButton 在 JFrame 中响应,但在 JPanel 中不响应
JButton responds in JFrame, but not in a JPanel
我是 java 的新手,我正在尝试了解动作侦听器和按钮的工作原理。我发现,如果我将 JButton 直接放入我的 JFrame 对象中,我可以获得一个有效的 JButton。但是,如果我将它放在 JFrame within 的 JPanel 中,它不会响应。这是为什么?
Main.java
public class Main {
private static Frame f = new Frame();
public static void main(String[] args) {}
}
Frame.java
public class Frame extends JFrame {
private final int WIDTH = 640, HEIGHT = 480;
private Panel p = new Panel();
Frame() {
super("Java Program");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(WIDTH, HEIGHT);
this.setLayout(null);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
p.paintComponent(g);
}
}
Panel.java
public class Panel extends JPanel {
JButton b = new JButton("Button");
Panel() {
b.setBounds(0, 0, 200, 100);
add(b);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
b.setText("Pressed");
}
});
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
b.paint(g);
}
}
我不是 Swing 专家,所以我无法真正解释为什么它不起作用。似乎在您的按钮上画了一个无响应的按钮。我稍微调整了一下,这里有一些修改以使其正常工作:
- 将面板添加到框架:
add(p);
- 删除
this.setLayout(null);
行,好像把框架搞乱了
- 要设置框架的大小,请使用 setPreferredSize:
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
- 您还需要在 Frame 构造函数的末尾调用
pack()
。
并且您需要从 Panel.paintComponent()
中删除 b.paint(g)
,这似乎是绘制 "unresponsive" 按钮的原因,(请参见答案).
可选地,您可以从框架中删除 paint(),它只做 JFrame 的一个
这是修改后的工作版本:
class Frame extends JFrame {
private final int WIDTH = 640, HEIGHT = 480;
private Panel p = new Panel();
Frame() {
super("Java Program");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
this.setLocationRelativeTo(null);
this.setVisible(true);
// add the panel to the frame
add(p);
pack();
}
}
class Panel extends JPanel {
JButton b = new JButton("Button");
Panel() {
b.setBounds(0, 0, 200, 100);
add(b);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
b.setText("Pressed");
}
});
}
// You can also get rid of this method,
// I just leave it here to show that I removed the b.paint(g) line
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
如果您在 Panel.paintComponent()
中保留 b.paint(g)
,这就是相同代码显示的内容,您可以看到有 2 个按钮,角落里的那个不起作用。
我是 java 的新手,我正在尝试了解动作侦听器和按钮的工作原理。我发现,如果我将 JButton 直接放入我的 JFrame 对象中,我可以获得一个有效的 JButton。但是,如果我将它放在 JFrame within 的 JPanel 中,它不会响应。这是为什么?
Main.java
public class Main {
private static Frame f = new Frame();
public static void main(String[] args) {}
}
Frame.java
public class Frame extends JFrame {
private final int WIDTH = 640, HEIGHT = 480;
private Panel p = new Panel();
Frame() {
super("Java Program");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(WIDTH, HEIGHT);
this.setLayout(null);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
p.paintComponent(g);
}
}
Panel.java
public class Panel extends JPanel {
JButton b = new JButton("Button");
Panel() {
b.setBounds(0, 0, 200, 100);
add(b);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
b.setText("Pressed");
}
});
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
b.paint(g);
}
}
我不是 Swing 专家,所以我无法真正解释为什么它不起作用。似乎在您的按钮上画了一个无响应的按钮。我稍微调整了一下,这里有一些修改以使其正常工作:
- 将面板添加到框架:
add(p);
- 删除
this.setLayout(null);
行,好像把框架搞乱了 - 要设置框架的大小,请使用 setPreferredSize:
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
- 您还需要在 Frame 构造函数的末尾调用
pack()
。 并且您需要从
Panel.paintComponent()
中删除b.paint(g)
,这似乎是绘制 "unresponsive" 按钮的原因,(请参见答案).可选地,您可以从框架中删除 paint(),它只做 JFrame 的一个
这是修改后的工作版本:
class Frame extends JFrame {
private final int WIDTH = 640, HEIGHT = 480;
private Panel p = new Panel();
Frame() {
super("Java Program");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
this.setLocationRelativeTo(null);
this.setVisible(true);
// add the panel to the frame
add(p);
pack();
}
}
class Panel extends JPanel {
JButton b = new JButton("Button");
Panel() {
b.setBounds(0, 0, 200, 100);
add(b);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
b.setText("Pressed");
}
});
}
// You can also get rid of this method,
// I just leave it here to show that I removed the b.paint(g) line
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
如果您在 Panel.paintComponent()
中保留 b.paint(g)
,这就是相同代码显示的内容,您可以看到有 2 个按钮,角落里的那个不起作用。