I'm trying to make a simple calculator to familiarize myself with the creation of GUIs that I've just learned in my intro to Computer Science class. I am having an issue getting the GUI to be arranged in the way that I would like. I figured that BoxLayout would be perfect, but whenever I try to use it, my program crashes with this error log:
Exception in thread "AWT-EventQueue-0" java.awt.AWTError: BoxLayout can't be shared
at javax.swing.BoxLayout.checkContainer(Unknown Source)
at javax.swing.BoxLayout.invalidateLayout(Unknown Source)
at javax.swing.BoxLayout.addLayoutComponent(Unknown Source)
at java.awt.Container.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at javax.swing.JFrame.addImpl(Unknown Source)
at java.awt.Container.add(Unknown Source)
at GUI.run(GUI.java:64)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Here is my code:
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.BoxLayout;
import javax.swing.JButton;
public class GUI implements Runnable{
@Override
public void run() {
JFrame window = new JFrame("Calculator");
window.setLayout(new BoxLayout(window, BoxLayout.Y_AXIS));
JPanel display = new JPanel();
JLabel label = new JLabel("display test");
display.add(label);
JPanel row1 = new JPanel();
JButton sevenButton = new JButton("7");
JButton eightButton = new JButton("8");
JButton nineButton = new JButton("9");
JButton divideButton = new JButton("÷");
JPanel row2 = new JPanel();
JButton fourButton = new JButton("4");
JButton fiveButton = new JButton("5");
JButton sixButton = new JButton("6");
JButton multiplyButton = new JButton("x");
JPanel row3 = new JPanel();
JButton oneButton = new JButton("1");
JButton twoButton = new JButton("2");
JButton threeButton = new JButton("3");
JButton minusButton = new JButton("-");
JPanel row4 = new JPanel();
JButton periodButton = new JButton(".");
JButton zeroButton = new JButton("0");
JButton enterButton = new JButton("=");
JButton addButton = new JButton("+");
row1.add(sevenButton);
row1.add(eightButton);
row1.add(nineButton);
row1.add(divideButton);
row2.add(fourButton);
row2.add(fiveButton);
row2.add(sixButton);
row2.add(multiplyButton);
row3.add(oneButton);
row3.add(twoButton);
row3.add(threeButton);
row3.add(minusButton);
row4.add(periodButton);
row4.add(zeroButton);
row4.add(enterButton);
row4.add(addButton);
window.add(display);
window.add(row1);
window.add(row2);
window.add(row3);
window.add(row4);
window.pack();
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
The program works fine when I change the BoxLayout to a FlowLayout, but that is not the type of layout I desire for my program.
Try something like:
//window.setLayout(new BoxLayout(window, BoxLayout.Y_AXIS));
JPanel contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
window.setContentPane(contentPane);
This way you are sure that the BoxLayout
is added to the panel to be used as the content pane of the frame.
The other option would be to add all the components directly to the "contentPane" panel and then add this panel to the frame:
//window.setLayout(new BoxLayout(window, BoxLayout.Y_AXIS));
JPanel contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
...
//window.add(display);
//window.add(row1);
//window.add(row2);
//window.add(row3);
//window.add(row4);
contentPane.add(display);
contentPane.add(row1);
contentPane.add(row2);
contentPane.add(row3);
contentPane.add(row4);
window.add(contentPane);