2016-07-04 20 views
0

Ich kann nicht sehen, wie man ein JPanel mit SpringLayout richtig berechnen seine bevorzugte Größe, wie es derzeit immer (0, 0) ist. Ich habe versucht, panel.setPreferredSize(layout.preferredLayoutSize(panel)); zu nennen, aber es ändert nichts. Ich habe auch versucht, Constraints (im folgenden Code auskommentiert) an der Süd- und Ostseite des Panels im Vergleich zu Komponenten, die am weitesten südlich/östlich liegen, zu erstellen. Während ich anfange, mir die bevorzugte Größe zu geben, wird die GUI bei der Größenänderung von JFrame total durcheinander gebracht. zB verschieben sich einige Komponenten aus der Sicht, überlappen sich gegenseitig usw.).JPanel mit SpringLayout preferredSize berechnet nicht den richtigen Wert

Dies ist die Klasse, die mir Fragen schenkt:

public class TileView extends JPanel { 

    private TilesController controller; 

    private JRadioButton paint, select; 
    private JPanel prototype_panel, selection_panel; 

    public TileView (TilesController tiles_controller) { 
     controller = tiles_controller; 
     SpringLayout layout = new SpringLayout(); 
     setLayout(layout); 

     prototype_panel = new TileBrushPanel(controller); 
     selection_panel = new TileSelectionPanel(controller); 
     paint = new JRadioButton("draw"); 
     paint.addActionListener(l -> controller.setPaintTileMode()); 
     select = new JRadioButton ("select"); 
     select.addActionListener(l -> controller.setSelectMode()); 

     ButtonGroup bGroup = new ButtonGroup(); 
     bGroup.add(paint); 
     bGroup.add(select); 

     layout.putConstraint(NORTH, paint, 4, NORTH, this); 
     layout.putConstraint(WEST, paint, 4, WEST, this); 
     add (paint); 

     layout.putConstraint(NORTH, select, 0, NORTH, paint); 
     layout.putConstraint(WEST, select, 4, EAST, paint); 
     add (select); 

     layout.putConstraint(NORTH, prototype_panel, 4, NORTH, paint); 
     layout.putConstraint(WEST, prototype_panel, 4, WEST, this); 
     add (prototype_panel); 

     layout.putConstraint(NORTH, selection_panel, 0, NORTH, prototype_panel); 
     layout.putConstraint(WEST, selection_panel, 4, EAST, prototype_panel); 
     add (selection_panel); 

     //layout.putConstraint(SOUTH, this, 4, SOUTH, prototype_panel); 
     //layout.putConstraint(EAST, this, 0, EAST, selection_panel); 
     setPreferredSize(layout.preferredLayoutSize(this)); 

    } 

} 
+0

Was passiert, wenn Sie 'validate()' die Komponente oder 'pack()' das umschließende Fenster? – trashgod

+0

1) Für bessere Hilfe, früher, ein [MCVE] oder [kurze, selbständige, korrekte Beispiel] (http://www.sscce.org/). 2) Siehe [Sollte ich die Verwendung der festgelegten Methoden (Preferred | Maximum | Minimum) in Java Swing vermeiden?] (Http://stackoverflow.com/q/7229226/418556) (Ja.) –

Antwort

3

SpringLayout arbeitet gut. Du hattest es beim ersten Mal richtig gemacht; Sie sollten die letzten beiden putConstraint-Aufrufe auskommentieren und den Aufruf von setPreferredSize entfernen.

Der Grund, warum Sie nicht die Ergebnisse bekommen Sie erwarten, ist wahrscheinlich auf dieser Linie:

layout.putConstraint(NORTH, prototype_panel, 4, NORTH, paint); 

, die Sie wahrscheinlich schreiben bedeutete:

layout.putConstraint(NORTH, prototype_panel, 4, SOUTH, paint); 

Durch die Ausrichtung der Nordrand prototype_panel mit der Nordkante der Farbe, während Sie ihre beiden westlichen Kanten an den westlichen Rand des Containers ausrichten, haben Sie sie überlappen lassen.

SpringLayout ist schwierig zu verwenden. Meiner Meinung nach wäre es besser, ein anderes Layout oder eine Kombination von Layouts zu verwenden. Es ist nichts falsch daran, mehrere Panels ineinander zu verschachteln.

In Ihrem Fall, ich glaube, Sie das gleiche Layout mit Box-Instanzen erreicht haben könnten:

Box radioButtons = Box.createHorizontalBox(); 
radioButtons.add(paint); 
radioButtons.add(select); 

Box panels = Box.createHorizontalBox(); 
panels.add(prototype_panel); 
panels.add(selection_panel); 

Box windowContents = Box.createVerticalBox(); 
windowContents.add(radioButtons); 
windowContents.add(panels); 

setLayout(new BorderLayout()); 
add(windowContents); 

Es ist nicht viel kürzer, aber es ist wesentlich einfacher zu lesen und zu verstehen.

Aus Gründen, warum Sie eine Breite und Höhe von Null erhalten, kann ich nur vermuten, dass Sie die bevorzugte Größe ausdrucken, bevor die Validierung stattgefunden hat. Selbst wenn Sie Ihren SpringLayout-Code verwenden, habe ich nie eine Breite und Höhe von Null erhalten, nachdem ich das TileView-Panel zu einem JFrame hinzugefügt und es pack() genannt habe.