From: Fencer on
Hello, I have a problem with BorderLayout, and I bet it's really simple.
I have JPanel with a TitledBorder (like a "group" widget) and this
JPanel contains a button.

Now I want to displays this JPanel centered horizontally and vertically
and I don't want it to occupy all the space of the client area of the
JFrame.

I tried this:
package main;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

public class CenteredGroup {

CenteredGroup() {
frame.setSize(1024, 768);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel contentPane = (JPanel)frame.getContentPane();

BorderLayout borderLayout = new BorderLayout(50, 50);

frame.setLayout(borderLayout);

contentPane.setLayout(borderLayout);

JPanel groupPanel = new JPanel();

groupPanel.setBorder(new TitledBorder("This is my group text."));

JButton button = new JButton("A button");

groupPanel.add(button);

contentPane.add(groupPanel, BorderLayout.CENTER);

frame.setVisible(true);
}

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

JFrame frame = new JFrame("Centered Group");
}

However, the "group control" occupies the entire client area of the
frame. Why?

I can provide a screenshot of what it looks like and how I want it to
look like if you have trouble understanding my problem description.

- F
From: RedGrittyBrick on
On 15/02/2010 16:50, Fencer wrote:
> Hello, I have a problem with BorderLayout, and I bet it's really simple.
> I have JPanel with a TitledBorder (like a "group" widget) and this
> JPanel contains a button.
>
> Now I want to displays this JPanel centered horizontally and vertically
> and I don't want it to occupy all the space of the client area of the
> JFrame.
>
> I tried this:
> package main;
>
> import java.awt.BorderLayout;
>
> import javax.swing.JButton;
> import javax.swing.JFrame;
> import javax.swing.JPanel;
> import javax.swing.border.TitledBorder;
>
> public class CenteredGroup {
>
> CenteredGroup() {
> frame.setSize(1024, 768);
> frame.setLocationRelativeTo(null);
> frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>
> JPanel contentPane = (JPanel)frame.getContentPane();
>
> BorderLayout borderLayout = new BorderLayout(50, 50);
>
> frame.setLayout(borderLayout);
>
> contentPane.setLayout(borderLayout);
>
> JPanel groupPanel = new JPanel();
>
> groupPanel.setBorder(new TitledBorder("This is my group text."));
>
> JButton button = new JButton("A button");
>
> groupPanel.add(button);
>
> contentPane.add(groupPanel, BorderLayout.CENTER);
>
> frame.setVisible(true);
> }
>
> public static void main(String[] args) {
> new CenteredGroup();
> }
>
> JFrame frame = new JFrame("Centered Group");
> }
>
> However, the "group control" occupies the entire client area of the
> frame. Why?
>

Because that is the defined behaviour of BorderLayout. If you don't want
that behaviour it is best to not use BorderLayout.

http://java.sun.com/javase/6/docs/api/java/awt/BorderLayout.html


You might like to read the tutorials and try some other layout managers

http://java.sun.com/docs/books/tutorial/uiswing/layout/visual.html
http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html


GridBagLayout is notoriously hard to understand. Many experienced Java
Developers feel it is worthwhile getting to know it well.

I've often seen it asserted that it is surprisingly easy to write your
own layout manager.

I'd recommend you also try a third party layout manager like MigLayout.




From: Knute Johnson on
On 2/15/2010 8:50 AM, Fencer wrote:
> Hello, I have a problem with BorderLayout, and I bet it's really simple.
> I have JPanel with a TitledBorder (like a "group" widget) and this
> JPanel contains a button.
>
> Now I want to displays this JPanel centered horizontally and vertically
> and I don't want it to occupy all the space of the client area of the
> JFrame.
>
> I tried this:
> package main;
>
> import java.awt.BorderLayout;
>
> import javax.swing.JButton;
> import javax.swing.JFrame;
> import javax.swing.JPanel;
> import javax.swing.border.TitledBorder;
>
> public class CenteredGroup {
>
> CenteredGroup() {
> frame.setSize(1024, 768);
> frame.setLocationRelativeTo(null);
> frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>
> JPanel contentPane = (JPanel)frame.getContentPane();
>
> BorderLayout borderLayout = new BorderLayout(50, 50);
>
> frame.setLayout(borderLayout);
>
> contentPane.setLayout(borderLayout);

There is no need to set both the JFrame layout and the ContentPane layout.

>
> JPanel groupPanel = new JPanel();
>
> groupPanel.setBorder(new TitledBorder("This is my group text."));
>
> JButton button = new JButton("A button");
>
> groupPanel.add(button);
>
> contentPane.add(groupPanel, BorderLayout.CENTER);
>
> frame.setVisible(true);
> }
>
> public static void main(String[] args) {
> new CenteredGroup();
> }
>
> JFrame frame = new JFrame("Centered Group");
> }

A little indentation would be nice.

>
> However, the "group control" occupies the entire client area of the
> frame. Why?
>
> I can provide a screenshot of what it looks like and how I want it to
> look like if you have trouble understanding my problem description.
>
> - F

BorderLayout causes the components added to it to fill the available
area. Specifying the hgap and vgap just put extra space between
components not the outer edges. Use a layout that will not do that such
as GridBagLayout. GBL also has the ability to adjust the size and
positions of components.

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

public class test8 extends JPanel {
public test8() {
setPreferredSize(new Dimension(40,30));
setBackground(Color.BLUE);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridBagLayout());
test8 t8 = new test8();
f.add(t8);
f.setSize(400,300);
f.setVisible(true);
}
});
}
}

And this one is a button centered in a JPanel, centered in the JFrame.

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

public class test9 extends JPanel {
public test9() {
super(new GridBagLayout());
setPreferredSize(new Dimension(160,120));
JButton b = new JButton("Press Me");
add(b);
setBorder(BorderFactory.createLineBorder(Color.BLUE,10));
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridBagLayout());
test9 t9 = new test9();
f.add(t9);
f.setSize(800,600);
f.setVisible(true);
}
});
}
}

It is trivial with GBL to align the JPanel to the upper left corner of
the JFrame.

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

public class test9 extends JPanel {
public test9() {
super(new GridBagLayout());
setPreferredSize(new Dimension(160,120));
JButton b = new JButton("Press Me");
add(b);
setBorder(BorderFactory.createLineBorder(Color.BLUE,10));
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridBagLayout());

GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.weightx = c.weighty = 1.0;

test9 t9 = new test9();
f.add(t9,c);
f.setSize(800,600);
f.setVisible(true);
}
});
}
}

--

Knute Johnson
email s/nospam/knute2010/

From: Lew on

Fencer wrote:
>> ... problem with BorderLayout ...
>> I have JPanel with a TitledBorder (like a "group" widget) and this
>> JPanel contains a button.
>>
>> Now I want to displays this JPanel centered horizontally and vertically
>> and I don't want it to occupy all the space of the client area of the
>> JFrame.
>>
>> I tried this [indentation restored from original post - LB]:
>> package main;
>>
>> import java.awt.BorderLayout;
>>
>> import javax.swing.JButton;
>> import javax.swing.JFrame;
>> import javax.swing.JPanel;
>> import javax.swing.border.TitledBorder;
>>
>> public class CenteredGroup {
>>
>> CenteredGroup() {
>> frame.setSize(1024, 768);
>> frame.setLocationRelativeTo(null);
>> frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
>>
>> JPanel contentPane = (JPanel)frame.getContentPane();
>>
>> BorderLayout borderLayout = new BorderLayout(50, 50);
>>
>> frame.setLayout(borderLayout);
>>
>> contentPane.setLayout(borderLayout);
>>
>> JPanel groupPanel = new JPanel();
>>
>> groupPanel.setBorder(new TitledBorder("This is my group text."));
>>
>> JButton button = new JButton("A button");
>>
>> groupPanel.add(button);
>>
>> contentPane.add(groupPanel, BorderLayout.CENTER);
>>
>> frame.setVisible(true);
>> }
>>
>> public static void main(String[] args) {
>> new CenteredGroup();
>> }
>>
>> JFrame frame = new JFrame("Centered Group");

Sorry, but the placement of this declaration and initialization in the source
is confusing

>> }
>>
>> However, the "group control" occupies the entire client area of the
>> frame. Why?

RedGrittyBrick wrote:
> Because that is the defined behaviour of BorderLayout. If you don't want
> that behaviour it is best to not use BorderLayout.
>
> <http://java.sun.com/javase/6/docs/api/java/awt/BorderLayout.html >
>
> You might like to read the tutorials and try some other layout managers
>
> <http://java.sun.com/docs/books/tutorial/uiswing/layout/visual.html>
> <http://java.sun.com/docs/books/tutorial/uiswing/layout/using.html>
>
> GridBagLayout is notoriously hard to understand. Many experienced Java
> Developers feel it is worthwhile getting to know it well.
>
> I've often seen it asserted that it is surprisingly easy to write your
> own layout manager.
>
> I'd recommend you also try a third party layout manager like MigLayout.

Side notes, OP: Do your GUI on the EDT only. Remember to 'pack()'. I suggest
doing the 'setVisible()' outside the constructor. Package-private access
isn't bad, but I wonder why you chose it over private access.

--
Lew
From: markspace on
Fencer wrote:

> However, the "group control" occupies the entire client area of the
> frame. Why?


Basically as others have said: it's because BorderLayout and JPanel
where designed to work that way. Both want to expand components to fill
all available space.

The advice you've got on this thread so far is good. Just to add a bit
of perspective ("there's more than one way to do it"), I feel that when
you start wanting to put GUI components in just the right spot in a
layout, it's time to get a drag-and-drop editor and do it the easy way.

NetBeans has a great GUI editor. Download it, layout your panel (or
JFrame) the way you like, and you're done. It's good to learn exactly
how to manipulate the GUI components programatically by using
GridBagLayout or whatnot, but it's often not necessary to do so. The
GUI editor will work in 90% or more of your use cases.

http://netbeans.org/

http://netbeans.org/kb/docs/java/quickstart-gui.html