2016-05-04 7 views
0

Я пытаюсь показать сообщение JLabel сообщения под сеткой отображаемых квадратов (каждый квадрат - JLabel). Когда я не пытаюсь добавить сообщение в JPanel, сетка квадратов 4x4 будет отображаться просто отлично. Однако, когда я пытаюсь добавить сообщение JLabel ниже или выше сетки, происходит то, что сетка квадратов становится разделенной на две части (после первого столбца квадратов), так что один столбец квадратов отображается слева, а затем это пробел, а затем отображаются три других столбца квадратов. Появится сообщение внизу. Почему добавление этого сообщения приводит к тому, что сетка квадратов разбивается так? Я поставил свой код ниже. Спасибо заранее за любую помощь.GridBagLayout делать странные вещи при попытке добавить сообщение JLabel ниже сетки квадратов

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(); 
} 

ответ

0

Я думаю, вам нужно использовать отдельный GridBagConstraints объект - вы не можете использовать тот же экземпляр, как вы делаете выше.

+0

Вы имеете в виду GridBagConstraints? Я думал, что использование одного и того же экземпляра - это вся идея. Если вы используете два разных GridBagConstraints, вы не сможете сделать это так, чтобы они не мешали друг другу. – lb91

+0

Нет проблем с повторным использованием 'GridBagConstraints': https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html – Berger

+0

Хорошо, я уверен, что у меня были проблемы в прошлое с использованием того же объекта GridBagConstraints, но я готов признать, что я ошибаюсь. У вас очень понятные манипуляции с моделью ввода-вывода и Swing в одном и том же потоке в вашем коде - рассмотрите возможность использования SwingWorker для управления задачей ввода-вывода. Кроме того, у вас есть «c.gridy = i/4;» там, который выглядит как ошибка для меня - это по дизайну? – Lee

1

Вы добавляете свой instructionsLabel в первый столбец пятой строки после матрицы 4 * 4 от JLabel.

Проблема в том, что ваш instructionsLabel имеет большую длину, чем ваш squareLabels[i], поэтому поведение по умолчанию GridBagLayout будет простираться первый столбец, чтобы соответствовать instructionsLabel.

Вы должны установить gridWidth для вашего GridBagConstraints объекта c перед добавлением instructionsLabel:

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

Устанавливая constraint.gridwidth = 4; вы говорите менеджеру компоновки разместить instructionsLabel более чем в одной колонке. (Здесь я поставил exaclty 4 колонки.)

Добавление некоторых LineBorder к вашим JLabel с поможет вам понять поведение GridBagLayout и его Constraints лучше.

[UPDATE] Вы можете использовать BorderLayout в качестве основного макета, а затем добавьте JPanel с JLabel с и другими компонентами центра BorderLayout. Затем в этом JPanel используйте GridBagLayout. См. Этот пример:

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; 
    } 
} 

Удачи.

+0

Можете ли вы подробно рассказать? Я не понимаю, что вы здесь делаете. – lb91

+0

Спасибо. Я понимаю, почему вы это предложили. Я изменил значение ширины сетки, а сетка отображает 4x4. Однако сетка не отображается в центре JPanel (она находится слева от центра). Вы знаете, почему это может быть так и как переместить его в центр JPanel? – lb91

+0

См. Обновление для центрирования JLabels. Если этот ответ поможет вам пометить его как ответ. – STaefi