Search code examples
javaswingjpaneljdialoggrouplayout

Resize JDialog with JPanel and GroupLayout manager


I have JDialog which have one JPanel with GroupLayout manager. I have following code:

Create JDialog:

DialogPanel rectangeDialog = new DialogPanel(clickedObject);
rectangeDialog.addWindowListener(new WindowAdapter() {
    @Override
    public void windowLostFocus(WindowEvent e) {
        MainFrame.closeDialog(rectangeDialog.getModul());
    }

    @Override
    public void windowClosing(WindowEvent e) {
        MainFrame.closeDialog(rectangeDialog.getModul());
    }
 });

Constructor (DialogPanel extends JDialog):

private static final int DIALOG_HEIGHT = 550;
private static final int DIALOG_WIDTH = 1050;

private RectangleModul modul = new RectangleModul();
private static final ImageIcon deleteIcon = createImageIcon("../resource/images/delete.gif");

    //Label-а за пътя и подравняване вдясно
    private JLabel idTxt = new JLabel();
    //Input полето за път на квадратчето
    private JTextField id = new JTextField(JTextField.RIGHT);
    //Label-а за пътя и подравняване вдясно
    private JLabel pathTxt = new JLabel();
    //Input полето за път на квадратчето
    private JTextField path = new JTextField(JTextField.LEFT);
    //Label-а за ниво и подравняване вдясно
    private JLabel levelTxt = new JLabel();
    //Input полето за ниво на квадратчето
    private JTextField level = new JTextField();
    //Label-а за име на квадратчето
    private JLabel appellationTxt = new JLabel();
    //Input полето за име на квадратчето
    private JTextField appellation = new JTextField();
    //Полето съдържащо описанието на квадрадтчето
    private JTextArea description = new JTextArea();
    //Таблицата с елемите с дежав
    private JTable childrenTable;
public DialogPanel(RectangleModul modul) {
        super(null, java.awt.Dialog.ModalityType.TOOLKIT_MODAL);

        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

        //data initialization...

        createDialogContent();

    }

And creating dialog content:

private void createDialogContent() {
    JPanel panel = new JPanel();
    //Панелът, който съдържа елемните
    panel.setSize(DIALOG_WIDTH + 10, DIALOG_HEIGHT + 10);
    panel.setAutoscrolls(false);
    panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    //Layout на групите в панела
    GroupLayout layout = new GroupLayout(panel);

    //Вклюване на задаването на разстояния между елементите
    layout.setAutoCreateGaps(true);
    layout.setAutoCreateContainerGaps(true);
    panel.setLayout(layout);

    //Area-та за описанието на квадратчето
    Border insideDescriptionBorder = BorderFactory.createTitledBorder("Описание");
    //ScrollBar-ът да полето за описание на квадратчето
    JScrollPane scrollArea = new JScrollPane(description);
    scrollArea.getVerticalScrollBar().setUnitIncrement(16);
    scrollArea.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    scrollArea.setBorder(insideDescriptionBorder);

    JScrollPane childrenTableScrollPane = new JScrollPane(childrenTable);
    childrenTableScrollPane.getVerticalScrollBar().setUnitIncrement(16);
    childrenTableScrollPane.setMaximumSize(new Dimension(20, 100));
    childrenTableScrollPane.setMinimumSize(new Dimension(20, 100));
    childrenTableScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);

    //Панелът, който съдържа бутоните на диалоговия прозорец
    JPanel panelButtons = new JPanel();
    panelButtons.setMaximumSize(new Dimension(20, 100));

    //Бутонът за запазване
    JButton saveBtn = new JButton("Запази");

    saveBtn.addActionListener((ActionEvent e) -> {
        //...
    });
    panelButtons.add(saveBtn);

    //Бутонът за създаване на ново дете
    JButton addChildBtn = new JButton("Ново дете");
    addChildBtn.addActionListener((ActionEvent e) -> {
        RectangleModul newModul = new RectangleModul(modul.getLevel() + 1, "Нов елемент", "", modul, new ArrayList<>(), new Polygon());
        addChild(newModul);

        DialogPanel newDialogPanel = new DialogPanel(newModul);
        newDialogPanel.setDefaultCloseOperation(DialogPanel.DISPOSE_ON_CLOSE);
        newDialogPanel.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                //...
            }
        });
        newDialogPanel.setVisible(true);
        MainFrame.getOpenPanels().add(newDialogPanel);
    });
    panelButtons.add(addChildBtn);

    //Бутонът за изтриване на елемнта и неговите деца
    JButton deleteBtn = new JButton(modul.getLevel() == 0 ? "Изчисти проект" : "Изтрий");
    deleteBtn.addActionListener((ActionEvent e) -> {
        //...
    });
    panelButtons.add(deleteBtn);
    panelButtons.setLayout(new FlowLayout(FlowLayout.LEFT));
    panelButtons.setSize(310, 10);

    layout.setHonorsVisibility(true);
    //Хозиронталното подравняване на елемнтите в Layout-а
    layout.setHorizontalGroup(layout.createSequentialGroup()/*.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)*/
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(scrollArea, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
                    .addComponent(childrenTable.getTableHeader(), GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
                    .addComponent(childrenTableScrollPane, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                            .addComponent(pathTxt)
                                    )
                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                            .addComponent(path, 100, 100, 100)
                                    )
                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                                            .addGroup(layout.createSequentialGroup()
                                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                                            .addComponent(idTxt)
                                                    )
                                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                                            .addComponent(id, 50, 50, 50)
                                                    )
                                            )
                                    )
                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                                            .addGroup(layout.createSequentialGroup()
                                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                                                            .addComponent(levelTxt)
                                                    )
                                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                                                            .addComponent(level, 50, 50, 50)
                                                    )
                                            )
                                    )
                            )
                    )
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                            .addComponent(appellationTxt)
                                    )
                                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                            .addComponent(appellation, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
                                    )
                            )
                    )
                    .addComponent(panelButtons, 310, 310, 310)
            )
    );
    //Задане на panelButtons, levelTxt, id и level да са с константна ширина
    layout.linkSize(SwingConstants.HORIZONTAL, levelTxt, level, id);

    //Вертикално подравняване на елемнтите в Layout-а
    layout.setVerticalGroup(layout.createSequentialGroup().addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(idTxt)
                    .addComponent(id, 25, 25, 25)
                    .addComponent(pathTxt)
                    .addComponent(path, 25, 25, 25)
                    .addComponent(levelTxt)
                    .addComponent(level, 25, 25, 25)
            )
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(appellationTxt)
                    .addComponent(appellation, 25, 25, 25)
            )
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(scrollArea)
            )
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(childrenTable.getTableHeader())
            )
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(childrenTableScrollPane, 100, 100, 100)
            )
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(panelButtons, 35, 35, 35)
            )
    );

    //Задаване на panelButtons да е с константна височина
    layout.linkSize(SwingConstants.VERTICAL, childrenTableScrollPane);

    add(panel);

    //Диалоговите прозорци не са модални с цел да може да се виждат по няколко едновременно
    setModal(false);
    //Името на диалоговия прозотец ще бъде пътя до квадратчето и неговото име
    setTitle(String.format("%s%s%s - %s", modul.getPath(), modul.getPath().length() > 0 ? "." : "", modul.getId(), modul.getName()));
    setMinimumSize(new Dimension(DIALOG_WIDTH, DIALOG_HEIGHT));
    setPreferredSize(new Dimension(DIALOG_WIDTH, DIALOG_HEIGHT));
    //Локализиране на диалогът в горната част на основния прозорец в центъра. Взема се спрямо позицията на root елемента
    setLocation(MainFrame.getRoot().getPolygon().xpoints[0] + RectangleModul.BODY_WIDTH / 2 - getWidth() / 2, MainFrame.getRoot().getPolygon().ypoints[0]);
}

That is dialog: enter image description here

When I increase the width everything is OK and components fit the width.

enter image description here

But when I decreased the width component don't decreased their width. I don't want scroll bar. I want component fit of dialog window width(below is unwanted result. It has to be like first image).

enter image description here


Solution

  • I don't know is this real answer but it is better answer to be sandpapered from question!

    I solved by problem by changing the Layout Manager. I change GroupLayout with GridBagLayout.

    Here is new code:

    GridBagLayout gridBagLayout = new GridBagLayout();
            panel.setLayout(gridBagLayout);
    
            gridBagLayout.rowHeights = new int[]{40, 40, 190, 190, 50};
            gridBagLayout.columnWidths = new int[]{40, 50, 70, 70, 700, 70, 50};
    
            panel.add(idTxt, newComponent(0, 0, 1, 1));
    
            panel.add(id, newComponent(1, 0, 1, 1));
    
            panel.add(pathTxt, newComponent(2, 0, 1, 1));
    
            panel.add(path, newComponent(3, 0, 1, 1));
    
            panel.add(new JLabel(""), newComponent(4, 0, 1, 1));
    
            panel.add(levelTxt, newComponent(5, 0, 1, 1));
    
            panel.add(level, newComponent(6, 0, 1, 1));
    
            panel.add(appellationTxt, newComponent(0, 1, 1, 1));
    
            panel.add(appellation, newComponent(1, 1, 6, 1));
    
            panel.add(scrollAreaDesc, newComponent(0, 2, 7, 1));
    
            panel.add(childrenTableScrollPane, newComponent(0, 3, 7, 1));
    
            panel.add(panelButtons, newComponent(0, 4, 6, 1));
    

    And newComponent:

    private GridBagConstraints newComponent(int x, int y, int w, int h) {
            GridBagConstraints c = new GridBagConstraints();
            c.fill = y != 2 && y != 3 ? GridBagConstraints.HORIZONTAL : GridBagConstraints.BOTH;
            c.gridx = x;
            c.gridy = y;
            c.gridwidth = w;
            c.gridheight = h;
            if (y == 2 || y == 3) {
                c.weighty = 1.0;
            }
            if (x <=4 && (x + w) >=4) {
                c.weightx = 1.0;
            }
            return c;
        }
    

    Thanks to MadProgrammer about idea to change the layout manager!