1

I am trying to learn GUI from a book I just got, but I am having tons of problems (my code is attached). When I launch this app, All I get is a minimum window that need to expand every time, and the only thing it shows is one of my radio buttons. I am obviously doing something wrong here. Can somebody please advise me?


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
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 3
    *"I am trying to learn GUI from a book I just got"* As an aside, if that book is using null layouts, it is crap. Get rid of it before it teaches you more bad habits. – Andrew Thompson May 19 '14 at 03:28

1 Answers1

4

Don't use null layouts. Pixel perfect layouts are an illusion in modern UI design, you have no control over fonts, DPI, rendering pipelines or other factors that will change the way that you components will be rendered on the screen.

Swing was designed to work with layout managers to overcome these issues. If you insist on ignoring these features and work against the API design, be prepared for a lot of headaches and never ending hard work.

By looking at JavaDocs for pack...

Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.

If the window and/or its owner are not displayable yet, both of them are made displayable before calculating the preferred size. The Window is validated after its size is being calculated.

You will note that pack relies on the layout manager API to determine the preferred viewable size of the frames content. By setting the layout manager to null, you've prevented it from been able to determine this information, so basically, it's done nothing.

If your book is telling you to use null layouts, get rid of it, it's not teaching you good habits or practices.

Take a look at Laying Out Components Within a Container for more details about layout managers and how to use them

Other problems you are having:

Calling setVisible(true); before you've finished building the UI can sometimes prevent the UI from appearing the way you intended it to. You could call revalidate on the frame, but it's simpler to just call setVisible last.

The calculation used by setLocationRelativeTo uses the frames current size, but this hasn't been set yet. Instead, you should do something like:

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

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

I would also discourage you from extending directly from top level containers like JFrame, apart from the fact that you're not adding any functionality to the frame per se, it prevents you from re-using the IU later.

Better to start with a JPanel and add this to whatever you want, but that's just me.

halfer
  • 19,824
  • 17
  • 99
  • 186
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Can you please explain your comment about extending directly from top level container like JFrame? Or at least give me a url so I can read about this? – Just As I Am May 21 '14 at 18:44
  • Generally, we discourage extending from JFrame for two basic reasons, 1- From a OO design principle, you're not actually adding any, reusable, functionary to the frame and 2- From a re-usable point of view, you're restricting yourself. You won't be able to use the UI in other programs, such as been able to add it to other components or top level containers like JApplet, for example. It also complicates custom painting – MadProgrammer May 21 '14 at 20:23
  • @JustAsIAm think of jpanel and the various containers as construction paper that stretches or shrinks to fit the components put onto it, organized by the layout manager. You can put as many pieces of construction paper in any layout you dream up. Sometimes it is easier to have one master jframe with several attached jpanels side by side or below each other to make layouts more manageable. Each jpanel has two or three components attached. There should never be a need to extend JFrame. – D-Klotz Aug 02 '18 at 13:48