Java Swing JFrame Layout
Asked Answered
O

6

12

I just wrote a simple code where I want a textfield and a button to appear on the main frame, but after running all I see is the textfield.

If I write the code of the button after the textfield then only the button is displayed.

Any idea why?

    JFrame mainframe=new JFrame();
    mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainframe.setBounds(0,0,200,200);
    JButton jb=new JButton();
    jb.setText("Leech");
    mainframe.add(jb);
    JTextField link=new JTextField(50);
    mainframe.add(link);
    mainframe.pack();
    mainframe.setVisible(true);
Oddfellow answered 28/12, 2011 at 20:12 Comment(1)
The class javadoc clearly states that you can call add as well, which will add it to the content pane. At least in more recent versions of Java then the 1.3 documentation to which you referBunyan
P
5

Add your components to a JPanel and then add that panel to the ContentPane of JFrame.

JFrame window = new JFrame();
JPanel mainframe = new JPanel();

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(0,0,200,200);

JButton jb = new JButton();
jb.setText("Leech");

mainframe.add(jb);

JTextField link = new JTextField(50);
mainframe.add(link);

window.getContentPane().add(mainframe);
window.pack();
window.setVisible(true);
Psalm answered 28/12, 2011 at 20:41 Comment(5)
which is basically the same as setting FlowLayout as LayoutManager on the JFrame, since that is the default layout form the JPanelBunyan
Can't believe this is the accepted answer. Robin's answer below is the correct answer. Just have to understand what the default layout manager of a JFrame is and the default position something is added to in a BorderLayout if one isn't specified.Circumstantiate
@Circumstantiate what is the point of your comment? Do you think this answer is wrong or you don't like how it is coded that way?Psalm
@Psalm the OP's question was "Any idea why?", you did not explain why his code wasn't working, Robin's answer explains whyCircumstantiate
@Circumstantiate whenever I ask "why something is not working", I mean "can someone make it work for me". But that is how I think and I assume that is what he want, "make both button and textfield show in the window". He accepted it as an answer because he found what he was looking for. For other people who really want to know why have up voted Robin's answer and you can see he got more votes so you can read the answer with most vote, which is what I do on stackoverflow.Psalm
B
14

The default layout on a JFrame is a BorderLayout. Calling the add method on a Container with such a layout is equivalent to a call add(..., BorderLayout.CENTER). Each of the locations of the BorderLayout can contain only one element. Hence making two calls

mainframe.add(jb);
mainframe.add(link);

results in a CENTER containing the last component you added. If you want to avoid this you can either add it to different locations, or use another layout manager (for example a FlowLayout) by calling JFrame#setLayout

Bunyan answered 28/12, 2011 at 20:30 Comment(1)
So what's the point of panels if you can just do this in the frame?Plot
E
9

Instead of adding directly Components to the JFrame, use a JPanel as container with the desired LayoutManager.

Here you can find several tutorials on layout managers.

Basically in Swing the LayoutManager is responsible for laying out the children Components (establishing their position and their size), so every container component you use inside your app, should be configured with the appropiate LayoutManager.

Enumerate answered 28/12, 2011 at 20:14 Comment(1)
The link on LayoutManager is now dead. Please fix.Aryl
P
5

Add your components to a JPanel and then add that panel to the ContentPane of JFrame.

JFrame window = new JFrame();
JPanel mainframe = new JPanel();

window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(0,0,200,200);

JButton jb = new JButton();
jb.setText("Leech");

mainframe.add(jb);

JTextField link = new JTextField(50);
mainframe.add(link);

window.getContentPane().add(mainframe);
window.pack();
window.setVisible(true);
Psalm answered 28/12, 2011 at 20:41 Comment(5)
which is basically the same as setting FlowLayout as LayoutManager on the JFrame, since that is the default layout form the JPanelBunyan
Can't believe this is the accepted answer. Robin's answer below is the correct answer. Just have to understand what the default layout manager of a JFrame is and the default position something is added to in a BorderLayout if one isn't specified.Circumstantiate
@Circumstantiate what is the point of your comment? Do you think this answer is wrong or you don't like how it is coded that way?Psalm
@Psalm the OP's question was "Any idea why?", you did not explain why his code wasn't working, Robin's answer explains whyCircumstantiate
@Circumstantiate whenever I ask "why something is not working", I mean "can someone make it work for me". But that is how I think and I assume that is what he want, "make both button and textfield show in the window". He accepted it as an answer because he found what he was looking for. For other people who really want to know why have up voted Robin's answer and you can see he got more votes so you can read the answer with most vote, which is what I do on stackoverflow.Psalm
G
1

You can also use something like Flow Layout which is the default layout used by JPanel. It is used to arrange components in a line or a row. For example from left to right or from right to left:

enter image description here

Flow layout arranges components in line and if no space left all remaining components goes to next line. Align property determines alignment of the components as left, right, center etc.

To use it you will need to set JFrame layout by using JFrame.setLayout(layout) and to pass flow layout as a parameter.

Following example shows components arranged in flow layout:

package example.com;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;

public class FlowLayoutExample {

    FlowLayoutExample(){
        JFrame frame = new JFrame("Flow Layout");
        JButton button, button1, button2, button3, button4;
        button = new JButton("button 1");
        button1 = new JButton("button 2");
        button2 = new JButton("button 3");
        button3 = new JButton("button 4");
        button4 = new JButton("button 5");
        frame.add(button);
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.add(button4);
        frame.setLayout(new FlowLayout());
        frame.setSize(300,300);  
        frame.setVisible(true);  

    }
    public static void main(String[] args) {
        new FlowLayoutExample();
    }
}

Check out to learn more about JFrame layouts.

Gauguin answered 4/5, 2019 at 18:34 Comment(0)
C
0

JFrame's default Layout Manager is BorderLayout. If you want the automatic layout, you may use the FlowLayout:

mainframe.setLayout(new FlowLayout());

If you want to specify coordinates by setBounds() method, you have to cancel the setting of layout manager on JFrame:

mainframe.setLayout(null);
jb.setBounds(10,10,100,50);
link.setBounds(10,70,180,100);
Craniotomy answered 27/9, 2014 at 5:19 Comment(1)
You should never recommend setting layout to null, that is just plain wrong.Circumstantiate
U
0

if you see BorderLayout Documentation mainframe.add(jb); is equals to mainframe.add(jb,BorderLayout.CENTER); mainframe.add(link); is equals to mainframe.add(jb,BorderLayout.CENTER);

so it just show the last one

Unclinch answered 5/6, 2017 at 21:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.