I noticed this kinda of event some weeks ago, but I ignored, now it's making me curious. the last element that I add always end up in the up position of the screen, no matter how much I try to alter the positions of the elements created, the result is the same.
It was supposed to have two buttons inline.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
import javax.swing.border.TitledBorder;
public class Todolist extends JFrame {
private JLabel jcriar, jtexto, jnum, jtexto1;
private JButton btcriar, btrem;
private JTextField txtcriar;
private JPanel jp;
int t = 0;
public static void main(String[] args) {
JFrame op = new Todolist();
op.setVisible(true);
op.setLayout(null);
op.setSize(500, 400);
op.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public Todolist() {
elemen();
}
public void elemen() {
jcriar = new JLabel("criar/remover");
txtcriar = new JTextField();
btcriar = new JButton("criar");
btrem = new JButton("remover");
jp = new JPanel();
jp.setBounds(230, 100, 150, 200);
jp.setLayout(null);
jp.setBorder(new TitledBorder(""));
jcriar.setBounds(30, 30, 100, 20);
txtcriar.setBounds(131, 30, 100, 20);
btcriar.setBounds(232, 30, 80, 20);
btrem.setBounds(314, 30, 80, 20);
add(jcriar);
add(txtcriar);
add(btcriar);
add(jp);
add(btrem);
}
}
-
2Welcome to StackOverflow!! I am not certain what you meant by the "up position." But you are making the Frame visible before it is fully populated. Move the op.setVisible(true) to the end. Also, you should not be extending JFrame as it is considered poor design. Also, learn about layout managers in lieu of absolute positioning. In the long run, it will make your GUI's more manageable.WJS– WJS2025年12月13日 14:12:22 +00:00Commented Dec 13, 2025 at 14:12
-
And please take the tour to learn more about SO.WJS– WJS2025年12月13日 14:19:35 +00:00Commented Dec 13, 2025 at 14:19
-
3Be careful in using the Null layout in swing, see stackoverflow.com/questions/6592468/…Progman– Progman2025年12月13日 19:48:27 +00:00Commented Dec 13, 2025 at 19:48
3 Answers 3
Never do this:
op.setLayout(null);
jp.setLayout(null);
And never call setBounds.
Instead, use layouts. They exist precisely to handle this problem. By trying to place components manually, you are taking on the responsibility of making sure everything ends up in the right place. Furthermore, your bounds are only valid on your computer—on another computer, the same font may take up a different number of pixels. In fact, there’s no guarantee the same font or font size will be used on other computers.
All of this is handled by layout managers. If you use a layout manager, you won’t have to worry about any of the above issues. Here is an example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
public class Todolist extends JFrame {
private JLabel jcriar, jtexto, jnum, jtexto1;
private JButton btcriar, btrem;
private JTextField txtcriar;
private JPanel jp;
int t = 0;
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame op = new Todolist();
op.setDefaultCloseOperation(EXIT_ON_CLOSE);
op.setLocationByPlatform(true);
op.setVisible(true);
});
}
public Todolist() {
elemen();
}
public void elemen() {
jcriar = new JLabel("criar/remover");
txtcriar = new JTextField();
btcriar = new JButton("criar");
btrem = new JButton("remover");
String padding = " ".repeat(32);
JList<String> itemList = new JList<String>(
new String[] {
"First" + padding,
"Second" + padding,
"Third" + padding,
"Fourth" + padding,
"Fifth" + padding
});
jp = new JPanel(new BorderLayout());
jp.add(new JScrollPane(itemList));
jp.setBorder(BorderFactory.createEmptyBorder(24, 200, 12, 200));
Box criarRow = Box.createHorizontalBox();
criarRow.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6));
criarRow.add(jcriar);
criarRow.add(Box.createHorizontalStrut(12));
criarRow.add(txtcriar);
criarRow.add(Box.createHorizontalStrut(6));
criarRow.add(btcriar);
criarRow.add(Box.createHorizontalStrut(6));
criarRow.add(btrem);
add(criarRow, BorderLayout.NORTH);
add(jp, BorderLayout.CENTER);
pack();
}
}
Two layouts are used in the above code: Box, which creates a row or column; and BorderLayout, which places one component in the center and optionally a component on each side (left, right, top, and bottom). jp is in the center position and criarRow is in the top (north) position.
Notice that there are no calls to setLayout(null) and no calls to setBounds. The layout managers take care of setting the locations and sizes of the components.
Instead of calling setSize on the frame, the above code calls the pack() (a method which JFrame inherits from its superclass, Window), which asks all of the layouts to report their preferred sizes based on the components they manage and then sets the frame’s size to that optimal prferred size. You could do all of that work yourself, but layout managers already do it for you. Considering such work can get pretty complex, it’s easier to just use layout managers the way they were intended to be used.
3 Comments
It usually happens when the element has positioning or margin applied.
Check either the position: absolute or relative with a top value
I reviewed your Java code carefully, and it seems like everything is correct even tough readability could be optionally improved.
1. Delayed Component Loading:
I can see that you are not using EDT (Event Dispatching Thread) in your code, it is type of Thread that we use in Java Swing to make components update easily and fastly.
2. Inheriting JFrame and then Initializing the Frame:
Actually, it is an interesting choice but actually doing so can lead to StackOverflowError, Instead it is truly better to finish creating instance of JFrame class.
3. Additional changes to JFrame:
It is totally optional but I added little changes to JFrame, so It works efficiently. otherwise its fine.
4. Important Part:
Please make sure that Components have their bounds set to correct coordinates such as (x, y, width, height).
5. Visibility of the Components:
it is also optional but I highly recommend to set components to visible and focusable to false as well (Excluding JTextArea/JTextField because text may not appear after doing so).
Short & Simple anserw: Components always appear at the top of the window because of bounds which you have set for them.
Fixed version of your code:
package main;
import javax.swing.*;
import javax.swing.border.TitledBorder;
public class Todolist {
private static final long serialVersionUID = 1L;
private JLabel jcriar, jtexto, jnum, jtexto1;
private JButton btcriar, btrem;
private JTextField txtcriar;
private JPanel jp;
private JFrame op;
int t = 0;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Todolist().elemen();
}); //fixing component loading Delay (using EDT)
}
public Todolist(){
op = new JFrame(); // lets directly initialize with JFrame because the same Todo-list class is called and StackOverflowError is happening..
// op.setTitle("To-Do List"); optional
op.setLayout(null);
// op.setResizable(false); optional
op.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
op.setSize(500, 400);
op.setLocationRelativeTo(null); // make the window appear at the middle/center of the screen
op.setVisible(true);
}
public void elemen(){
jcriar = new JLabel("criar/remover");
txtcriar = new JTextField();
btcriar = new JButton("criar");
btrem = new JButton("remover");
jp = new JPanel();
jp.setBounds(230, 100, 150, 200);
jp.setLayout(null);
jp.setBorder(new TitledBorder(""));
// MOST IMPORANT PART (Adjust the bounds as you want to make components appear in a right place)
jcriar.setBounds(30, 30, 100, 20);
txtcriar.setBounds(131, 30, 100, 20);
btcriar.setBounds(232, 30, 80, 20);
btrem.setBounds(314, 30, 85, 20); //changed the bounds little bit to make text fit inside of the button
jcriar.setFocusable(false);
btcriar.setFocusable(false);
btcriar.setVisible(true);
btrem.setVisible(true);
jcriar.setVisible(true);
txtcriar.setVisible(true);
op.add(jcriar);
op.add(txtcriar);
op.add(btcriar);
op.add(jp);
op.add(btrem);
}
}