问题
Can Component
s be added to groups in GroupLayout
dynamically, after setHorizontalGroup()
andsetVerticalGroup()
have been called, without resetting the layout? I'm working on the GUI to a project that will help students find the best way to put together their weekly class schedules. This involves inputting information regarding class times, etc., for an unknown number of classes. Of course, I can't just add an arbitrarily large number of forms for the user to put information into and say "no one could be considering more than this number of classes", so the user needs to be able to add new forms on their own. I can create the forms, but I can't find any way to successfully add them to the GroupLayout
in the window without re-calling setHorizontalGroup(...)
or setVerticalGroup(...)
, which write over the previous Group
s rather than add to them.
This is the relevant portion of the code I currently have (commented for legibility):
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);
}
I've tried calling frame.add([some component])
just before frame.pack()
, but it never makes any visible difference. I've looked at the official documentation for GroupLayout, and I see no way of accessing or altering the horizontal/vertical Group
s in GroupLayout
, or even a field referring to those Group
s, for that matter.
I'm at a complete loss as to what to do here. I want to avoid learning a new type of Layout
if at all possible, but I'm starting to fear that I'm going to have to (or, even worse, that what I'm trying to do is impossible to begin with).
回答1:
As shown here, you can use this approach:
- First, create the required
ParallelGroup
andSequentialGroup
. - Later, add the desired groups and components representing a new row.
In the example below, add()
appends a new label and text field to the layout. An AdjustmentListener
, suggested here, scrolls to the last added row.
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);
}
});
}
}
来源:https://stackoverflow.com/questions/41924962/can-components-be-added-to-groups-in-grouplayout-dynamically