JFrame布局设置为空问题

时间:2014-05-19 03:11:25

标签: java swing layout-manager null-layout-manager

我正在尝试从我刚刚获得的一本书中学习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
}

1 个答案:

答案 0 :(得分:4)

不要使用null布局。像素完美布局是现代UI设计中的一种幻觉,您无法控制字体,DPI,渲染管道或其他因素,这些因素将改变组件在屏幕上呈现的方式。

Swing旨在与布局管理员合作以克服这些问题。如果你坚持忽略这些功能并违背API设计,那就要做好准备应对很多令人头疼的事情,永远不要过时的努力。

查看JavaDocs for pack ...

  

使此窗口的大小适合首选大小和布局   其子组件。窗口的最终宽度和高度是   如果任何一个尺寸小于,则自动放大   上一次调用setMinimumSize指定的最小大小   方法。

如果窗口和/或其所有者不可显示   然而,在计算之前,它们都可以显示   首选尺寸。窗口在其大小之后进行验证   计算

您将注意到pack依赖于布局管理器API来确定帧内容的首选可查看大小。通过将布局管理器设置为null,您已经阻止它能够确定此信息,所以基本上,它什么也没做。

如果您的图书告诉您使用null布局,请将其删除,这并不能教会您良好的习惯或做法。

请查看Laying Out Components Within a Container,了解有关布局管理器以及如何使用它们的更多详细信息

您遇到的其他问题:

在构建完UI之前调用setVisible(true);有时会阻止UI按照您的预期方式显示。你可以在框架上调用revalidate,但最后只需调用setVisible就更简单了。

setLocationRelativeTo使用的计算使用帧当前大小,但尚未设置。相反,你应该做类似的事情:

public CarPaymentCalc() {
    //...build UI here with appropriate layout managers...

    pack();
    setLocationRelativeTo(null);
    setVisible(true);
}

我也不鼓励你直接从JFrame这样的顶级容器扩展,除了你没有向框架本身添加任何功能这一事实,它会阻止你从以后重新使用IU开始。

最好先从JPanel开始,然后将其添加到您想要的任何内容中,但这只是我。