Kal*_*lec 5 java user-interface swing multiple-instances jframe
我刚刚学习java GUI的基础知识.我有这种奇怪的情况,我无法解释.
我有一个GUI类,我在其中构建一个简单的JFrame.如果我.setVisible(true) 在构造函数中使用一切正常,如果我在外面使用它,没有任何加载(窗口是可见的,但按钮和什么不是).
为什么会这样?
public class GUI extends JFrame {
private JTextField humanYears_TextField = new JTextField(3);
private JTextField dogYears_TextField = new JTextField(3);
private JButton convert_Button = new JButton("Convert");
private JLabel greeting = new JLabel ("Dog years to Human years!");
public GUI () {
JFrame window = new JFrame();
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(this.greeting);
content.add(new JLabel("Dog Years: "));
content.add(this.dogYears_TextField);
content.add(this.convert_Button);
content.add(new JLabel("Human Years: "));
content.add(this.humanYears_TextField);
window.setContentPane(content);
pack(); // aplica contentPane-ul
window.setLocationRelativeTo(null);
window.setTitle("Dog Year Converter");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true); // IF IT'S HERE IT WORKS
}
}
public static void main(String[] args) {
GUI dogYears = new GUI();
//dogYears.setVisible(true); // IF IT'S HERE
//NOTHING EXCEPT THE WINDOW LOADS
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?
在这个例子中它并不重要,但是如果我只想点击一个按钮或什么东西我想让窗口可见呢?
1)您可以在类上创建JFrame 第一个第一个实例,JFrame第二个来自JFrame window=...你不是去上调用setVisible(..)的window,并在你的主,你尝试调用setVisible(...)你的dogYears.
解
您应该只JFrame为每个Swing GUI 创建一个.摆脱extends JFrame(以及随之而来的代码),因为它不是JFrame在Swing中扩展的好习惯.因此,当然你无法调用setVisible(true)你的构造函数,无论是在构造函数中创建GUI之后调用它还是setVisible在GUI类中创建一个方法,它将是你JFrame的setVisble(boolean b)方法的包装器.
其他建议
始终Event Dispatch Thread在via SwingUtilitites.invokeLater(Runnable r)块中创建Swing组件.阅读Swing中的Concurrency.
请记住在设置JFrame可见之前和添加组件之后调用pack .
setLocationRelativeTo(..)应该来pack().
JFrame.DISPOSE_ON_CLOSE除非使用Timers,否则最好使用.
也没有必要setContentPane简单地调用add(..)的JFrame实例.
这是您的代码与上述修复:

import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class GUI {
private JTextField humanYears_TextField = new JTextField(3);
private JTextField dogYears_TextField = new JTextField(3);
private JButton convert_Button = new JButton("Convert");
private JLabel greeting = new JLabel("Dog years to Human years!");
private JFrame window = new JFrame();
private JPanel content = new JPanel();
public GUI() {
content.setLayout(new FlowLayout());
content.add(this.greeting);
content.add(new JLabel("Dog Years: "));
content.add(this.dogYears_TextField);
content.add(this.convert_Button);
content.add(new JLabel("Human Years: "));
content.add(this.humanYears_TextField);
window.add(content);
window.setTitle("Dog Year Converter");
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.pack();
window.setLocationRelativeTo(null);
//window.setVisible(true); //works here now
}
//our wrapper method so we can change visibility of our frame from outside the class
void setVisible(boolean visible) {
window.setVisible(visible);
}
public static void main(String[] args) {
//Create Swing components on EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GUI dogYears = new GUI();
dogYears.setVisible(true);//works here too
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
你有两个JFrame,GUI类本身和内部变量"窗口".只使用一个.
确保GUI不会扩展JFrame(不需要这样做),并为类提供一个公共void setVisible(boolean)方法,将窗口设置为可见.
public class GUI {
private JTextField humanYears_TextField = new JTextField(3);
private JTextField dogYears_TextField = new JTextField(3);
private JButton convert_Button = new JButton("Convert");
private JLabel greeting = new JLabel ("Dog years to Human years!");
private JFrame window = new JFrame();
public GUI () {
JPanel content = new JPanel();
content.setLayout(new FlowLayout());
content.add(this.greeting);
content.add(new JLabel("Dog Years: "));
content.add(this.dogYears_TextField);
content.add(this.convert_Button);
content.add(new JLabel("Human Years: "));
content.add(this.humanYears_TextField);
window.setContentPane(content);
pack(); // aplica contentPane-ul
window.setLocationRelativeTo(null);
window.setTitle("Dog Year Converter");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// window.setVisible(true); // IF IT'S HERE IT WORKS
}
public void setVisible(boolean visible) {
window.setVisible(visible);
}
}
Run Code Online (Sandbox Code Playgroud)