PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Java/Swing] GridBagLayout resized ungerecht


Senior Sanchez
2006-10-30, 23:55:54
Hi,

Ich habe momentan ein blödes Problem mit dem GridBagLayout.
Es besteht aus sieben Spalten in die entsprechende Panels eingefügt werden können, die alle dieselbe preferredSize haben. Weiterhin besitzen sämtliche Panels die reingehangen werden das gleiche resizing-Behavior (GridBagConstraints.BOTH, weightx 1.0, weighty 1.0) und sollten demzufolge den verfügbaren Platz gerecht untereinander aufteilen.

Doch das passiert nicht.
Füge ich ein Panel in die erste Spalte ein nimmt sich das mehr als die preferedSize. Füge ich dann ein weiteres Panel in eine andere Spalte ein, so ist dieses Panel wesentlich schmaler als das zuletzt eingefügte. Doch das möchte ich ja nicht.

Hat jemand ne Ahnung was ich dagegen tun kann?

Monger
2006-10-31, 08:28:35
Mit dem GridBagLayout habe ich mich auch regelmäßig rumgeärgert. Für meinen Geschmack muss ich da viel zu viel rumparametrieren um zu brauchbaren Ergebnissen zu kommen...

Hast du mal über andere LayoutManager nachgedacht? Was spricht denn z.B. gegen GridLayout? Das teilt den verfügbaren Platz unter allen Komponenten zu gleichen Teilen auf.

mithrandir
2006-10-31, 08:40:29
Wo hast du denn GridBagLayout verwendet? Wenn der Container mit dem GBL selbst in einem anderen Layout liegt, gibt's evtl. schon mal Probleme beim resizen. Allerdings scheint bei mir das "Verteilen" beim Resizen einigermassen gut zu funktionieren (nur bei fill BOTH wird auf die minimum, preferred und maximum Size eh geschi**en):

public class Test extends JFrame implements ActionListener
{
protected static final int MAX_COMPONENTS = 32;
protected List compList = new Vector( MAX_COMPONENTS );
protected GridBagConstraints gbc = new GridBagConstraints();
protected JPanel gblPanel = new JPanel( new GridBagLayout() );
protected JPanel btPanel = new JPanel( new FlowLayout() );
protected JButton btAddLabel = new JButton( "Add Label" );
protected JTextField txtGridX = new JTextField( "1" );
protected JTextField txtGridY = new JTextField( "1" );
protected JTextField txtWeightXY = new JTextField( "1" );

public Test()
{
super( "Test" );

Container pane = this.getContentPane();

// Komponenten erstellen:
JComponent comp = null;
Dimension min = new Dimension( 125, 50 );
Dimension pref = new Dimension( 250, 100 );
Dimension max = new Dimension( 500, 200 );
for ( int i = 1; i <= MainWindow.MAX_COMPONENTS; i++ )
{
comp = new JPanel();
((JPanel) comp).setBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(),
"Component # " + i ) );
comp.setOpaque( true );
comp.setBackground( new Color( 150 + i * 3, 150 - i * 4, 250 - i * 6 ) );
comp.setMinimumSize( min );
comp.setPreferredSize( pref );
comp.setMinimumSize( max );

this.compList.add( comp );
}

this.gblPanel.setBackground( Color.WHITE );

this.btAddLabel.setActionCommand( "addLabel" );
this.btAddLabel.addActionListener( this );
this.txtGridX.setColumns( 3 );
this.txtGridY.setColumns( 3 );
this.txtWeightXY.setColumns( 3 );

this.btPanel.add( new JLabel( " X: " ) );
this.btPanel.add( this.txtGridX );
this.btPanel.add( new JLabel( " Y: " ) );
this.btPanel.add( this.txtGridY );
this.btPanel.add( new JLabel( " Weight: " ) );
this.btPanel.add( this.txtWeightXY );
this.btPanel.add( new JLabel( " " ) );
this.btPanel.add( this.btAddLabel );

pane.add( this.gblPanel, BorderLayout.CENTER );
pane.add( this.btPanel, BorderLayout.SOUTH );

this.setSize( 700, 500 );

this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}

public static void main( String[] args )
{
new Test().setVisible( true );
}

public void actionPerformed( ActionEvent e )
{
String command = e.getActionCommand();

if ( "addLabel".equals( command ) )
{
if ( this.compList.isEmpty() )
return;

// Label einfuegen. Folgende Constraints aus
// den GUI-Komponenten auslesen:
// gridx, gridy, weightx, weighty
try
{
this.gbc.gridx = Integer.parseInt( this.txtGridX.getText() );
}
catch( NumberFormatException nfex )
{
nfex.printStackTrace();
}

try
{
this.gbc.gridy = Integer.parseInt( this.txtGridY.getText() );
}
catch( NumberFormatException nfex )
{
nfex.printStackTrace();
}

try
{
double d = Double.parseDouble( this.txtWeightXY.getText() );
this.gbc.weightx = d;
this.gbc.weighty = d;
}
catch( NumberFormatException nfex )
{
nfex.printStackTrace();
}

this.gbc.fill = GridBagConstraints.BOTH;

JComponent comp = (JComponent) this.compList.remove( 0 );

this.gblPanel.add( comp, this.gbc );

this.gblPanel.revalidate();
}
}
}

Senior Sanchez
2006-10-31, 09:47:17
Vielen Dank, ich habe den Fehler gefunden.

Meine Panels, die ich reinhänge enthalten eine JTextArea in die Text eingefügt wird. Habe ich LineWrap aktiviert, so stellt er das erste Panel groß dar, aber beim zweiten stellt er fest, dass er ja einfach umbrechen kann und das Panel somit nicht soviel Platz in der Breite braucht. Deaktiviere ich LineWrap, haben alle Panels die gleiche Größe.

GridLayout scheidet aus, weil ich wirklich unterschiedlich große Zellen brauche. Ich habe ein Panel, dass einen Stundenplan darstellt und die einzelnen Zellen stellen dann Veranstaltungen dar. Um das gut hinzubekommen habe ich mich gegen eine Tabelle, aber dafür für ein GridBagLayout entschieden, dass für mich auch das resizen übernimmt. Außerdem brauche ich keine spezifischen CellRenderer und Editoren schreiben, weil ich in das große Panel ja jede Komponenten reinhangen kann wie ich lustig bin.

Ich habe das ganze jetzt übrigens so gemacht, dass ich bei den JTextArea den LineWrap deaktiviert habe und das ganze in eine JScrollPane gehangen habe.