Search code examples
javaswinglayoutjpaneljdialog

JDialog - "line break" in between components


I have a JDialog that looks like this:

JDialog myDialog = new JDialog();

myDialog.setLocationRelativeTo(parent); 
// parent is a JPanel. 
// I want the Dialog to appear in the middle of the parent JPanel.

myDialog.setModal(true);
myDialog.setLayout(new FlowLayout());
myDialog.add(new JLabel("my text", SwingConstants.CENTER));
myDialog.add(new JButton("button 1"));
myDialog.add(new JButton("button 2"));
myDialog.pack();
myDialog.setVisible(true);

The result is a dialog where the JLabel and the JButtons appear next to each other.

1) What is the most convenient way make a "line break" after the JLabel, so that the JButtons appear below the JLabel, without using setSize()? I want the size to be automatically determined so the the components fit exactly, as is done by pack().

2) When I do set a custom size, the dialog appears where I want it: the middles of parent and myDialog match. However, if I use pack() instead, the top left corner of myDialog is at the middle of the parent. What is the best way to make the middles match instead?


Solution

    1. Nest JPanels, each using its own layout manager
    2. Call setLocationRelativeTo(parent) after calling pack(). You need to position the window after it has been rendered.

    For example:

    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.BorderLayout;
    import java.awt.Dialog.ModalityType;
    import java.awt.event.ActionEvent;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class SimpleGuiPanel extends JPanel {
        private static final String TITLE = "This is my Dialog Title";
    
        public SimpleGuiPanel() {
            JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
            titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, 16f));
    
            JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 5));
            buttonPanel.add(new JButton("Button 1"));
            buttonPanel.add(new JButton("Button 2"));
    
            setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            setLayout(new BorderLayout(5, 5));
            add(titleLabel, BorderLayout.PAGE_START);
            add(buttonPanel, BorderLayout.CENTER);
        }
    
        private static void createAndShowGui() {
            JPanel mainFramePanel = new JPanel();
            mainFramePanel.setPreferredSize(new Dimension(500, 400));
            final JFrame mainFrame = new JFrame("Main Frame");
            mainFrame.add(mainFramePanel);
            mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            SimpleGuiPanel simpleGuiPanel = new SimpleGuiPanel();
            final JDialog myDialog = new JDialog(mainFrame, "Dialog", ModalityType.APPLICATION_MODAL);
            myDialog.getContentPane().add(simpleGuiPanel);
            myDialog.pack();
    
            mainFramePanel.add(new JButton(new AbstractAction("Show Dialog") {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    myDialog.setLocationRelativeTo(mainFrame);
                    myDialog.setVisible(true);
                }
            }));
    
            mainFrame.pack();
            mainFrame.setLocationRelativeTo(null);
            mainFrame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> createAndShowGui());
        }
    }