2017-01-29 4 views
-1

Может ли Component s быть добавлен к группам в GroupLayout динамически, после того, как setHorizontalGroup() и setVerticalGroup() были вызваны, не перезагружая компоновку? Я работаю над графическим интерфейсом проекта, который поможет студентам найти лучший способ составить свои недельные расписания занятий. Это предполагает ввод информации о времени класса и т. Д. Для неизвестного количества классов. Конечно, я не могу просто добавить произвольно большое количество форм для того, чтобы пользователь мог ввести информацию и сказать «никто не может рассматривать больше, чем это число классов», поэтому пользователь должен иметь возможность добавлять новые формы на их. Я могу создать формы, но я не могу найти способ успешно добавить их в GroupLayout в окне без повторного вызова setHorizontalGroup(...) или setVerticalGroup(...), которые записывают за предыдущие Group s, а не добавляют к ним. Это соответствующая часть кода я в настоящее время (комментировал для удобочитаемости):Можно добавить компоненты в группы в GroupLayout динамически?

private static void createAndShowGUI() { 
    //Create window and assign an empty GroupLayout to it 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    GroupLayout layout = new GroupLayout(frame.getContentPane()); 
    frame.getContentPane().setLayout(layout); 

    /*WeekPanel extends JPanel, and is the "form" the user enters data into. 
    In essence, it's a JPanel with a series of JTextFields.*/ 
    WeekPanel panel1 = new WeekPanel(); 
    WeekPanel panel2 = new WeekPanel(); 

    //The layout code below places two WeekPanels in the window, one on top of the other 
    layout.setHorizontalGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup() 
        .addComponent(panel1) 
        .addComponent(panel2))); 
    layout.setVerticalGroup(layout.createSequentialGroup() 
      .addComponent(panel1) 
      .addComponent(panel2)); 

    /*I would like to add a component to the layout here as proof of concept.*/ 
    frame.pack(); 
    frame.setVisible(true); 
} 

Я попытался назвать frame.add([some component]) как раз перед frame.pack(), но он никогда не делает никакой видимой разницы. Я просмотрел официальную документацию для GroupLayout, и я не вижу возможности доступа или изменения горизонтального/вертикального Group s в GroupLayout или даже поля, ссылающегося на те Group s, если на то пошло. У меня полная потеря относительно того, что делать здесь. Я хочу избежать изучения нового типа Layout, если это вообще возможно, но я начинаю опасаться, что мне придется (или, что еще хуже, то, что я пытаюсь сделать, с чего начать) ,

+0

* «Это включает в себя ввод информации о времени класса, и т.д. для неизвестного числа классов.» * Похоже, работа для 'JTable'. * «Я хочу избежать изучения нового типа« Макет », если это вообще возможно». Необходимо иметь рабочие знания о нескольких макетах, а также о том, как их объединить, прежде чем, скорее всего, вы добьетесь успеха завершить любое нетривиальное приложение на основе графического интерфейса. (Даже если основная часть информации отображается в 'JTable'.) –

ответ

2

Как показано here, вы можете использовать этот подход:

  1. Первое, создать необходимый ParallelGroup и SequentialGroup.
  2. Позже добавьте нужные группы и компоненты, представляющие новую строку.

В приведенном ниже примере add() добавляет новую метку и текстовое поле в макет. AdjustmentListener, предложенный here, прокручивает до последней добавленной строки.

image

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.AdjustmentEvent; 
import javax.swing.AbstractAction; 
import javax.swing.GroupLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextField; 

/** 
* @see https://stackoverflow.com/a/41926375/230513 
* @see https://stackoverflow.com/a/14858272/230513 
* @see https://stackoverflow.com/a/8504753/230513 
* @see https://stackoverflow.com/a/14011536/230513 
*/ 
public class DynamicGroupLayout { 

    private static final int NUM = 6; 
    private GroupLayout layout; 
    private GroupLayout.ParallelGroup parallel; 
    private GroupLayout.SequentialGroup sequential; 
    private int i; 

    private JPanel create() { 
     JPanel panel = new JPanel(); 
     layout = new GroupLayout(panel); 
     panel.setLayout(layout); 
     layout.setAutoCreateGaps(true); 
     layout.setAutoCreateContainerGaps(true); 
     parallel = layout.createParallelGroup(); 
     layout.setHorizontalGroup(layout.createSequentialGroup().addGroup(parallel)); 
     sequential = layout.createSequentialGroup(); 
     layout.setVerticalGroup(sequential); 
     for (int i = 0; i < NUM; i++) { 
      add(); 
     } 
     return panel; 
    } 

    private void add() { 
     JLabel label = new JLabel(String.valueOf(i + 1), JLabel.RIGHT); 
     JTextField field = new JTextField(String.valueOf("String " + (i + 1))); 
     label.setLabelFor(field); 
     parallel.addGroup(layout.createSequentialGroup(). 
      addComponent(label).addComponent(field)); 
     sequential.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE). 
      addComponent(label).addComponent(field)); 
     i++; 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame f = new JFrame("DynamicGroupLayout"); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       final DynamicGroupLayout dgl = new DynamicGroupLayout(); 
       final JPanel panel = dgl.create(); 
       JScrollPane jsp = new JScrollPane(panel) { 
        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(320, 240); 
        } 
       }; 
       jsp.getVerticalScrollBar().addAdjustmentListener((AdjustmentEvent e) -> { 
        e.getAdjustable().setValue(e.getAdjustable().getMaximum()); 
       }); 
       f.add(jsp); 
       JPanel controls = new JPanel(); 
       controls.add(new JButton(new AbstractAction("Add") { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         dgl.add(); 
         panel.validate(); 
        } 
       })); 
       f.add(controls, BorderLayout.SOUTH); 
       f.pack(); 
       f.setLocationRelativeTo(null); 
       f.setVisible(true); 
      } 
     }); 
    } 
}