0

I'm new to Java programming. Can you help me with the layout of my first application (which is a simple calculator) please? Here's the code I wrote:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class InputPad extends JFrame {

    private JLabel statusLabel;
    private JTextArea expTextArea;

    InputPad() {
        prepareGUI();
    }

    private void prepareGUI(){
        JFrame mainFrame = new JFrame("My Calculator");
        mainFrame.setSize(450,450);
        mainFrame.setLayout(new GridLayout(3,2));
        mainFrame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent windowEvent){
                System.exit(0);
            }
        });

        JLabel headerLabel = new JLabel("Put your expression here:", JLabel.CENTER);
        statusLabel = new JLabel("",JLabel.CENTER);
        expTextArea = new JTextArea("1+(2^3*4)");

        //Digits Panel
        JPanel digitPanel = new JPanel();
        GroupLayout layoutDigits = new GroupLayout(digitPanel);
        digitPanel.setLayout(layoutDigits);
        layoutDigits.setAutoCreateGaps(true);
        layoutDigits.setAutoCreateContainerGaps(true);

        //Operators Panel
        JPanel operatorPanel = new JPanel();
        GroupLayout layoutOperators = new GroupLayout(operatorPanel);
        operatorPanel.setLayout(layoutOperators);
        layoutOperators.setAutoCreateGaps(true);
        layoutOperators.setAutoCreateContainerGaps(true);


        JButton[] numButtons= new JButton[10];

        int i;
        for (i=0;i<10;i++){
            numButtons[i] = new JButton(Integer.toString(i));
            numButtons[i].addActionListener(e -> {
//            TODO
            });
        }

        JButton bEquals = new JButton("=");
        bEquals.addActionListener(e -> {
//            TODO
        });

        JButton bPlus = new JButton("+");
        bPlus.addActionListener(e -> {
//            TODO
        });
        JButton bMinus = new JButton("-");
        bMinus.addActionListener(e -> {
//            TODO
        });
        JButton bMultiply = new JButton("*");
        bMultiply.addActionListener(e -> {
//            TODO
        });
        JButton bDivide = new JButton("/");
        bDivide.addActionListener(e -> {
//            TODO
        });
        JButton bLeftParenthesis = new JButton("(");
        bLeftParenthesis.addActionListener(e -> {
//            TODO
        });
        JButton bRightParenthesis = new JButton(")");
        bRightParenthesis.addActionListener(e -> {
//            TODO
        });
        JButton bPower = new JButton("^");
        bPower.addActionListener(e -> {
//            TODO
        });
        JButton bDel = new JButton("←");
        bDel.addActionListener(e -> {
//            TODO
        });


        layoutDigits.setHorizontalGroup(
                layoutDigits.createSequentialGroup()
                        .addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
                                .addComponent(numButtons[7])
                                .addComponent(numButtons[4])
                                .addComponent(numButtons[1])
                                .addComponent(numButtons[0]))
                        .addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
                                .addComponent(numButtons[8])
                                .addComponent(numButtons[5])
                                .addComponent(numButtons[2])
                                .addComponent(bEquals))
                        .addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.LEADING)
                                .addComponent(numButtons[9])
                                .addComponent(numButtons[6])
                                .addComponent(numButtons[3]))
        );
        layoutDigits.setVerticalGroup(
                layoutDigits.createSequentialGroup()
                        .addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(numButtons[7])
                                .addComponent(numButtons[8])
                                .addComponent(numButtons[9]))
                        .addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(numButtons[4])
                                .addComponent(numButtons[5])
                                .addComponent(numButtons[6]))
                        .addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(numButtons[1])
                                .addComponent(numButtons[2])
                                .addComponent(numButtons[3]))
                        .addGroup(layoutDigits.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(numButtons[0])
                                .addComponent(bEquals))
        );

        layoutOperators.setHorizontalGroup(
                layoutOperators.createSequentialGroup()
                        .addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.LEADING)
                                .addComponent(bPlus)
                                .addComponent(bMinus)
                                .addComponent(bLeftParenthesis)
                                .addComponent(bPower))
                        .addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.LEADING)
                                .addComponent(bMultiply)
                                .addComponent(bDivide)
                                .addComponent(bRightParenthesis)
                                .addComponent(bDel))
        );
        layoutOperators.setVerticalGroup(
                layoutOperators.createSequentialGroup()
                        .addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(bPlus)
                                .addComponent(bMultiply))
                        .addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(bMinus)
                                .addComponent(bDivide))
                        .addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(bLeftParenthesis)
                                .addComponent(bRightParenthesis))
                        .addGroup(layoutOperators.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(bPower)
                                .addComponent(bDel))
        );


        mainFrame.add(headerLabel);
        mainFrame.add(expTextArea);
        mainFrame.add(digitPanel);
        mainFrame.add(operatorPanel);
        mainFrame.add(statusLabel);
        mainFrame.setVisible(true);
    }

}

I tried the GridLayout for my JFrame, but I couldn't resize and of my JComponent except the main JFrame. Even I can't place two JPanels (side by side) in one cell of the GridLayout or expand a JLabel to two cells of the GridLayout.

This is what I got:

what I got

And here's what I want: what I want

DimaSan
  • 12,264
  • 11
  • 65
  • 75
Mehran
  • 13
  • 1
  • 3

2 Answers2

2

Let's start from the use of Layout Managers, from the link on the part of GridLayout

GridLayout simply makes a bunch of components equal in size and displays them in the requested number of rows and columns

So, this isn't what you want, but if you read the GridBagLayout part it says:

GridBagLayout is a sophisticated, flexible layout manager. It aligns components by placing them within a grid of cells, allowing components to span more than one cell. The rows in the grid can have different heights, and grid columns can have different widths.

We can combine both of them, along with a BoxLayout and you will get a similar output to what you're trying to achieve:

enter image description here


PLEASE NOTE:

Before posting the code, take note of the following tips:

  1. You're extending JFrame and at the same time you're creating a JFrame object, this is discouraged, remove one of them, in this case as you're using the object and this is the recommended thing to do, simply remove the extends JFrame from your class. If you really need to extend something, don't extend JFrame but a JPanel instead.

  2. Place your program inside the EDT, as I did in the main() method

  3. Don't use System.exit(0); instead call setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) as shown in the above code


And now the code

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class CalculatorExample {
    private JFrame frame;
    private JTextArea area;
    private JButton[][] digitsButtons, symbolsButtons;
    private String[][] digitsText = {{"7", "8", "9"}, {"4", "5", "6"}, {"1", "2", "3"}, {"0", "="}}; //Looks strange but this will make the button adding easier
    private String[][] symbolsText = {{"+", "*"}, {"-", "/"}, {"(", ")"}, {"^", "←"}};
    private JPanel buttonsPane, areaAndResultsPane, digitsPane, symbolsPane;
    private JLabel label;
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new CalculatorExample().createAndShowGui();
            }
        });
    }
    
    public void createAndShowGui() {
        frame = new JFrame("Calculator Example");
        area = new JTextArea();
        area.setRows(5);
        area.setColumns(20);
        label = new JLabel("Results go here");
        digitsButtons = new JButton [4][3];
        symbolsButtons= new JButton [4][2];
        areaAndResultsPane = new JPanel();
        areaAndResultsPane.setLayout(new BoxLayout(areaAndResultsPane, BoxLayout.PAGE_AXIS));
        
        buttonsPane = new JPanel();
        buttonsPane.setLayout(new GridLayout(1, 2, 10, 10));
        
        digitsPane = new JPanel();
        digitsPane.setLayout(new GridBagLayout());
        
        symbolsPane = new JPanel();
        symbolsPane.setLayout(new GridLayout(4, 2));
        
        GridBagConstraints c = new GridBagConstraints();
        
        for (int i = 0; i < digitsText.length; i++) {
            for (int j = 0; j < digitsText[i].length; j++) {
                digitsButtons[i][j] = new JButton(digitsText[i][j]);
            }
        }
        
        for (int i = 0; i < symbolsText.length; i++) {
            for (int j = 0; j < symbolsText[i].length; j++) {
                symbolsButtons[i][j] = new JButton(symbolsText[i][j]);
            }
        }
        
        areaAndResultsPane.add(area);
        areaAndResultsPane.add(label);
        
        boolean shouldBreak = false;
        for (int i = 0; i < digitsButtons.length; i++) {
            for (int j = 0; j < digitsButtons[i].length; j++) {
                c.gridx = j;
                c.gridy = i;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weightx = 0.5;
                if (i == 3) {
                    if (j == 1) {
                        c.gridwidth = 2; //This makes the "=" button larger
                        shouldBreak = true;
                    }
                }
                digitsPane.add(digitsButtons[i][j], c);
                if (shouldBreak) {
                    break;
                }
            }
        }
        
        for (int i = 0; i < symbolsButtons.length; i++) {
            for (int j = 0; j < symbolsButtons[i].length; j++) {
                symbolsPane.add(symbolsButtons[i][j]);
            }
        }
        
        frame.add(areaAndResultsPane, BorderLayout.NORTH);
        buttonsPane.add(digitsPane);
        buttonsPane.add(symbolsPane);
        
        frame.add(buttonsPane, BorderLayout.CENTER);
        
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

This was done nesting JPanels, each with a different layout, I hope it helps you to continue from here.

Community
  • 1
  • 1
Frakcool
  • 10,915
  • 9
  • 50
  • 89
0

According to the Oracle documentation :

Each component takes all the available space within its cell, and each cell is exactly the same size.

So sadly, you can't resize any components inside a GridLayout.

You could instead use a GridBagLayout. It is a little bit more complicated to understand but offers more features. I let you make some tests with the documentation to get in touch with it !

Kapcash
  • 6,377
  • 2
  • 18
  • 40