I am going to make a calculator and I am having some Issues arranging the buttons. You should be able to see the layout when you run the code. Some clarification though there will be a blank spot under the "3" for a "+/-" button (switches between positive and negative). Here is my code:

import javax.swing.*;

import java.awt.event.*;
import java.awt.*;

public class Calc implements ActionListener{

	JTextField disp;
	double total;
	String number;
	
	
	public Calc (){
		JFrame f = new JFrame ("Calculator"); f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		JPanel pane = new JPanel (new GridBagLayout ());
		GridBagConstraints c = new GridBagConstraints ();
		disp = new JTextField (25);disp.setText ("0");
		c.gridx = 1;
		c.gridy = 1;
		c.gridheight = 1;
		c.gridwidth = 17;
		pane.add (disp,c);
		
			JButton btn0 = new JButton ("0"); btn0.addActionListener(this); btn0.setActionCommand ("0");
			c.gridheight = 4;
			c.gridwidth = 8;
			c.gridx = 1;
			c.gridy = 17;
			pane.add (btn0,c);
			JButton btn1 = new JButton ("1"); btn1.addActionListener(this); btn1.setActionCommand ("1");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 1;
			c.gridy = 13;
			pane.add (btn1, c);
			JButton btn2 = new JButton ("2"); btn2.addActionListener(this); btn2.setActionCommand ("2");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 5;
			c.gridy = 13;
			pane.add (btn2,c);
			JButton btn3 = new JButton ("3"); btn3.addActionListener(this); btn3.setActionCommand ("3");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 9;
			c.gridy = 13;
			pane.add (btn3,c);
			JButton btn4 = new JButton ("4"); btn4.addActionListener(this); btn4.setActionCommand ("4");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 1;
			c.gridy = 9;
			pane.add (btn4,c);
			JButton btn5 = new JButton ("5"); btn5.addActionListener(this); btn5.setActionCommand ("5");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 5;
			c.gridy = 9;
			pane.add (btn5,c);
			JButton btn6 = new JButton ("6"); btn6.addActionListener(this); btn6.setActionCommand ("6");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 9;
			c.gridy = 9;
			pane.add (btn6,c);
			JButton btn7 = new JButton ("7"); btn7.addActionListener(this); btn7.setActionCommand ("7");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 1;
			c.gridy = 5;
			pane.add (btn7,c);
			JButton btn8 = new JButton ("8"); btn8.addActionListener(this); btn8.setActionCommand ("8");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 5;
			c.gridy = 5;
			pane.add (btn8,c);
			JButton btn9 = new JButton ("9"); btn9.addActionListener(this); btn9.setActionCommand ("9");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 9;
			c.gridy = 5;
			pane.add (btn9,c);
			JButton btnPlus = new JButton ("+"); btnPlus.addActionListener(this); btnPlus.setActionCommand ("+");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 13;
			c.gridy = 13;
			pane.add (btnPlus,c);
			JButton btnMin = new JButton ("-"); btnMin.addActionListener(this); btnMin.setActionCommand ("-");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 17;
			c.gridy = 13;
			pane.add (btnMin,c);
			JButton btnMult = new JButton ("x"); btnMult.addActionListener(this); btnMult.setActionCommand ("*");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 13;
			c.gridy = 9;
			pane.add (btnMult,c);
			JButton btnDiv = new JButton ("/"); btnDiv.addActionListener(this); btnDiv.setActionCommand ("/");
			c.gridheight = 4;
			c.gridwidth = 4;
			c.gridx = 17;
			c.gridy = 9;
			pane.add (btnDiv,c);
			JButton btnEq = new JButton ("="); btnEq.addActionListener(this); btnEq.setActionCommand ("=");
			c.gridheight = 4;
			c.gridwidth = 8;
			c.gridx = 13;
			c.gridy = 17;
			pane.add (btnEq,c);
			JButton btnClr = new JButton ("CE"); btnClr.addActionListener(this); btnClr.setActionCommand ("clear");
			c.gridheight = 4;
			c.gridwidth = 8;
			c.gridx = 13;
			c.gridy = 5;
			pane.add (btnClr,c);
		
		
		
		f.add (pane);
		f.setSize (300,350);
		f.setVisible (true);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Calc c = new Calc ();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if (e.getActionCommand().equals("1")){
			System.out.println ("1 Pressed");
			
		}
		
		
		
	}
	
}

Please tell me how to fix this issue.

Thanks for any help.

Recommended Answers

All 20 Replies

I am having some Issues arranging the buttons

Can you describe the issues?

The buttons aren't quite as they should be. The buttons that are supposed to be 2 buttons wide (CE, 0, =) are not 2 wide, they are in the center and they are only 1 button wide. Also no matter what I change the button sizes to they stay the same size. Also the "/", "-", "=" and "CE" are not beside the rest of the buttons when I expand the frame.

Here is an image:

[IMG]http://img535.imageshack.us/img535/5954/calcerror.jpg[/IMG]

Why are you using widths/heights of 4 and 8, instead of simply 1 and 2?

> Also no matter what I change the button sizes to they stay the same size.
You can call setPreferredWidth() on your buttons to specify their preferred size to the layout manager.

btnMult.setPreferredWidth (4); did not work. it game me this error

The method setPreferredWidth() is undefined for the type JButton

Sorry, the method is actually setPreferredSize(Dimension)

Dimension is in pixels, then how would I get it so the buttons are still arranged according to the gridBagLayout?

Now my buttons are on top of each other.

I think you are confusing grid cells and pixel dimensions.

You only need to use setPreferredSize if you want to change the default size in pixels for a component. That is unrelated to how many grid cells that a component may occupy.

If your component are now on top of one another, then you have not placed them into the proper grid cells with 'gridx' and 'gridy'. You were pretty close with the layout posted above, but as I mentioned, you don't need to use multiples of 4 to specify the grid cells. 0,1,2, etc will suffice.

They are just cell locations in a grid of hypothetical squares - not actual heights/widths.

If you want the components to fill space horizontally or vertically, you need to set that with the 'fill', 'weightx' and 'weighty' properties.

'anchor' will let you set which side components are "stuck to".

The buttons that separate themselves from the group are affected by the text field. How would I fix this?

Edit:
Nvm the maximum number was 21 so I had to make my text field 21.

Now I just need to get the buttons wide enough.

Consider that components don't fill their grid cells unless you specify that in the constraints. The default is no fill.

You also need to specify how "extra" space gets divided up horizontally and vertically with the weightx and weighty properties. The default is 0, so if you want a component to take some of that extra space you need to set a value for it 0 < weight <= 1.0 GridBag is just one of those layouts you have to work with on your own until you "get it" and that can take a little time.

just alternative to GridBagLaout (Action, AbstractAction is threadSafe for some of LayoutManagers, for other you have to call revalidate() + repaint())

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

public class Calc {

    private static void createAndShowUI() {
        CalcGui gui = new CalcGui();
        CalcMenu menu = new CalcMenu(gui);
        JFrame frame = new JFrame("Calculator");
        frame.getContentPane().add(gui.getMainPanel());
        frame.setJMenuBar(menu.getJMenuBar());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                createAndShowUI();
            }
        });
    }

    private Calc() {
    }
}

class CalcGui {

    private static final String[][] STANDARD_BTN_TEXTS = {
        {"7", "8", "9", "/"},
        {"4", "5", "6", "*"},
        {"1", "2", "3", "-"},
        {"0", ".", "=", "+"}};
    private static final String[][] SCIENTIFIC_BTN_TEXTS = {
        {"sqrt", "1/x", "sin", "A", "Sta"},
        {"%", "Exp", "cos", "B", "Ave"},
        {"x^y", "ln", "tan", "C", "Sum"},
        {"x^2", "n!", "sec", "D", "s"},
        {"x^3", "Xor", "Or", "E", "Dat"},
        {"Bit", "+/-", "log", "pi", "dms"}};
    private static final int GAP = 5;
    private static final Font BTN_FONT = new Font(Font.DIALOG, Font.BOLD, 20);
    private JPanel mainPanel = new JPanel();
    private JPanel sciPanel, standardPanel;
    private JTextField display = new JTextField();

    CalcGui() {
        display.setFont(BTN_FONT);
        standardPanel = createBtnPanel(STANDARD_BTN_TEXTS, "Standard");
        sciPanel = createBtnPanel(SCIENTIFIC_BTN_TEXTS, "Scientific");
        mainPanel.setLayout(new BorderLayout());
        mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
        mainPanel.add(standardPanel, BorderLayout.CENTER);
        mainPanel.add(sciPanel, BorderLayout.WEST);
        mainPanel.add(display, BorderLayout.NORTH);
        sciPanel.setVisible(false);
    }

    public void sciPanelSetVisible(boolean visible) {
        sciPanel.setVisible(visible);
        standardPanel.setVisible(!visible);
        Window win = SwingUtilities.getWindowAncestor(mainPanel);
        win.pack();
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

    private JPanel createBtnPanel(String[][] texts, String title) {
        JPanel btnPanel = new JPanel();
        int rows = texts.length;
        int cols = texts[0].length;
        btnPanel.setLayout(new GridLayout(rows, cols, GAP, GAP));
        for (int row = 0; row < texts.length; row++) {
            for (int col = 0; col < texts[row].length; col++) {
                JButton btn = new JButton(texts[row][col]);
                btn.setFont(BTN_FONT);
                btnPanel.add(btn);
            }
        }
        btnPanel.setBorder(BorderFactory.createTitledBorder(title));
        return btnPanel;
    }
}

class CalcMenu {

    private static final String STANDARD = "Standard";
    private static final String SCIENTIFIC = "Scientific";
    private CalcGui gui;
    private JMenuBar menuBar = new JMenuBar();
    private JMenuItem standardView;
    private JMenuItem scientificView;

    CalcMenu(CalcGui gui) {
        this.gui = gui;
        standardView = new JMenuItem(STANDARD, KeyEvent.VK_T);
        scientificView = new JMenuItem(SCIENTIFIC, KeyEvent.VK_S);
        ViewAction viewAction = new ViewAction();
        standardView.addActionListener(viewAction);
        scientificView.addActionListener(viewAction);
        JMenu viewMenu = new JMenu("View");
        viewMenu.setMnemonic(KeyEvent.VK_V);
        viewMenu.add(standardView);
        viewMenu.add(scientificView);
        menuBar.add(new JMenu("Edit"));
        menuBar.add(viewMenu);
        menuBar.add(new JMenu("Help"));
    }

    public JMenuBar getJMenuBar() {
        return menuBar;
    }

    private class ViewAction implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String command = e.getActionCommand();
            if (command.equals(STANDARD)) {
                gui.sciPanelSetVisible(false);
            } else if (command.equals(SCIENTIFIC)) {
                gui.sciPanelSetVisible(true);
            }
        }
    }
}

Thanks for the help.

I added this line of code to the end (the negative button)

JButton btnNeg = new JButton ("+/-"); btnNeg.addActionListener (this); btnNeg.setActionCommand ("negate");
			//btnClr.setPreferredSize(new Dimension (81,26));
			c.gridheight = 4;
			c.gridwidth = 8;
			c.gridx = 9;
			c.gridy = 17;
			pane.add (btnNeg, c);

It should go under the "3", but for some reason it hides halfway behind the "=" button.

for GridBagLaoyut you have to fill all grids horizontally and vertically too, then after you'll play with to set some JComponents to the desired Anchor, start with manual matrix, if with suceed the is possible create matrix on fly

label label label label label label label label

label

label button(setPrefferedSize(new Dimension(int, int)))

label

label

label

setPreferredSize always can safe any of 'mess'

You'll be able to see the locations easier if you change all of those 9, 17, etc to simpler values like 0,1,2 to address the cells. There is no reason they need to be so large. Also remember that indexing begins at 0.

So your "+/-" button should be located at gridx=2, gridy=4 if you normalized those grid positions.

I changed all of the values. Here is the new code:

import javax.swing.*;

import java.awt.event.*;
import java.awt.*;

public class Calc implements ActionListener{

	JTextField disp;
	double total;
	String number;
	
	
	public Calc (){
		JFrame f = new JFrame ("Calculator"); f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
		JPanel pane = new JPanel (new GridBagLayout ());
		GridBagConstraints c = new GridBagConstraints ();
		//c.insets = new Insets (1,1,1,1);
		disp = new JTextField (18);disp.setText ("0");
		c.gridx = 1;
		c.gridy = 1;
		c.gridheight = 1;
		c.gridwidth = 6;
		pane.add (disp,c);
		
			JButton btn0 = new JButton ("0"); btn0.addActionListener(this); btn0.setActionCommand ("0");
			//btn0.setPreferredSize(new Dimension (84,26));
			c.gridheight = 1;
			c.gridwidth = 2;
			c.gridx = 1;
			c.gridy = 5;
			pane.add (btn0,c);
			JButton btn1 = new JButton ("1"); btn1.addActionListener(this); btn1.setActionCommand ("1");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 1;
			c.gridy = 4;
			pane.add (btn1, c);
			JButton btn2 = new JButton ("2"); btn2.addActionListener(this); btn2.setActionCommand ("2");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 2;
			c.gridy = 4;
			pane.add (btn2,c);
			JButton btn3 = new JButton ("3"); btn3.addActionListener(this); btn3.setActionCommand ("3");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 3;
			c.gridy = 4;
			pane.add (btn3,c);
			JButton btn4 = new JButton ("4"); btn4.addActionListener(this); btn4.setActionCommand ("4");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 1;
			c.gridy = 3;
			pane.add (btn4,c);
			JButton btn5 = new JButton ("5"); btn5.addActionListener(this); btn5.setActionCommand ("5");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 2;
			c.gridy = 3;
			pane.add (btn5,c);
			JButton btn6 = new JButton ("6"); btn6.addActionListener(this); btn6.setActionCommand ("6");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 3;
			c.gridy = 3;
			pane.add (btn6,c);
			JButton btn7 = new JButton ("7"); btn7.addActionListener(this); btn7.setActionCommand ("7");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 1;
			c.gridy = 2;
			pane.add (btn7,c);
			JButton btn8 = new JButton ("8"); btn8.addActionListener(this); btn8.setActionCommand ("8");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 2;
			c.gridy = 2;
			pane.add (btn8,c);
			JButton btn9 = new JButton ("9"); btn9.addActionListener(this); btn9.setActionCommand ("9");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 3;
			c.gridy = 2;
			pane.add (btn9,c);
			JButton btnPlus = new JButton ("+"); btnPlus.addActionListener(this); btnPlus.setActionCommand ("+");
			c.gridwidth = 1;
			c.gridheight = 1;
			c.gridx = 4;
			c.gridy = 4;
			pane.add (btnPlus,c);
			JButton btnMin = new JButton ("-"); btnMin.addActionListener(this); btnMin.setActionCommand ("-");
			c.gridwidth = 1;
			c.gridheight = 1;
			c.gridx = 5;
			c.gridy = 4;
			pane.add (btnMin,c);
			JButton btnMult = new JButton ("x"); btnMult.addActionListener(this); btnMult.setActionCommand ("*");
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 4;
			c.gridy = 3;
			pane.add (btnMult,c);
			System.out.println (btnMult.getPreferredSize());
			JButton btnDiv = new JButton ("/"); btnDiv.addActionListener(this); btnDiv.setActionCommand ("/");
			//btnDiv.setPreferredSize(new Dimension (38,26));
			c.gridheight = 1;
			c.gridwidth = 1;
			c.gridx = 5;
			c.gridy = 3;
			System.out.println (btnDiv.getPreferredSize());
			pane.add (btnDiv,c);
			JButton btnEq = new JButton ("="); btnEq.addActionListener(this); btnEq.setActionCommand ("=");
			//btnEq.setPreferredSize(new Dimension (81,26)); // 41,26
			c.gridheight = 1;
			c.gridwidth = 2;
			c.gridx = 4;
			c.gridy = 5;
			pane.add (btnEq,c);
			JButton btnClr = new JButton ("CE"); btnClr.addActionListener(this); btnClr.setActionCommand ("clear");
			//btnClr.setPreferredSize(new Dimension (81,26));
			c.gridheight = 1;
			c.gridwidth = 2;
			c.gridx = 4;
			c.gridy = 2;
			pane.add (btnClr,c);
			JButton btnNeg = new JButton ("+/-"); btnNeg.addActionListener (this); btnNeg.setActionCommand ("negate");
			//btnNeg.setPreferredSize(new Dimension (41,26));
			c.gridheight = 1;
			c.gridwidth = 2;
			c.gridx = 3;
			c.gridy = 5;
			pane.add (btnNeg, c);
		
		
		f.getContentPane().add(pane,BorderLayout.NORTH);
		f.setSize (300,350);
		f.setVisible (true);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Calc c = new Calc ();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if (e.getActionCommand().equals("1")){
			System.out.println ("1 Pressed");
			
		}
		
		
		
	}
	
}

The "+/-" button still starts halfway through the "3" button, when it is supposed to start on the same x axis.

Consider anchoring.

wrong :-)

Anchoring solved the problem. Thanks

wrong :-)

Not wrong.

It addresses on of the problems he describes. I'm looking at the result right here on my screen ;)

Anchoring solved the problem. Thanks

Try playing around with 'fill' next.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.