Макет JFrame установлен на нулевые проблемы

Я пытаюсь изучить 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 ответ

Не использовать null макеты. Макеты Pixel Perfect - это иллюзия в современном дизайне пользовательского интерфейса, у вас нет контроля над шрифтами, DPI, конвейерами рендеринга или другими факторами, которые изменят способ визуализации компонентов на экране.

Swing был разработан для работы с менеджерами верстки для преодоления этих проблем. Если вы настаиваете на игнорировании этих функций и работаете против дизайна API, будьте готовы к многочисленным головным болям и никогда не прекращайте тяжелую работу.

Глядя на JavaDocs дляpack...

Заставляет размер этого окна соответствовать предпочтительному размеру и расположению его подкомпонентов. Результирующая ширина и высота окна автоматически увеличиваются, если любое из измерений меньше минимального размера, указанного в предыдущем вызове метода setMinimumSize.

Если окно и / или его владелец еще не отображаются, оба они становятся отображаемыми до вычисления предпочтительного размера. Окно проверяется после расчета его размера.

Вы заметите, что pack полагается на API менеджера макета для определения предпочтительного видимого размера содержимого фреймов. Установив менеджер макета в nullВы помешали ей определить эту информацию, поэтому, по сути, ничего не сделано.

Если ваша книга говорит вам использовать null макеты, избавьтесь от этого, это не учит вас хорошим привычкам или практикам.

Посмотрите на Компоновку Компонентов Внутри Контейнера для более подробной информации о менеджерах компоновки и как их использовать

Другие проблемы, которые у вас возникают:

призвание setVisible(true); перед тем, как вы закончите создание пользовательского интерфейса, он может иногда препятствовать тому, чтобы пользовательский интерфейс отображался так, как вы хотели. Вы могли бы позвонить revalidate на раме, но проще просто позвонить setVisible прошлой.

Расчет используется setLocationRelativeTo использует текущий размер фрейма, но это еще не установлено. Вместо этого вы должны сделать что-то вроде:

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

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

Я также не рекомендовал бы вам простираться прямо из контейнеров верхнего уровня, таких как JFrameкроме того факта, что вы не добавляете какие-либо функциональные возможности в фрейм как таковые, это не позволяет вам повторно использовать IU позже.

Лучше начать с JPanel и добавьте это к тому, что вы хотите, но это только я.

Другие вопросы по тегам