java.awt.BorderLayout doesn't let you put things in the corners.
The corners don't even exist in their own right.
All that exists are a bar across the top, full width, a similar bar at the bottom, and left/right sections in between those bars, and then the center that resizes to fill the gap.
But what about when you want those corners?
This is one approach:
It resembles the desired result, but is fairly hackish by using nested BorderLayouts. Ugh.
Google "borderlayout corner" and you get a bunch of non-answers, all very hackish, all of which purport to do what you want, but have various drawbacks ("I would use nested JPanels with such-n-such" or some other garbage). Stackoverflow is where most of the discussion takes place, and the result is typical of SOF. GridBag (yuk), the above nested BorderLayouts, "put your widgets into a custom Border", etc; all yuk, all missing the target.
The basic answer is that there's no built-in way in awt/swing to do this. At all. Which is kinda sad.
Actually the custom border is almost the right approach.
-------------------
I had wanted this years ago, long enough back that I don't remember when the idea first occurred to me.
Should not take an Advanced Degree(tm) to figure this out. Altho looking at that SOF discussion, it might. Fortunately that's what we have here at Hyde U.
-------------------
The answer is of course that you have to make your own layout manager. That's not terribly hard, I've done it before, with a grid variation.
The NE corner is a JButton. The other corners are JLabels. The sides are JPanels, with one JLabel each. The center is just a JPanel. All with background colors that are hideous so you can see where the boundaries are. The center/east boundary appears to have a one-pixel glitch I haven't figured out.
In the code below, it's ok to only fill one corner. Remember that JButton uses a lot of margin space, so if you wanted (for example, and the reason I started on this finally) a tiny little "X" button @ NE, you're going to have to force the JButton to be the size you want.
All the proper resizing takes place, layout is dynamically computed to match whatever you are putting in the corners.
Of course this leads to a fairly horrible aesthetic around the sides because the corners can force the sides into sizes you don't like, but the whole thing DOES work. If you want something sized more like the first image, then you should go with that alternative. It's in the code at the bottom.
How'd I do this? I grabbed the Java 7 source for BorderLayout, and started banging on it. It's not quite finished, I want to strip out some extraneous garbage (the LTR stuff, and the PAGE_START stuff), hgap/vgap aren't used everywhere as spacers...
Took me about 3 hours. Longer than it should have, I went down a bad direction with cut-n-paste errors, had to start over.
Here it is:
(note that this is at least partially copyright Sun Microsystems, from way back when; you can find the Java 7 source code easily enough, and see the original I started from)
--------
package com.hu.Test;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager2;
// HU: jeez, I should have written this over a decade ago. Well, finally, here it is.
/**
* A border layout lays out a container, arranging and resizing
* its components to fit in five regions:
* north, south, east, west, and center.
*
* This modified version ALSO allows you to use the corners to hold other components. HU, Mar, 2016.
*
* Each region may contain no more than one component, and
* is identified by a corresponding constant:
*
NORTH
, SOUTH
, EAST
,*
WEST
, and CENTER
. When adding a* component to a container with a border layout, use one of these
* five constants, for example:
*
* Panel p = new Panel(); * p.setLayout(new BorderLayout()); * p.add(new Button("Okay"), BorderLayout.SOUTH); *
* As a convenience,
BorderLayout
interprets the* absence of a string specification the same as the constant
*
CENTER
:*
* Panel p2 = new Panel(); * p2.setLayout(new BorderLayout()); * p2.add(new TextArea()); // Same as p.add(new TextArea(), BorderLayout.CENTER); *
*
* NOTE: Currently (in the Java 2 platform v1.2),
*
BorderLayout
does not support vertical* orientations. The
isVertical
setting on the container's*
ComponentOrientation
is not respected.*
* The components are laid out according to their
* preferred sizes and the constraints of the container's size.
* The
NORTH
and SOUTH
components may* be stretched horizontally; the
EAST
and*
WEST
components may be stretched vertically;* the
CENTER
component may stretch both horizontally* and vertically to fill any space left over.
*
*
* @author Arthur van Hoff (original), Hyde University (corners)
* @see java.awt.Container#add(String, Component)
* @see java.awt.ComponentOrientation
* @see java.awt.BorderLayout
* @since JDK1.0
*/
public class BorderLayout implements LayoutManager2, java.io.Serializable {
/**
* Constructs a border layout with the horizontal gaps
* between components.
* The horizontal gap is specified by
hgap
.*
* @see #getHgap()
* @see #setHgap(int)
*
* @serial
*/
int hgap;
/**
* Constructs a border layout with the vertical gaps
* between components.
* The vertical gap is specified by
vgap
.*
* @see #getVgap()
* @see #setVgap(int)
* @serial
*/
int vgap;
/**
* Constant to specify components location to be the
* north portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component north;
/**
* Constant to specify components location to be the
* west portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component west;
/**
* Constant to specify components location to be the
* east portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component east;
/**
* Constant to specify components location to be the
* south portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component south;
/**
* Constant to specify components location to be the
* center portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component center;
Component northeast, southeast, northwest, southwest;
/**
* The north layout constraint (top of container).
*/
public static final String NORTH = "North";
/**
* The south layout constraint (bottom of container).
*/
public static final String SOUTH = "South";
/**
* The east layout constraint (right side of container).
*/
public static final String EAST = "East";
/**
* The west layout constraint (left side of container).
*/
public static final String WEST = "West";
/**
* The center layout constraint (middle of container).
*/
public static final String CENTER = "Center";
public static final String NORTHEAST = "Northeast";
public static final String NORTHWEST = "Northwest";
public static final String SOUTHEAST = "Southeast";
public static final String SOUTHWEST = "Southwest";
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -8658291919501921765L;
/**
* Constructs a new border layout with
* no gaps between components.
*/
public BorderLayout() {
this(0, 0);
}
/**
* Constructs a border layout with the specified gaps
* between components.
* The horizontal gap is specified by
hgap
* and the vertical gap is specified by
vgap
.* @param hgap the horizontal gap.
* @param vgap the vertical gap.
*/
public BorderLayout(int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
}
/**
* Returns the horizontal gap between components.
* @since JDK1.1
*/
public int getHgap() {
return hgap;
}
/**
* Sets the horizontal gap between components.
* @param hgap the horizontal gap between components
* @since JDK1.1
*/
public void setHgap(int hgap) {
this.hgap = hgap;
}
/**
* Returns the vertical gap between components.
* @since JDK1.1
*/
public int getVgap() {
return vgap;
}
/**
* Sets the vertical gap between components.
* @param vgap the vertical gap between components
* @since JDK1.1
*/
public void setVgap(int vgap) {
this.vgap = vgap;
}
/**
* Adds the specified component to the layout, using the specified
* constraint object. For border layouts, the constraint must be
* one of the following constants:
NORTH
,*
SOUTH
, EAST
,*
WEST
, or CENTER
,*
NORTHEAST
, NORTHWEST
,*
SOUTHEAST
, SOUTHWEST
*
* Most applications do not call this method directly. This method
* is called when a component is added to a container using the
*
Container.add
method with the same argument types.* @param comp the component to be added.
* @param constraints an object that specifies how and where
* the component is added to the layout.
* @see java.awt.Container#add(java.awt.Component, java.lang.Object)
* @exception IllegalArgumentException if the constraint object is not
* a string, or if it not one of the five specified
* constants.
* @since JDK1.1
*/
public void addLayoutComponent(Component comp, Object constraints) {
synchronized (comp.getTreeLock()) {
if ((constraints == null) || (constraints instanceof String)) {
addLayoutComponent((String)constraints, comp);
} else {
throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
}
}
}
/**
* @deprecated replaced by
addLayoutComponent(Component, Object)
.*/
@Deprecated
public void addLayoutComponent(String name, Component comp) {
synchronized (comp.getTreeLock()) {
/* Special case: treat null the same as "Center". */
if (name == null) {
name = "Center";
}
/* Assign the component to one of the known regions of the layout.
*/
if (CENTER.equals(name)) {
center = comp;
} else if (NORTH.equals(name)) {
north = comp;
} else if (SOUTH.equals(name)) {
south = comp;
} else if (EAST.equals(name)) {
east = comp;
} else if (WEST.equals(name)) {
west = comp;
} else if (NORTHEAST.equals(name)) {
northeast = comp;
} else if (SOUTHEAST.equals(name)) {
southeast = comp;
} else if (NORTHWEST.equals(name)) {
northwest = comp;
} else if (SOUTHWEST.equals(name)) {
southwest = comp;
} else {
throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
}
}
}
/**
* Removes the specified component from this border layout. This
* method is called when a container calls its
remove
or*
removeAll
methods. Most applications do not call this* method directly.
* @param comp the component to be removed.
* @see java.awt.Container#remove(java.awt.Component)
* @see java.awt.Container#removeAll()
*/
public void removeLayoutComponent(Component comp) {
synchronized (comp.getTreeLock()) {
if (comp == center) {
center = null;
} else if (comp == north) {
north = null;
} else if (comp == south) {
south = null;
} else if (comp == east) {
east = null;
} else if (comp == west) {
west = null;
} else if (comp == northeast) {
northeast = null;
} else if (comp == southeast) {
southeast = null;
} else if (comp == northwest) {
northwest = null;
} else if (comp == southwest) {
southwest = null;
}
}
}
/**
* Gets the component that was added using the given constraint
*
* @param constraints the desired constraint, one of
CENTER
,*
NORTH
, SOUTH
,*
WEST
, EAST
,*
NORTHEAST
, NORTHWEST
,*
SOUTHEAST
, SOUTHWEST
* @return the component at the given location, or
null
if* the location is empty
* @exception IllegalArgumentException if the constraint object is
* not one of the specified constants
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Component getLayoutComponent(Object constraints) {
if (CENTER.equals(constraints)) {
return center;
} else if (NORTH.equals(constraints)) {
return north;
} else if (SOUTH.equals(constraints)) {
return south;
} else if (WEST.equals(constraints)) {
return west;
} else if (EAST.equals(constraints)) {
return east;
} else if (NORTHEAST.equals(constraints)) {
return northeast;
} else if (SOUTHEAST.equals(constraints)) {
return southeast;
} else if (NORTHWEST.equals(constraints)) {
return northwest;
} else if (SOUTHWEST.equals(constraints)) {
return southwest;
} else {
throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints);
}
}
/**
* Returns the component that corresponds to the given constraint location.
*
* @param constraints the desired absolute position, one of
CENTER
,*
NORTH
, SOUTH
,*
EAST
, WEST
,*
NORTHEAST
, NORTHWEST
,*
SOUTHEAST
, SOUTHWEST
* @param target the {@code Container} used to obtain
* the constraint location based on the target
* {@code Container}'s component orientation.
* @return the component at the given location, or
null
if* the location is empty
* @exception IllegalArgumentException if the constraint object is
* not one of the specified constants
* @exception NullPointerException if the target parameter is null
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Component getLayoutComponent(Container target, Object constraints) {
//boolean ltr = target.getComponentOrientation().isLeftToRight();
Component result = null;
if (NORTH.equals(constraints)) {
result = north;
} else if (SOUTH.equals(constraints)) {
result = south;
} else if (WEST.equals(constraints)) {
result = west;
} else if (EAST.equals(constraints)) {
result = east;
} else if (NORTHEAST.equals(constraints)) {
result = northeast;
} else if (SOUTHEAST.equals(constraints)) {
result = southeast;
} else if (NORTHWEST.equals(constraints)) {
result = northwest;
} else if (SOUTHWEST.equals(constraints)) {
result = southwest;
} else if (CENTER.equals(constraints)) {
result = center;
} else {
throw new IllegalArgumentException("cannot get component: invalid constraint: " + constraints);
}
return result;
}
/**
* Gets the constraints for the specified component
*
* @param comp the component to be queried
* @return the constraint for the specified component,
* or null if component is null or is not present
* in this layout
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Object getConstraints(Component comp) {
//fix for 6242148 : API method java.awt.BorderLayout.getConstraints(null) should return null
if (comp == null){
return null;
}
if (comp == center) {
return CENTER;
} else if (comp == north) {
return NORTH;
} else if (comp == south) {
return SOUTH;
} else if (comp == west) {
return WEST;
} else if (comp == east) {
return EAST;
} else if (comp == northwest) {
return NORTHWEST;
} else if (comp == southwest) {
return SOUTHWEST;
} else if (comp == northwest) {
return NORTHWEST;
} else if (comp == southwest) {
return SOUTHWEST;
}
return null;
}
/**
* Determines the minimum size of the
target
container* using this layout manager.
*
* This method is called when a container calls its
*
getMinimumSize
method. Most applications do not call* this method directly.
* @param target the container in which to do the layout.
* @return the minimum dimensions needed to lay out the subcomponents
* of the specified container.
* @see java.awt.Container
* @see java.awt.BorderLayout#preferredLayoutSize
* @see java.awt.Container#getMinimumSize()
*/
public Dimension minimumLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
Dimension dim = new Dimension(0, 0);
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
if ((c=getChild(EAST,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(WEST,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(CENTER,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(NORTH,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
if ((c=getChild(SOUTH,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
if ((c=getChild(NORTHEAST,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width + hgap;
dim.height = d.height + vgap;
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.top + insets.bottom;
return dim;
}
}
/**
* Determines the preferred size of the
target
* container using this layout manager, based on the components
* in the container.
*
* Most applications do not call this method directly. This method
* is called when a container calls its
getPreferredSize
* method.
* @param target the container in which to do the layout.
* @return the preferred dimensions to lay out the subcomponents
* of the specified container.
* @see java.awt.Container
* @see java.awt.BorderLayout#minimumLayoutSize
* @see java.awt.Container#getPreferredSize()
*/
public Dimension preferredLayoutSize(Container target) {
synchronized (target.getTreeLock()) {
Dimension dim = new Dimension(0, 0);
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
if ((c=getChild(EAST,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(WEST,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(CENTER,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(NORTH,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
if ((c=getChild(SOUTH,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
if ((c=getChild(NORTHEAST,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width + hgap;
dim.height = d.height + vgap;
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.top + insets.bottom;
return dim;
}
}
/**
* Returns the maximum dimensions for this layout given the components
* in the specified target container.
* @param target the component which needs to be laid out
* @see Container
* @see #minimumLayoutSize
* @see #preferredLayoutSize
*/
public Dimension maximumLayoutSize(Container target) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
* Returns the alignment along the x axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentX(Container parent) {
return 0.5f;
}
/**
* Returns the alignment along the y axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentY(Container parent) {
return 0.5f;
}
/**
* Invalidates the layout, indicating that if the layout manager
* has cached information it should be discarded.
*/
public void invalidateLayout(Container target) {
}
/**
* Lays out the container argument using this border layout.
*
* This method actually reshapes the components in the specified
* container in order to satisfy the constraints of this
*
BorderLayout
object. The NORTH
* and
SOUTH
components, if any, are placed at* the top and bottom of the container, respectively. The
*
WEST
and EAST
components are* then placed on the left and right, respectively. Finally,
* the
CENTER
object is placed in any remaining* space in the middle.
*
* And the corners work as well, with NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST.
*
* Most applications do not call this method directly. This method
* is called when a container calls its
doLayout
method.* @param target the container in which to do the layout.
* @see java.awt.Container
* @see java.awt.Container#doLayout()
*/
public void layoutContainer(Container target) {
synchronized (target.getTreeLock()) {
Insets insets = target.getInsets();
int top = insets.top;
int bottom = target.getHeight() - insets.bottom;
int left = insets.left;
int right = target.getWidth() - insets.right;
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
// order is somewhat important in the original, because there was an implied ordering to what was going on, top->bottom, L->R
// now there's not.
// we have to manage all 8 edge pieces together.
Dimension zero = new Dimension(0, 0);
Dimension nw = northwest != null ? northwest.getPreferredSize() : zero;
Dimension no = north != null ? north.getPreferredSize() : zero;
Dimension ne = northeast != null ? northeast.getPreferredSize() : zero;
Dimension we = west != null ? west.getPreferredSize() : zero;
Dimension ea = east != null ? east.getPreferredSize() : zero;
Dimension sw = southwest != null ? southwest.getPreferredSize() : zero;
Dimension so = south != null ? south.getPreferredSize() : zero;
Dimension se = southeast != null ? southeast.getPreferredSize() : zero;
// boundary sizes.
int lwid = Math.max(Math.max(nw.width, we.width), sw.width);
int rwid = Math.max(Math.max(ne.width, ea.width), se.width);
int thei = Math.max(Math.max(nw.height, no.height), ne.height);
int bhei = Math.max(Math.max(sw.height, so.height), se.height);
// each of these methods resizes the widget: setSize, setBounds
if ((c=getChild(NORTH,ltr)) != null) {
c.setBounds(left+lwid, top, right - left - lwid - rwid, thei);
}
if ((c=getChild(SOUTH,ltr)) != null) {
c.setBounds(left+lwid, bottom - bhei, right - left - lwid - rwid, bhei);
}
if ((c=getChild(EAST,ltr)) != null) {
c.setBounds(right - rwid, top+thei, rwid, bottom - top - thei - bhei);
}
if ((c=getChild(WEST,ltr)) != null) {
c.setBounds(left, top+thei, lwid, bottom - top - thei - bhei);
}
if ((c=getChild(CENTER,ltr)) != null) {
c.setBounds(left + lwid, top + thei, right - left - rwid - lwid, bottom - top - thei - bhei);
}
if ((c=getChild(NORTHEAST,ltr)) != null) {
c.setBounds(right-rwid, top, rwid, thei);
}
if ((c=getChild(SOUTHEAST,ltr)) != null) {
c.setBounds(right-rwid, bottom - bhei, rwid, bhei);
}
if ((c=getChild(NORTHWEST,ltr)) != null) {
c.setBounds(left, top, lwid, thei);
}
if ((c=getChild(SOUTHWEST,ltr)) != null) {
c.setBounds(left, bottom-bhei, lwid, bhei);
}
}
}
/**
* Get the component that corresponds to the given constraint location
*
* @param key The desired absolute position,
* either NORTH, SOUTH, EAST, or WEST.
* Or NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST.
* @param ltr Is the component line direction left-to-right?
*/
private Component getChild(String key, boolean ltr) {
Component result = null;
if (key == NORTH) {
result = north;
}
else if (key == SOUTH) {
result = south;
}
else if (key == WEST) {
result = west;
}
else if (key == EAST) {
result = east;
}
else if (key == NORTHWEST) {
result = northwest;
}
else if (key == SOUTHWEST) {
result = southwest;
}
else if (key == NORTHEAST) {
result = northeast;
}
else if (key == SOUTHEAST) {
result = southeast;
}
else if (key == CENTER) {
result = center;
}
if (result != null && !result.isVisible()) {
result = null;
}
return result;
}
/**
* Returns a string representation of the state of this border layout.
* @return a string representation of this border layout.
*/
public String toString() {
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
}
}
--------------------
Here's the test case:
(There are four different approaches in here:)
package com.hu.Test;
//import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class BorderCorners {
public static void main(String[] args) {
JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints(0, 0, 2,2, 1.0, 1.0,
GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(
0, 0, 0, 0), 0, 0);
mainPanel.add(new JLabel("Left Upper"), gbc);
gbc.gridx = 2;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTHEAST;
mainPanel.add(new JLabel("Right Upper"), gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.SOUTHWEST;
mainPanel.add(new JLabel("Left Lower"), gbc);
gbc.gridx = 2;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.SOUTHEAST;
mainPanel.add(new JLabel("Right Lower"), gbc);
JFrame frame = new JFrame("Grid Bag Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
// well, this ends up in the middle all right, but it doesn't size up/down when you resize the frame.
JPanel centerPanel = new JPanel();
centerPanel.setBackground(Color.red);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.CENTER;
mainPanel.add(centerPanel, gbc);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
// ***********************
//yep, this misses the target too.
JPanel northPanel = new JPanel(new java.awt.BorderLayout());
northPanel.add(new JLabel("North East"), java.awt.BorderLayout.EAST);
northPanel.add(new JLabel("North West"), java.awt.BorderLayout.WEST);
JPanel southPanel = new JPanel(new java.awt.BorderLayout());
southPanel.add(new JLabel("South East"), java.awt.BorderLayout.EAST);
southPanel.add(new JLabel("South West"), java.awt.BorderLayout.WEST);
mainPanel = new JPanel(new java.awt.BorderLayout());
mainPanel.add(northPanel, java.awt.BorderLayout.NORTH);
mainPanel.add(southPanel, java.awt.BorderLayout.SOUTH);
centerPanel = new JPanel();
centerPanel.setBackground(Color.red);
mainPanel.add(centerPanel, java.awt.BorderLayout.CENTER);
JPanel left = new JPanel();
left.setBackground(Color.YELLOW);
mainPanel.add(left, java.awt.BorderLayout.WEST);
JPanel right = new JPanel();
right.setBackground(Color.GREEN);
mainPanel.add(right, java.awt.BorderLayout.EAST);
frame = new JFrame("AWT BorderLayout Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setLocationByPlatform(true);
frame.setSize(300, 300);
frame.setVisible(true);
// ***********************
System.out.println("trying now with a copy of border layout");
mainPanel = new JPanel(new BorderLayout());
JButton xx = new JButton("X");
System.out.println(xx.getInsets());
Insets xxi = xx.getInsets();
xxi.set(2, 2, 2, 2);
xx.setMargin(xxi);
//JLabel xx = new JLabel("X");
xx.setOpaque(true);
xx.setBackground(Color.MAGENTA);
xx.setForeground(Color.white);
mainPanel.add(xx, BorderLayout.NORTHEAST);
mainPanel.add(new JLabel("North W"), BorderLayout.NORTHWEST);
mainPanel.add(new JLabel("South East"), BorderLayout.SOUTHEAST);
mainPanel.add(new JLabel("South W"), BorderLayout.SOUTHWEST);
northPanel = new JPanel();
northPanel.setBackground(Color.PINK);
northPanel.add(new JLabel("N"));
mainPanel.add(northPanel, BorderLayout.NORTH);
southPanel = new JPanel();
southPanel.setBackground(Color.CYAN);
southPanel.add(new JLabel("S"));
mainPanel.add(southPanel, BorderLayout.SOUTH);
centerPanel = new JPanel();
centerPanel.setBackground(Color.red);
//mainPanel.add(centerPanel, BorderLayout.CENTER);
mainPanel.add(centerPanel);
left = new JPanel();
left.setBackground(Color.YELLOW);
left.add(new JLabel("W"));
mainPanel.add(left, BorderLayout.WEST);
right = new JPanel();
right.setBackground(Color.GREEN);
right.add(new JLabel("E"));
mainPanel.add(right, BorderLayout.EAST);
frame = new JFrame("NEW BorderLayout Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
frame.setSize(300, 300);
frame.setVisible(true);
// ***********************
// this isn't right either. but it's slightly better.
frame = new JFrame("Group L");
JLabel labelNW = new JLabel("NW");
JButton labelNE = new JButton("NE");
JLabel labelSW = new JLabel("SW");
JLabel labelSE = new JLabel("SE");
GroupLayout layout = new GroupLayout(frame.getContentPane());
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(labelNW)
.addComponent(labelSW))
.addGap(20,50,Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(Alignment.TRAILING)
.addComponent(labelNE)
.addComponent(labelSE))
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(Alignment.LEADING)
.addComponent(labelNW)
.addComponent(labelNE))
.addGap(20,50,Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(Alignment.TRAILING)
.addComponent(labelSW)
.addComponent(labelSE))
);
frame.getContentPane().setLayout(layout);
frame.getContentPane().setBackground(Color.LIGHT_GRAY);
frame.setSize(200, 200);
frame.setVisible(true);
}
}
No comments:
Post a Comment