我正在学习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)
也不起作用。
答案 0 :(得分:4)
我在您的代码中看到了一些问题:
button.setBounds(100, 100, 130, 35);
该行将被忽略,您不应该手动确定组件的位置。请参阅Null layout is evil和Why is it frowned upon to use a null layout in swing?,即使您没有使用空布局,也可以解释为什么您不应该手动确定组件的位置。
您已使用main
方法运行程序中的所有内容,以后很难维护。
在您将所有元素添加到其中之前,您正在致电frame.setVisible(true)
,这会导致您出现随机问题。
您未在Event Dispatch Thread (EDT)上运行程序,可以使用以下代码启动程序来解决此问题,该代码将其置于EDT中。它被推荐为Swing不是线程安全的。
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//Your constructor here
}
});
}
您已使用setSize(...)
设置JFrame
的尺寸,而是调用frame.pack()
并覆盖getPreferredSize()
的{{1}}方法}。
完成上述所有操作后,您需要在JPanel
上致电revalidate()
和repaint()
,以便您的计划描绘其新状态。
此程序遵循以上所有建议并生成以下输出(在点击之前和单击按钮3次之后),我的目的是不使图像如此之大,使GUI缩短(200 x 200而不是400 x 400)
ActionListener
我是否在像JPanel,JButton这样的其他组件之前写这个...或者我是否在代码末尾写了这个?
frame.setVisible(真); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
有什么区别?
尽管我在建议中回答了这个问题,不同之处在于,如果在将所有元素添加到框架之前调用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);
}
}
,那么您会发现自己遇到一些随机问题,其中组件并非全部直到你将鼠标放在它们上面(或它们应该在哪里)才可见。 setVisible
和frame.pack()
应该是您的计划中要调用的最后一个,setVisible
可以在开头或结尾,它不会影响,但我更喜欢最后也有它。
button.setBounds(100,100,130,35);也不起作用。
嗯,那是因为你使用了layout manager(这是正确的GUI方式)而不是frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
(你是不管怎样都不应该使用)(参见第1点)。
frame.setSize();有什么区别?和frame.setpack()?
如果您阅读了null-layout
的{{3}}:
使此窗口的大小适合其子组件的首选大小和布局。如果任一维度小于上一次调用setMinimumSize方法所指定的最小大小,则会自动放大窗口的最终宽度和高度。
因此,它会计算pack()
的最小尺寸,其中所有元素都是可见的,并且是首选尺寸,而JFrame
只会设置窗口大小,但是如果放置{{1}例如,这将减少窗口大小,因此,这就是为什么你应该覆盖容器的setSize
方法,所以它会计算它的首选大小,包括{的宽度{1}}或其他一些可以修改其大小的元素。请参阅docs(普遍的共识是是)
答案 1 :(得分:0)
当您向组件动态添加组件时,需要重新创建它。
这样做
panel.revalidate();
之后
panel.add(label);