我正试图从我刚得到的一本书中学习GUI,但我有很多问题(我的代码是附加的)。当我启动这个应用程序时,我得到的只是一个每次都需要展开的最小窗口,它唯一显示的是我的一个单选按钮。我显然做错了什么。有人能给我点建议吗?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CarPayment
{
public static void main(String[] args)
{
new CarPaymentCalc();
} // main
} // CarPayment
class CarPaymentCalc extends JFrame
{
private JLabel labelTitle, labelInterest, labelLoan;
private JTextField tfLoan, tfInterest, tfAnswer;
private ButtonGroup bgSelect;
private JRadioButton rbPmts36, rbPmts48, rbPmts60;
private JButton bClear;
public CarPaymentCalc()
{
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null); // Centers the window
setTitle("Car Payments Calculator");
// Labels
labelTitle = new JLabel("Calculate My Car Payment");
labelTitle.setVerticalAlignment(JLabel.TOP);
add(labelTitle, JLabel.CENTER);
labelLoan = new JLabel("Loan Amount");
labelLoan.setLocation(0, 10);
add(labelLoan);
labelInterest = new JLabel("Interest");
labelInterest.setLocation(0, 45);
add(labelInterest);
// Input Fields
tfLoan = new JTextField(20);
tfLoan.setLocation(0, 25);
add(tfLoan);
tfInterest = new JTextField(5);
tfInterest.setLocation(0, 60);
add(tfInterest);
JTextArea tfAnswer = new JTextArea(50,10);
tfAnswer.setLocation(0, 110);
add(tfAnswer);
// Radio buttons
bgSelect = new ButtonGroup();
rbPmts36 = new JRadioButton();
rbPmts36.setText("36 Payments");
rbPmts36.setLocation(0, 80);
bgSelect.add(rbPmts36);
add(rbPmts36);
bgSelect.add(rbPmts48);
rbPmts48.setText("48 Payments");
rbPmts48.setLocation(150, 80);
rbPmts48 = new JRadioButton();
add(rbPmts48);
bgSelect.add(rbPmts60);
rbPmts60.setText("60 Payments");
rbPmts60.setLocation(300, 80);
rbPmts60 = new JRadioButton();
add(rbPmts60);
setLayout(null);
pack();
} // CarPaymentCalc
}
不要使用null
布局。在现代UI设计中,像素完美的布局是一种错觉,你无法控制字体、DPI、渲染管道或其他会改变组件在屏幕上呈现方式的因素。
Swing被设计成与布局管理器一起工作来克服这些问题。如果你坚持忽略这些特性,违背API的设计,那么你要准备好面对很多令人头疼的事情,并且要做没完没了的艰苦工作。
通过查看JavaDocs for pack
…
使此窗口的大小适合首选大小和布局它的子成分。窗口的宽度和高度为中的任何一个维度小于时自动放大由先前调用setMinimumSize指定的最小大小方法。
如果窗口和/或其所有者不可显示然而,在计算前,它们都可以显示首选大小。窗口的大小被验证后计算。
你会注意到pack
依赖于布局管理器API来确定帧内容的首选可见大小。通过将布局管理器设置为null
,您已经阻止了它能够确定此信息,因此基本上,它什么也没做。
如果你的书告诉你使用null
布局,扔掉它,它没有教你好的习惯或实践。
关于布局管理器和如何使用它们的更多细节,请参阅在容器内布局组件。
您遇到的其他问题:
在你完成UI的构建之前调用setVisible(true);
有时会阻止UI以你想要的方式出现。你可以在帧上调用revalidate
,但是最后调用setVisible
更简单。
setLocationRelativeTo
使用的计算使用帧的当前大小,但这还没有设置。相反,您应该这样做:
public CarPaymentCalc() {
//...build UI here with appropriate layout managers...
pack();
setLocationRelativeTo(null);
setVisible(true);
}
我也不鼓励您直接从像JFrame
这样的顶级容器扩展,除了您没有向框架本身添加任何功能之外,它还会阻止您以后重用IU。
最好从JPanel
开始,然后添加到任何你想要的,但这只是我。