[英]Java - My action event doesn't work
我正在学习Java和Swing,但是我的JButton不起作用。
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Programma {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e){
e.printStackTrace();
}
JFrame frame = new JFrame("DIG");
JPanel panel = new JPanel();
JButton button = new JButton("Click Me");
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.setBounds(100, 100, 130, 35);
panel.add(button);
frame.add(panel);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JLabel label = new JLabel("Hello World");
label.setVisible(true);
panel.add(label);
}
});
}
}
框架和按钮是可见的,当我单击框架和按钮时,它不会出现标签。 我怎样才能解决这个问题?
我应该在其他组件(例如JPanel,JButton等)之前编写此代码,还是在代码末尾编写以下代码:
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
有什么区别 ?
顺便说一句, button.setBounds(100, 100, 130, 35)
也不起作用。
我在您的代码中看到了一些问题:
button.setBounds(100, 100, 130, 35);
该行将被忽略,您不应该手动确定组件的位置。 请参见Null布局是邪恶的 , 为什么不赞成在swing中使用null布局? 尽管您没有使用null布局,但解释了为什么不应该手动确定组件的位置。
您正在使用main
方法运行程序中的所有内容,以后将很难维护。
在将所有元素添加到frame.setVisible(true)
之前,您将调用它,这将导致随机问题。
您没有在事件调度线程(EDT)上运行程序,可以通过以下代码启动程序来解决此问题,并将其放在EDT中。 推荐使用Swing并不是线程安全的。
public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { //Your constructor here } }); }
您可以使用setSize(...)
设置JFrame
的大小,而不是调用frame.pack()
并重写JPanel
的getPreferredSize()
方法。
说完上述所有内容后,您需要在ActionListener
上调用revalidate()
和repaint()
,以便您的程序绘制其新状态。
该程序遵循上述所有建议,并产生以下输出(单击之前和单击按钮3次之后),我故意使图像不变得如此大,使GUI较短(200 x 200而不是400 x 400)
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Programma {
private JFrame frame;
private JPanel panel;
private JButton button;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Programma().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("DIG");
panel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
};
button = new JButton("Click Me");
panel.add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JLabel label = new JLabel("Hello World");
panel.add(label);
panel.revalidate();
panel.repaint();
}
});
frame.add(panel);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
我是在JPanel,JButton等其他组件之前编写此代码还是在代码末尾编写此代码?
frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
有什么区别 ?
尽管我在建议中回答了这个问题,但不同之处在于,如果在将所有元素添加到框架之前调用setVisible
,则会遇到一些随机问题,在这些问题上,除非您将鼠标移到组件上,否则所有组件都不可见(或应该在哪里)。 frame.pack()
和setVisible
应该是程序中要调用的最后一个,并且frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
可以在开始或结束时使用,但不受影响,但我也希望在结束时使用。
button.setBounds(100,100,130,35); 也行不通。
好吧,这是因为您使用的是布局管理器 (这是执行GUI的正确方法),而不是使用null-layout
(无论如何您都不应使用)(请参阅第1点)。
frame.setSize();有什么区别? 和frame.setpack()?
如果您阅读pack()
的文档 :
使此窗口的大小适合其子组件的首选大小和布局。 如果任意一个尺寸小于上一次调用setMinimumSize方法指定的最小尺寸,则窗口的宽度和高度将自动放大。
因此,它将为您的JFrame
计算最小尺寸,在该尺寸下所有元素都是可见的且处于其首选尺寸,而setSize
仅设置窗口尺寸,但是例如,如果在其中放置JScrollBar
,则会减小窗口尺寸,因为因此,您应该重写容器的getPreferredSize(...)
方法,以便它将计算其首选大小,包括JScrollBar
的宽度或其他可以修改其大小的元素。 请参阅我应该避免在Swing中使用setPreferred | Maximum | MinimumSize吗? (一般共识是 )
将组件动态添加到面板时,需要重新添加面板。
做这个
panel.revalidate();
后
panel.add(label);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.