Re: Multiple Lines with a FlowLayout within a SOUTH region in a BorderLayout
phi wrote:
Hi
My Problem is, that I want to have a my Buttons in the SOUTH in a
Border Layout.
I looked at this some more. I don't think FlowLayout returns a good
result for BorderLayout, at least for the outer panels. Problem is,
FlowLayout, if you look at the code, only calculates a preferred size
which does not take into account the width of the parent container. The
preferred size of a FlowLayout is always a single row.
This is kinda weird, and not what BorderLayout is really expecting. So
I adapted a new preferredSize method from the actual layoutContainer
code. It seems to work.
This code below is pasted from my IDE, then edited a bit. I hope it all
still compiles. If not, post and ask me for the whole thing (which is
rather messy).
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package test;
import java.awt.*;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
/**
*
* @author Brenden
*/
public class TestLayout
{
public static void main( String[] args )
{
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
buildAndShowGui();
}
} );
}
private static void buildAndShowGui()
{
top();
}
static void top()
{
JFrame jf = new JFrame( "Multiple Lines in the South" );
jf.add( new JLabel( "center" ) );
// JPanel mainPanel = makeMainPanel();
// jf.add(mainPanel);
jf.add( makeSouthPanel(), BorderLayout.SOUTH );
jf.setSize( 300, 300 );
jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
jf.setVisible( true );
}
static JPanel makeMainPanel()
{
JPanel mainPanel = new JPanel();
mainPanel.setLayout( new BorderLayout() );
populateMainPanel( mainPanel );
return mainPanel;
}
static JPanel makeSouthPanel()
{
JPanel southPanel = new JPanel();
southPanel.setLayout( new LayoutInspector() );
//southPanel.setLayout(null); // which to use here?
populateMultiLinePanel( southPanel );
return southPanel;
}
static JPanel makeMultiLinePanel()
{
JPanel mzp = new JPanel();
mzp.setLayout( new LayoutInspector() );
populateMultiLinePanel( mzp );
return mzp;
}
static void populateMultiLinePanel( Container mzp )
{
mzp.add( new JButton( "Hello" ) );
mzp.add( new JButton( "World" ) );
mzp.add( new JButton( "OK" ) );
mzp.add( new JButton( "Cancel" ) );
}
}
class LayoutInspector
extends FlowLayout
{
private static Logger log =
Logger.getAnonymousLogger();
static
{
ConsoleHandler ch = new ConsoleHandler();
ch.setLevel( Level.ALL );
log.addHandler( ch );
log.setLevel( Level.ALL );
log.setUseParentHandlers( false );
}
public void addLayoutComponent( String name, Component comp )
{
log.entering( "FlowLayout", "addLayoutComponent",
new Object[]
{
name, comp
} );
// throw new UnsupportedOperationException( "Not supported yet." );
super.addLayoutComponent( name, comp );
log.exiting( "FlowLayout", "addLayoutComponent" );
}
public void removeLayoutComponent( Component comp )
{
log.entering( "FlowLayout", "removeLayoutComponent",
new Object[]
{
comp
} );
// throw new UnsupportedOperationException( "Not supported yet." );
super.removeLayoutComponent( comp );
log.exiting( "FlowLayout", "removeLayoutComponent" );
throw new UnsupportedOperationException( "Not supported yet." );
}
public Dimension preferredLayoutSize( Container parent )
{
log.entering( "FlowLayout", "preferredLayoutSize",
new Object[] { parent } );
// throw new UnsupportedOperationException( "Not supported yet." );
// Dimension rt =
// super.preferredLayoutSize( parent );
// log.finest( "Dimenions="+rt);
Insets insets = parent.getInsets();
int maxwidth = parent.getWidth() - (insets.left + insets.right +
super.getHgap() * 2);
int ourMaxwidth = 0;
int nmembers = parent.getComponentCount();
int x = 0, y = insets.top + super.getVgap();
int rowh = 0, start = 0;
boolean ltr = parent.getComponentOrientation().isLeftToRight();
boolean useBaseline = getAlignOnBaseline();
int[] ascent = null;
int[] descent = null;
if( useBaseline )
{
ascent = new int[nmembers];
descent = new int[nmembers];
}
for( int i = 0; i < nmembers; i++ )
{
Component m = parent.getComponent( i );
if( m.isVisible() )
{
Dimension d = m.getPreferredSize();
m.setSize( d.width, d.height );
if( useBaseline )
{
int baseline = m.getBaseline( d.width, d.height );
if( baseline >= 0 )
{
ascent[i] = baseline;
descent[i] = d.height - baseline;
} else
{
ascent[i] = -1;
}
}
if( (x == 0) || ((x + d.width) <= maxwidth) )
{
if( x > 0 )
{
x += super.getHgap();
}
x += d.width;
rowh = Math.max( rowh, d.height );
} else
{
// rowh = moveComponents( parent, insets.left + hgap, y,
// maxwidth - x, rowh, start, i, ltr,
// useBaseline, ascent, descent );
ourMaxwidth = Math.max( ourMaxwidth, x );
x = d.width;
y += super.getVgap() + rowh;
rowh = d.height;
start = i;
}
}
}
// moveComponents( parent, insets.left + hgap, y, maxwidth - x, //rowh,
// start, nmembers, ltr, useBaseline, ascent, descent );
ourMaxwidth = Math.max( ourMaxwidth, x );
Dimension rt = new Dimension( ourMaxwidth, y+rowh );
log.finest( "Dimenions="+rt);
log.exiting( "FlowLayout", "preferredLayoutSize" );
return rt;
}
public Dimension minimumLayoutSize( Container parent )
{
log.entering( "FlowLayout", "minimumLayoutSize",
new Object[]
{
parent
} );
// throw new UnsupportedOperationException( "Not supported yet." );
Dimension rt =
super.minimumLayoutSize( parent );
log.finest( "Dimenions=" + rt );
log.exiting( "FlowLayout", "minimumLayoutSize" );
return rt;
}
public void layoutContainer( Container parent )
{
log.entering( "FlowLayout", "layoutContainer",
new Object[]
{
parent
} );
// throw new UnsupportedOperationException( "Not supported yet." );
super.layoutContainer( parent );
log.exiting( "FlowLayout", "layoutContainer" );
}
}