2016-05-04 4 views
0

Ich versuche, eine JLabel einer Nachricht unter einem Raster von angezeigten Quadraten anzuzeigen (jedes Quadrat ist ein JLabel). Wenn ich nicht versuche, die Nachricht an die JPanel hinzuzufügen, zeigt das 4x4 Raster der Quadrate einfach gut. Wenn ich jedoch versuche, die Nachricht JLabel unter oder über dem Gitter hinzuzufügen, passiert, dass das Gitter der Quadrate in zwei geteilt wird (nach der ersten Spalte der Quadrate), so dass eine Spalte mit Quadraten auf der linken Seite angezeigt wird ist eine Lücke, und dann werden die anderen drei Spalten von Quadraten angezeigt. Die Nachricht wird darunter angezeigt. Warum führt das Hinzufügen dieser Nachricht dazu, dass sich das Gitter aus Quadraten so aufteilt? Ich habe meinen Code unten eingefügt. Vielen Dank im Voraus für jede Hilfe.GridBagLayout macht seltsame Dinge beim Versuch, eine Nachricht hinzuzufügen JLabel unter einem Raster von Quadraten

public void displayGrid(JButton button) { 

    JLabel instructionsLabel = new JLabel ("Select the locations of the four objects that you saw previously. Be careful - when you select one box, you can't take it back."); 

    try { 
     squareImage = ImageIO.read(this.getClass().getResource("stimulus(0).gif")); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    for(int i = 0; i < 16; i++){ 
     c.gridx = i % 4; 
     c.gridy = i/4; 
     squareLabels[i] = new JLabel(new ImageIcon(squareImage)); 
     panel.add(squareLabels[i], c); 
     squareLabels[i].addMouseListener(this); 
    } 

    panel.validate(); 

    c.gridy += 1; 
    c.gridx = 0; 
    panel.add(instructionsLabel, c); 
    panel.validate(); 
} 

Antwort

0

Ich glaube, Sie brauchen ein separates GridBagConstraints zu-Objekt verwenden - Sie können nicht die gleiche Instanz wiederverwenden, wie Sie oben tun.

+0

Meinst du GridBagConstraints? Ich dachte, mit der gleichen Instanz wäre die ganze Idee. Wenn Sie zwei verschiedene GridBagConstraints verwenden, können Sie es nicht so einrichten, dass sie sich nicht gegenseitig stören. – lb91

+0

Es gibt kein Problem mit der Wiederverwendung von 'GridBagConstraints': https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html – Berger

+0

Okay, ich bin ziemlich sicher, dass ich Probleme in der Vergangenheit mit dem gleichen GridBagConstraints-Objekt - aber ich bin bereit zu akzeptieren, dass ich falsch liege. Sie haben eine sehr klare IO- und Swing-Modellmanipulation für denselben Thread in Ihrem Code. Ziehen Sie in Erwägung, SwingWorker zu verwenden, um die IO-Task zu verwalten. Außerdem haben Sie 'c.gridy = i/4;' da drin, was für mich wie ein Käfer aussieht - ist das Absicht? – Lee

1

Sie fügen Ihre instructionsLabel in die erste Spalte der fünften Zeile, nach der 4 * 4-Matrix von JLabel s.

Das Problem ist, weil Ihre instructionsLabel eine größere Länge als Ihre squareLabels[i] hat, so dass das Standardverhalten von GridBagLayout würde die erste Spalte die instructionsLabel passen strecken.

Sie benötigen c die gridWidth für die Ihr GridBagConstraints Objekt zu setzen, bevor die instructionsLabel Zugabe:

c.gridy += 1; 
c.gridx = 0; 
constraint.gridwidth = 4; 
panel.add(instructionsLabel, c); 

Durch constraint.gridwidth = 4; Einstellung können Sie die Layout-Manager erzählen die instructionsLabel in mehr als einer Spalte zu platzieren. (Hier stelle ich exaclty 4 Spalten.)

einige LineBorder auf Ihre JLabel s Hinzufügen würden Sie das Verhalten von GridBagLayout und seine Constraints besser verstehen helfen.

[UPDATE] Sie können BorderLayout als Haupt Layout verwenden, und fügen Sie dann die JPanel mit JLabel s und anderen Komponenten zum Zentrum von BorderLayout. Dann verwenden Sie JPanelGridBagLayout. Siehe dieses Beispiel:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 

public class TestGridBagLAyout extends JFrame { 

    private static final long serialVersionUID = -392403850862179703L; 
    private static final int FRAME_WIDTH = 200; 
    private static final int FRAME_HEIGHT = 200; 

    public TestGridBagLAyout() { 
     setSize(FRAME_WIDTH, FRAME_HEIGHT); 
     // 
     setForeground(Color.RED); 
     // 
     setLayout(new BorderLayout()); 
     add(initCenterPanel()); 
    } 

    private JPanel initCenterPanel() { 
     GridBagLayout gridBagLayout = new GridBagLayout(); 
     JPanel centerPanel = new JPanel(gridBagLayout); 
     centerPanel.setBackground(Color.WHITE); 
     // 
     GridBagConstraints constraint = new GridBagConstraints(0, 0, 1, 1, 0d, 0d, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0); 
     // 
     JLabel[] squareLabels = new JLabel[16]; 
     for(int i = 0; i < 16; i++){ 
      constraint.gridx = i % 4; 
      constraint.gridy = i/4; 
      squareLabels[i] = new JLabel("Test"); 
      centerPanel.add(squareLabels[i], constraint); 
     } 
     // 
     JLabel instructionsLabel = new JLabel("This is long instruction!"); 
     constraint.gridy += 1; 
     constraint.gridx = 0; 
     constraint.gridwidth = 4; 
     centerPanel.add(instructionsLabel, constraint); 
     // 
     return centerPanel; 
    } 
} 

Viel Glück.

+0

Können Sie bitte erläutern? Ich verstehe nicht, was du hier machst. – lb91

+0

Danke. Ich verstehe, warum du das jetzt vorgeschlagen hast. Ich änderte den Wert der Rasterbreite, und das Raster zeigt 4x4 an. Das Raster wird jedoch nicht in der Mitte des JPanels angezeigt (es befindet sich links von der Mitte). Weißt du, warum dies der Fall ist und wie man es in die Mitte des JPanel bewegt? – lb91

+0

Siehe das Update zum Zentrieren der JLabels. Wenn diese Antwort Ihnen hilft, können Sie sie als Antwort markieren. – STaefi

Verwandte Themen