Can Components be added to groups in GroupLayout dynamically?

萝らか妹 提交于 2019-12-25 08:27:42

问题


Can Components 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 Groups 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 Groups in GroupLayout, or even a field referring to those Groups, 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:

  1. First, create the required ParallelGroup and SequentialGroup.
  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!