The primary GUI of my application is composed of a JDesktopPane at the CENTER of a frame's content pane using a BorderLayout. I am hoping to have a component placed in the top right of the screen that still allows the user to drag JInternalFrames within the space to the left and and bottom of this component.
Setting the component to the NORTH or EAST of the BorderLayout seems to fill the entire space. I am thinking BorderLayout may not be the best layout manager for what I am trying to accomplish? Any suggestions on a better approach?
Check out the OverlayLayout
. It allows you to stack components on top of one another.
You need to manipulate the setAlignmentX(..)
and setAlignmentY(...)` methods to get the layout you want. It is not always intuitive how these alignments work together but setting the component to the top/left is relatively easy.
Here is a little demo for you to play with:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class OverlayLayoutTest extends JPanel
implements ActionListener
{
JPanel green;
JPanel red;
JLabel greenLabel;
JLabel redLabel;
JComboBox greenAlignmentX;
JComboBox greenAlignmentY;
JComboBox redAlignmentX;
JComboBox redAlignmentY;
public OverlayLayoutTest()
{
setLayout( new BorderLayout(10, 10) );
add(createNorthPanel(), BorderLayout.NORTH);
add(createCenterPanel(), BorderLayout.CENTER);
add(createSouthPanel(), BorderLayout.SOUTH);
}
private JPanel createNorthPanel()
{
JPanel panel = new JPanel();
panel.add( new JLabel("Green:") );
greenLabel = new JLabel();
panel.add( greenLabel );
panel.add( new JLabel("Red:") );
redLabel = new JLabel();
panel.add( redLabel );
return panel;
}
private JPanel createCenterPanel()
{
JPanel panel = new JPanel();
panel.setLayout( new OverlayLayout(panel) );
panel.setBackground( Color.ORANGE );
panel.setPreferredSize( new Dimension(200, 200) );
red = new JPanel();
red.setBackground( Color.RED );
red.setPreferredSize( new Dimension(50, 50) );
red.setMaximumSize( red.getPreferredSize() );
red.setMinimumSize( red.getPreferredSize() );
panel.add( red );
green = new JPanel();
green.setBackground( Color.GREEN );
green.setPreferredSize( new Dimension(100, 100) );
green.setMaximumSize( green.getPreferredSize() );
green.setMinimumSize( green.getPreferredSize() );
panel.add( green );
JPanel wrap = new JPanel();
wrap.add( panel );
return wrap;
}
private JPanel createSouthPanel()
{
JPanel panel = new JPanel( new GridLayout(1, 0, 10, 10) );
JPanel green = new JPanel(new GridLayout(0, 2, 5, 5) );
green.setBorder( new TitledBorder("Green Alignment") );
green.add( new JLabel("X Alignment:") );
greenAlignmentX = createComboBox();
green.add( greenAlignmentX );
green.add( new JLabel("Y Alignment:") );
greenAlignmentY = createComboBox();
green.add( greenAlignmentY );
panel.add( green );
JPanel red = new JPanel(new GridLayout(0, 2, 5, 5) );
red.setBorder( new TitledBorder("Red Alignment") );
red.add( new JLabel("X Alignment:") );
redAlignmentX = createComboBox();
red.add( redAlignmentX );
red.add( new JLabel("Y Alignment:") );
redAlignmentY = createComboBox();
red.add( redAlignmentY );
panel.add( red );
JButton reset = new JButton("Reset Alignment");
reset.addActionListener( this );
panel.add( reset );
return panel;
}
public void actionPerformed(ActionEvent e)
{
green.setAlignmentX( ((Float)greenAlignmentX.getSelectedItem()) );
green.setAlignmentY( ((Float)greenAlignmentY.getSelectedItem()) );
red.setAlignmentX( ((Float)redAlignmentX.getSelectedItem()) );
red.setAlignmentY( ((Float)redAlignmentY.getSelectedItem()) );
JPanel parent = (JPanel)green.getParent();
parent.revalidate();
/*
System.out.print(green.getAlignmentX() + " : ");
System.out.print(green.getAlignmentY() + " : ");
System.out.print(red.getAlignmentX() + " : ");
System.out.print(red.getAlignmentY() + " : ");
System.out.println();
*/
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
greenLabel.setText( green.getLocation().toString() );
redLabel.setText( red.getLocation().toString() );
}
});
}
private JComboBox createComboBox()
{
JComboBox<Float> comboBox = new JComboBox<Float>();
comboBox.addItem( new Float(0f) );
comboBox.addItem( new Float(0.25f) );
comboBox.addItem( new Float(0.5f) );
comboBox.addItem( new Float(0.75f) );
comboBox.addItem( new Float(1.0f) );
comboBox.setSelectedItem(0.5f);
return comboBox;
}
private static void createAndShowUI()
{
JFrame frame = new JFrame("OverlayLayoutTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new OverlayLayoutTest() );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
- set the alignment X values to 1.0 for both components
- set the alignment Y values to 0.0 for both components
and you should get the layout you want.
Edit:
Missed the part about dragging a JInternalFrame. So this imples you are using a JDesktopPane to support the dragging. A JDesktopPane uses a null layout to allow you to drag components around.
There is no reason you can't add another component (other than a JInternalFrame) to the desktop. You just need to set the size/location of this component to be displayed at the top right of the desktop. You would then need to add a ComponentListener
to the desktop pane to listen for the componentResized
event. When this event is fired you would need to recalucate the location of the component to reset it to the top right.