【问题标题】:JFrame Layout set to null issuesJFrame Layout 设置为空问题
【发布时间】:2014-05-19 03:11:25
【问题描述】:

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

【问题讨论】:

  • “我正在尝试从我刚拿到的一本书中学习 GUI” 顺便说一句,如果那本书使用空布局,那就太垃圾了。在它教你更多坏习惯之前摆脱它。

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


【解决方案1】:

不要使用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 开始,然后将其添加到您想要的任何内容中,但这只是我。

【讨论】:

  • 您能否解释一下您对直接从 JFrame 等顶级容器扩展的评论?或者至少给我一个网址,以便我阅读?
  • 一般来说,我们不鼓励从 JFrame 扩展,有两个基本原因,1- 从 OO 设计原则,您实际上并没有向框架添加任何可重用的功能;2- 从可重用观点,你是在限制自己。您将无法在其他程序中使用 UI,例如能够将其添加到其他组件或 JApplet 等顶级容器中。它还使自定义绘画复杂化
  • @JustAsIAm 将 jpanel 和各种容器视为结构纸,可以拉伸或收缩以适应放置在其上的组件,由布局管理器组织。您可以在您梦想的任何布局中放置尽可能多的建筑用纸。有时更容易让一个主 jframe 与几个附加的 jpanel 并排或彼此下方,以使布局更易于管理。每个 jpanel 都附加了两个或三个组件。永远不需要扩展 JFrame。
猜你喜欢
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 2011-08-06
相关资源
最近更新 更多