Можно ли динамически добавлять компоненты в группы в GroupLayout?
Можно Component
быть добавлены в группы в GroupLayout
динамически, после setHorizontalGroup()
а такжеsetVerticalGroup()
были вызваны без сброса макета? Я работаю над графическим интерфейсом для проекта, который поможет студентам найти лучший способ составить расписание занятий на неделю. Это включает ввод информации о времени занятий и т. Д. Для неизвестного количества классов. Конечно, я не могу просто добавить сколь угодно большое количество форм, чтобы пользователь мог поместить информацию и сказать: "Никто не может рассматривать больше, чем это количество классов", поэтому пользователь должен иметь возможность добавлять новые формы в их собственный. Я могу создавать формы, но не могу найти способ успешно добавить их в GroupLayout
в окне без повторного вызова setHorizontalGroup(...)
или же setVerticalGroup(...)
, которые пишут поверх предыдущего Group
с, а не добавить к ним. Это релевантная часть кода, который у меня есть (прокомментирован для разборчивости):
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
в GroupLayout
или даже поле, относящееся к тем Group
с, в этом отношении. Я в полной растерянности относительно того, что делать здесь. Я хочу избежать изучения нового типа Layout
если это вообще возможно, но я начинаю бояться, что мне придется (или, что еще хуже, то, что я пытаюсь сделать, с самого начала невозможно).
1 ответ
Как показано здесь, вы можете использовать этот подход:
- Сначала создайте необходимый
ParallelGroup
а такжеSequentialGroup
, - Позже добавьте нужные группы и компоненты, представляющие новую строку.
В приведенном ниже примере add()
добавляет новую метку и текстовое поле к макету. AdjustmentListener
, предлагается здесь, прокрутка до последней добавленной строки.
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://stackru.com/a/41926375/230513
* @see https://stackru.com/a/14858272/230513
* @see https://stackru.com/a/8504753/230513
* @see https://stackru.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);
}
});
}
}