I want to create the following GUI with Java Swing.
Since I'm not experienced enough with Java Swing, I'm not sure how to exactly recreate that GUI.
I've tried using GridLayout which looks like this:
I've tried other LayoutManagers but due to my inexperience, I couldn't get anything even remotely resembling the GUI I want to achieve.
I probably have to use GridBagLayout but I've tried it and simply wasn't able to get anything done.
I'm not sure how to exactly use GridBagLayout, especially since there is a variance of the amount of colums needed (2, 2 and then 3).
Here is the code used for creating the second GUI:
import java.awt.*;
import javax.swing.*;
public class GUITest extends JFrame {
public GUITest() {
super("Testing Title");
Container pane = getContentPane();
pane.setLayout(new GridLayout(3,1));
pane.add(getHeader());
pane.add(getTextArea());
pane.add(getButtonPanel());
}
public JComponent getHeader() {
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new GridLayout(1,2));
labelPanel.setSize(getPreferredSize());
JLabel labelLocal = new JLabel("Left value: ", JLabel.CENTER);
JLabel labelDB = new JLabel("Right value: ", JLabel.CENTER);
labelPanel.add(labelLocal);
labelPanel.add(labelDB);
return labelPanel;
}
public JComponent getTextArea() {
JPanel textPanel = new JPanel();
textPanel.setLayout(new GridLayout(1,2,5,0));
JTextArea testTextArea = new JTextArea();
testTextArea.setEditable(false);
JScrollPane sp1 = new JScrollPane(testTextArea);
JTextArea testTextArea2 = new JTextArea();
JScrollPane sp2 = new JScrollPane(testTextArea2);
testTextArea2.setEditable(false);
testTextArea.setText("Hello Hello Hello\nTesting!\ntesterino\ntesteroni");
testTextArea2.setText("Hello Hello Hello\nTesting!\ntest\nABC123\ncdef123\nhijk123");
textPanel.add(sp1);
textPanel.add(sp2);
return textPanel;
}
public JComponent getButtonPanel() {
JPanel inner = new JPanel();
inner.setLayout(new FlowLayout((FlowLayout.CENTER),0,100));
inner.add(new JButton("Do something"));
inner.add(new JButton("Do something different"));
inner.add(new JButton("Do something even more different"));
return inner;
}
public static void main(String[] args) {
GUITest e = new GUITest();
e.setSize(700, 500);
e.setVisible(true);
e.setResizable(false);
e.setDefaultCloseOperation(EXIT_ON_CLOSE);
e.setLocationRelativeTo(null);
}
}
I'm thankful for any kind of support!
You could try something like this:
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
public class Example {
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setTitle("Testing Title");
jFrame.setLocationRelativeTo(null);
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
JPanel listPanel = new JPanel(new GridLayout(0, 2, 10, 0));
JPanel leftListPanel = new JPanel(new BorderLayout(0, 10));
JLabel leftLabel = new JLabel("Left value:");
JTextArea leftTextArea = new JTextArea("Hello Hello Hello\nTesting!\ntest");
JScrollPane leftScrollPane = new JScrollPane(leftTextArea);
leftListPanel.add(leftLabel, BorderLayout.NORTH);
leftListPanel.add(leftScrollPane, BorderLayout.CENTER);
JPanel rightListPanel = new JPanel(new BorderLayout(0, 10));
JLabel rightLabel = new JLabel("Right value:");
JTextArea rightTextArea = new JTextArea("Hello Hello Hello\nTesting!\ntest");
JScrollPane rightScrollPane = new JScrollPane(rightTextArea);
rightListPanel.add(rightLabel, BorderLayout.NORTH);
rightListPanel.add(rightScrollPane, BorderLayout.CENTER);
listPanel.add(leftListPanel);
listPanel.add(rightListPanel);
mainPanel.add(listPanel, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel(new BorderLayout());
buttonsPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
buttonsPanel.add(new JButton("Do something"), BorderLayout.WEST);
buttonsPanel.add(new JButton("Do something different"), BorderLayout.CENTER);
buttonsPanel.add(new JButton("Do something even more different"), BorderLayout.EAST);
mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
jFrame.setContentPane(mainPanel);
jFrame.pack();
jFrame.setVisible(true);
}
}
Explanation:
Firstly I created a main JPanel with a BorderLayout. This JPanel will be split horizontally, the CENTRE component will be another JPanel containing the text areas and labels, and the SOUTH component will be a JPanel containing the buttons.
The JPanel that contains the text areas is given a GridLayout so that it can be easily split vertically, and is also given a hgap of 10 to add some spacing.
The left and right JPanels that are put into that are both the same. They have a BorderLayout with a vgap to add spacing. The NORTH component is a JLabel and the CENTRE component is a JScrollPane containing a JTextArea.
Finally, the SOUTH component of the main JPanel is another JPanel which is given a BorderLayout again. Three JButtons are added with WEST, CENTRE and EAST attributes allocated accordingly.
The overall result looks like:
Here is your code with just some little changes :)
import java.awt.*;
import javax.swing.*;
public class GUITest extends JFrame {
public GUITest() {
super("Testing Title");
Container pane = getContentPane();
pane.setLayout(new BorderLayout());//Modified Layout to BorderLayout
pane.add(getHeader(),BorderLayout.NORTH); //BorderLayout.NORTH
pane.add(getTextArea(),BorderLayout.CENTER);//BorderLayout.CENTER
pane.add(getButtonPanel(),BorderLayout.SOUTH);//BorderLayout.SOUTH
}
public JComponent getHeader() {
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new GridLayout(1,2));
labelPanel.setSize(getPreferredSize());
JLabel labelLocal = new JLabel("Left value: ", JLabel.CENTER);
JLabel labelDB = new JLabel("Right value: ", JLabel.CENTER);
labelPanel.add(labelLocal);
labelPanel.add(labelDB);
return labelPanel;
}
public JComponent getTextArea() {
JPanel textPanel = new JPanel();
textPanel.setLayout(new GridLayout(1,2,5,0));
JTextArea testTextArea = new JTextArea();
testTextArea.setEditable(false);
JScrollPane sp1 = new JScrollPane(testTextArea);
JTextArea testTextArea2 = new JTextArea();
JScrollPane sp2 = new JScrollPane(testTextArea2);
testTextArea2.setEditable(false);
testTextArea.setText("Hello Hello Hello\nTesting!\ntesterino\ntesteroni");
testTextArea2.setText("Hello Hello Hello\nTesting!\ntest\nABC123\ncdef123\nhijk123");
textPanel.add(sp1);
textPanel.add(sp2);
return textPanel;
}
public JComponent getButtonPanel() {
JPanel inner = new JPanel();
inner.setLayout(new FlowLayout());//Modified to standard FlowLayout
inner.add(new JButton("Do something"));
inner.add(new JButton("Do something different"));
inner.add(new JButton("Do something even more different"));
return inner;
}
public static void main(String[] args) {
GUITest e = new GUITest();
e.pack(); //Modified setSize(700,500) to pack()
e.setVisible(true);
e.setResizable(false);
e.setDefaultCloseOperation(EXIT_ON_CLOSE);
e.setLocationRelativeTo(null);
}
}
GridLayout sizes all cells the same, i.e. your outer layout with 3 rows and 1 column makes 3 cells of all the same size.
Instead, use BorderLayout for your outer container and add the top, mid and lower panels with constraints BorderLayout.NORTH, BorderLayout.CENTER and BorderLayout.SOUTH respectively
Related
I am making a Java application with tabbed pane, I want some panes to have the same panel layout and structure, I don't want to clutter my code by writing the same code over and over again, so I created a method that returns a JPanel with a structure I want the pane to have.
I am initialising new variables and taking them to the method . My problem is that after I create a panel I can not do anything else in it because it doesn't show up. I can not add labels etc, etc (although if I add the label in the method it does show).
My question is it possible to somehow change the code I've written to make it possible to change it after the panel is returned?
JPanel panel2 = panel2(); // this code bit is in the constructor
JPanel mainPanel = new JPanel(); //Variables needed to create a panel
JPanel LeftPanel = new JPanel();
JPanel RightPanel = new JPanel();
JSplitPane splitPaneH = new JSplitPane();
JPanel panelTop = new JPanel();
JPanel panelBottom = new JPanel();
private JPanel panel2() {
JPanel newPanel = new JPanel();
CreateAPanel(newPanel, LeftPanel,RightPanel,splitPaneH, panelTop,panelBottom);
JLabel label = new JLabel ("lalala");
LeftPanel.add(label,BorderLayout.CENTER);
return newPanel;
}
private JPanel CreateAPanel(JPanel mainPanel, JPanel LeftPanel,JPanel RightPanel, JSplitPane splitPaneH, JPanel panelTop, JPanel panelBottom){
mainPanel.setPreferredSize(new Dimension(1100, 630));
mainPanel.setLayout(new BorderLayout());
LeftPanel = new JPanel();
RightPanel = new JPanel();
splitPaneH = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
panelTop = new JPanel();
panelBottom = new JPanel();
splitPaneH.setTopComponent(panelTop);
splitPaneH.setBottomComponent(panelBottom);
splitPaneH.setDividerLocation(300);
splitPaneH.setPreferredSize(new Dimension(800,630));
mainPanel.add(LeftPanel, BorderLayout.WEST);
mainPanel.add(RightPanel,BorderLayout.EAST);
LeftPanel.setBackground(Color.RED);
LeftPanel.setPreferredSize(new Dimension (300,630));
RightPanel.add(splitPaneH);
return mainPanel;
}
you do not use your return value...
your method CreateAPanel(...) creates the desired panel but you just don't use it
you should adjust your method panel2() in like this:
private JPanel panel2()
{
//JPanel newPanel = new JPanel(); don't create a new panel!
//CreateAPanel(newPanel, LeftPanel,RightPanel,splitPaneH, panelTop,panelBottom);
//instead do this:
JPanel newPanel = CreateAPanel(newPanel, LeftPanel,RightPanel,splitPaneH, panelTop,panelBottom);
JLabel label = new JLabel ("lalala");
LeftPanel.add(label,BorderLayout.CENTER);
return newPanel;
}
It's totally possible to add components to the Panel object afterwards. The only mistake that you have made is that "inside the method body you create new JPanel instances to replace with original param references" so when the method returns there is no effect on the original objects. I suggest doing something different as this:
private JPanel[] CreateAPanel(JPanel mainPanel)
{
mainPanel.setPreferredSize(new Dimension(1100, 630));
mainPanel.setLayout(new BorderLayout());
JPanel leftPanel = new JPanel();
JPanel rightPanel = new JPanel();
JSplitPane splitPaneH = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
JPanel panelTop = new JPanel();
JPanel panelBottom = new JPanel();
splitPaneH.setTopComponent(panelTop);
splitPaneH.setBottomComponent(panelBottom);
splitPaneH.setDividerLocation(300);
splitPaneH.setPreferredSize(new Dimension(800,630));
mainPanel.add(leftPanel, BorderLayout.WEST);
mainPanel.add(rightPanel,BorderLayout.EAST);
leftPanel.setBackground(Color.RED);
leftPanel.setPreferredSize(new Dimension (300,630));
rightPanel.add(splitPaneH);
return new JPanel[]{mainPanel, leftPanel, rightPanel, panelTop, panelBottom};
}
If you want to change or add some more components inside result JPanel you get you can set names to all your components when you create them:
JPanel newPanel = new JPanel();
newPanel .setName("leftPanel");
resultPanel.add(newPanel, BorderLayout.WEST);
Then when you get resultPanel you can get it's components:
Component[] componentList = resultPanel.getContentPane().getComponents();
JPanel leftPanel = null;
for (Component component: componentList) {
if (Objects.equals(component.getName(), "leftPanel")) {
leftPanel = (JPanel) component;
}
}
if (leftPanel != null) {
// do something
}
How can I fix blank screen on jframe and set values of vgap and hgap from textfield. i am using borderlayout for this.
import java.awt.*;
import javax.swing.*;
public class d1{
public static void main(String[] args) {
JFrame f1 = new JFrame ("Border Layout") ;
f1.setLayout(new BorderLayout());
f1.setVisible(true);
f1.setSize(400,400);
f1.setLocationRelativeTo(null);
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField t1 = new JTextField();
t1.setBorder(BorderFactory.createLineBorder(Color.BLACK));
JTextField t2 = new JTextField();
t2.setBorder(BorderFactory.createLineBorder(Color.BLACK));
JPanel p1 = new JPanel ();
p1.setLayout(new BorderLayout());
p1.add(new JButton("East"), BorderLayout.EAST);
p1.add(new JButton("South"), BorderLayout.SOUTH);
p1.add(new JButton("West"), BorderLayout.WEST);
p1.add(new JButton("North"), BorderLayout.NORTH);
p1.add(new JButton("Center"), BorderLayout.CENTER);
JPanel p2 = new JPanel ();
p2.setLayout(new BorderLayout());
JPanel p3 = new JPanel ();
p3.setLayout(new BorderLayout());
p3.add(new JLabel("Vgap"), BorderLayout.WEST);
p3.add(t1, BorderLayout.CENTER);
JPanel p4 = new JPanel ();
p4.setLayout(new BorderLayout());
p4.add(new JLabel("Hgap"), BorderLayout.WEST);
p4.add(t2, BorderLayout.CENTER);
JPanel p5 = new JPanel();
p5.setLayout(new BorderLayout());
p5.add(new JLabel("Container of BorderLayout"));
JPanel p6 = new JPanel();
p6.setLayout(new BorderLayout());
p6.add(new JLabel("BorderLayout Properties"));
JPanel p7 = new JPanel ();
p7.setLayout(new BorderLayout());
p7.add(p6, BorderLayout.NORTH);
p7.add(p2, BorderLayout.SOUTH);
p2.add(p3, BorderLayout.NORTH);
p2.add(p4, BorderLayout.SOUTH);
f1.add(p1, BorderLayout.CENTER);
f1.add(p7, BorderLayout.SOUTH);
f1.add(p5, BorderLayout.NORTH);
}
}
after this code.
There should be space between north-south and center, north, south and center.
I can not fix blank screen problem when frame is opened.
Add your panels before f1.setVisible(True) on frame and f1.pack() the frame after it.
You don't need to set a fixed size for your frame. Your added components should take care of it.
To set your components, look at MigLayout. It's easy to use and set components the way you need it.
please check this link you can find it here but first you should add ActionListener into your textField objects so that they can take numbers from inside of themselves. Providing white space in a Swing GUI
something like that
t1 = new JTextField();
t1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String v = t1.getText();
int numberhGap = Integer.parseInt(v);
}
});
t1.setBorder(BorderFactory.createLineBorder(Color.BLACK));
t2 = new JTextField();
t2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String h = t2.getText();
int numberhGap = Integer.parseInt(h);
}
});
and declare t1 and t2 outside main method.
like this
public class d1{
static JTextField t1;
static JTextField t2;
My JTabbedPane is in a JSplitPane in a JPanel, like this, but I don't want it to be small like that:
I want it to look like this:
How do I do that?
Here is my code:
Tabbed_Tables.java
public void setupWidow(){
JPanel left = new JPanel();
JPanel right = new JPanel();
JTabbedPane EntryTabs = new JTabbedPane();
JTabbedPane ViewTabs = new JTabbedPane();
EntryTabs.addTab("Form Entry", new FormEntry());
EntryTabs.setOpaque(true);
EntryTabs.addTab("Table Entry", new TableEntry());
//EntryTabs.setSize(new Dimension(500,500));
//ViewTabs.setSize(new Dimension(200,200));
ViewTabs.add("Help Window", new HelpWindow());
left.add(EntryTabs);
right.add(ViewTabs);
JSplitPane splitPane= new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,left, right);
splitPane.setSize(new Dimension(pane.getWidth(),pane.getHeight()));
//((JFrame) pane).setContentPane(splitPane);
pane.add(splitPane,BorderLayout.CENTER);
//this.setSize(500, 500);
this.setVisible(true);
this.revalidate();
}
Either add the JTabbedPanes directly to the JSplitPane
JSplitPane splitPane= new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true, EntryTabs, ViewTabs);
Or change the layout managers for left and right to BorderLayout
JPanel left = new JPanel(new BorderLayout());
JPanel right = new JPanel(new BorderLayout());
See How to Use BorderLayout for more details
use this code
import java.awt.*;
import javax.swing.*;
class MyLayout extends JFrame
{
JPanel p1,p2;
JTabbedPane jtp;
public MyLayout()
{
setTitle("Tabed pane example");
setSize(750,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p1 = new JPanel();
p2 = new JPanel();
jtp = new JTabbedPane(JTabbedPane.TOP);
jtp.addTab("Table Entry",p1);
jtp.addTab("Chart Entry",p2);
add(jtp);
setVisible(true);
}
public static void main(String args[])
{
MyLayout m = new MyLayout();
}
}
you are not set frame size
Can anyone help me. Why is the Label "Current" NOT left aligned in Panel/Frame?
public static void main(String[] args) {
JFrame TFrame = new JFrame("Test DisplayLayout");
TFrame.setResizable(true);
TFrame.setSize(new Dimension(900, 840));
TFrame.setLocationRelativeTo(null);
TFrame.setTitle("DisplayLayout");
TFrame.setVisible(true);
JPanel P = DisplayLayout2();
P.setVisible(true);
P.setOpaque(true);
P.setLayout(new BoxLayout(P, BoxLayout.Y_AXIS));
TFrame.add(P);
TFrame.revalidate();
TFrame.repaint();
}
public static JPanel DisplayLayout2() {
JPanel Panel=new JPanel();
Panel.setVisible(true);
Panel.setOpaque(true);
Panel.setLayout(new BoxLayout(Panel, BoxLayout.Y_AXIS));
Panel.setAlignmentX(Component.LEFT_ALIGNMENT);
JLabel lab = new JLabel("Current");
lab.setHorizontalAlignment(SwingConstants.LEFT);
lab.setForeground(Color.WHITE);
lab.setBackground(Color.PINK);
lab.setOpaque(true);
Panel.add(lab,Component.LEFT_ALIGNMENT);
JPanel posPanel = new JPanel();
JScrollPane scrollPane = new JScrollPane(posPanel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(290, 200));
scrollPane.setOpaque(true);
posPanel.setBackground(Color.YELLOW);
posPanel.setPreferredSize(new Dimension(290, 200));
posPanel.setLayout(new BoxLayout(posPanel, BoxLayout.Y_AXIS));
posPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
Panel.add(scrollPane);
return Panel;
}
This is one of the quirks of the BoxLayout (well, quirk to me, but it is a documented expected behavior of the layout), and I'm forgetting off the top of my head why it does this, but I do know of at least one way around it: put your JLabel into a JPanel that uses FlowLayout.LEFT (or LEADING), and add that to your BoxLayout-using container:
JPanel labPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
labPanel.add(lab);
panel.add(labPanel, Component.LEFT_ALIGNMENT);
Note, that I believe that it has something to do with the JLabel not wanting to expand while the JPanel that encloses it does, but don't quote me on that.
Edit
From the BoxLayout Tutorial:
For a top-to-bottom box layout, the preferred width of the container is that of the maximum preferred width of the children. If the container is forced to be wider than that, BoxLayout attempts to size the width of each component to that of the container's width (minus insets). If the maximum size of a component is smaller than the width of the container, then X alignment comes into play.
You could probably solve this by setting both the JLabel's and the JScrollPane's x-alignment to Component.LEFT_ALIGNMENT. Your current code forgets to set the JScrollPane's x-alignment, and that's where your trouble lies:
scrollPane.setAlignmentX(Component.LEFT_ALIGNMENT);
For example:
import java.awt.*;
import javax.swing.*;
public class Foo2 {
private static void createAndShowGui() {
JLabel topLabel = new JLabel("Top Label", SwingConstants.LEFT);
topLabel.setOpaque(true);
topLabel.setBackground(Color.pink);
JScrollPane scrollpane = new JScrollPane(
Box.createRigidArea(new Dimension(400, 400)),
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
topLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
mainPanel.add(topLabel);
scrollpane.setAlignmentX(Component.LEFT_ALIGNMENT);
mainPanel.add(scrollpane);
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This results in:
Use constant into Component(Left,Right,Center)
When I run this program, the window blocks out the buttons in panel2 when I use setSize to determine window size.
In addition, if I use frame.pack() instead of setSize(), all components are on one horizontal line but I'm trying to get them so that panel1 components are on one line and panel2 components are on a line below them.
Could someone explain in detail the answers to both of these problems?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Exercise16_4 extends JFrame{
// FlowLayout components of top portion of calculator
private JLabel jlbNum1 = new JLabel("Number 1");
private JTextField jtfNum1 = new JTextField(4);
private JLabel jlNum2 = new JLabel("Number 2");
private JTextField jtfNum2 = new JTextField(4);
private JLabel jlbResult = new JLabel("Result");
private JTextField jtfResult = new JTextField(8);
// FlowLayout Components of bottom portion of calculator
private JButton jbtAdd = new JButton("Add");
private JButton jbtSubtract = new JButton("Subtract");
private JButton jbtMultiply = new JButton("Multiply");
private JButton jbtDivide = new JButton("Divide");
public Exercise16_4(){
JPanel panel1 = new JPanel();
panel1.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3));
panel1.add(jlbNum1);
panel1.add(jtfNum1);
panel1.add(jlNum2);
panel1.add(jtfNum2);
panel1.add(jlbResult);
panel1.add(jtfResult);
JPanel panel2 = new JPanel();
panel2.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 10));
panel1.add(jbtAdd);
panel1.add(jbtSubtract);
panel1.add(jbtMultiply);
panel1.add(jbtDivide);
add(panel1, BorderLayout.NORTH);
add(panel2, BorderLayout.CENTER);
}
public static void main(String[] args){
Exercise16_4 frame = new Exercise16_4();
frame.setTitle("Caculator");
frame.setSize(400, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setResizable(false);
frame.setVisible(true);
}
}
You're problem is likely a typographical error in that you're adding all components to panel1 and none to panel2:
// you create panel2 just fine
JPanel panel2 = new JPanel();
panel2.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 10));
// but you don't use it! Change below to panel2.
panel1.add(jbtAdd);
panel1.add(jbtSubtract);
panel1.add(jbtMultiply);
panel1.add(jbtDivide);
Add the buttons to panel2, and then call pack() before setVisible(true). Do not set the size of the GUI.