Search code examples
javaswingjdialog

How to close JDialog and save the setting ?


Hi I'm working on a program and I faced a problem when I choose some settings from JDialog then click "ok", which is that the setting didn't save but come back to the original settings.

PS : I'm not English speaker so maybe you observe some mistakes in my text above.

picture enter image description here

class DrawingSettingWindow extends JDialog {


    public DrawingSettingWindow() {

        this.setTitle("Drawing Setting Window");
        this.setSize(550, 550);
        this.setLocationRelativeTo(null);

        this.setModal(true);

        this.setLayout(new GridLayout(4, 1));

        JLabel selectColorText = new JLabel("Select Drawing Color");

        colorsList = new JComboBox(colors);
        JPanel panel1 = new JPanel();
        panel1.add(selectColorText);
        panel1.add(colorsList);
        add(panel1);

        JLabel selectStyleText = new JLabel("Select Drawing Style");
        JPanel panel2 = new JPanel();

        normal = new JRadioButton("Normal");
        normal.setSelected(true);
        filled = new JRadioButton("Filled");
        ButtonGroup bg = new ButtonGroup();

        bg.add(normal);
        bg.add(filled);
        panel2.add(selectStyleText);
        panel2.add(normal);
        panel2.add(filled);
        add(panel2);

        JButton ok = new JButton("OK");

        add(ok);

        ok.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                setVisible(false);
            }
        });




        this.pack();
        this.setVisible(true);

    }

Solution

  • The information is there, you just have to extract it from the dialog after the user is done using it. I would give the code above at least two new methods, one a public getColor() method that returns colorsList.getSelectedItem();, the color selection of the user (I'm not sure what type of object this is, so I can't show the method yet). Also another one that gets the user's filled setting, perhaps

    public boolean getFilled() {
        return filled.isSelected();
    }
    

    Since the dialog is modal, you'll know that the user has finished using it immediately after you set it visible in the calling code. And this is where you call the above methods to extract the data.

    In the code below, I've shown this in this section: drawingSettings.setVisible(true);

            // here you extract the data
            Object color = drawingSettings.getColor();
            boolean filled = drawingSettings.getFilled();
            textArea.append("Color: " + color + "\n");
            textArea.append("Filled: " + filled + "\n");                
        }
    

    For example (see comments):

    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    import java.awt.Window;
    import java.awt.Dialog.ModalityType;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class UseDrawingSettings extends JPanel {
        private JTextArea textArea = new JTextArea(20, 40);
        private DrawingSettingWindow drawingSettings;
    
        public UseDrawingSettings() {
            JPanel topPanel = new JPanel();
            topPanel.add(new JButton(new ShowDrawSettings()));
            setLayout(new BorderLayout());
    
            add(new JScrollPane(textArea));
            add(topPanel, BorderLayout.PAGE_START);
        }
    
        private class ShowDrawSettings extends AbstractAction {
            public ShowDrawSettings() {
                super("Get Drawing Settings");
            }
    
            @Override
            public void actionPerformed(ActionEvent e) {
                if (drawingSettings == null) {
                    Window win = SwingUtilities.getWindowAncestor(UseDrawingSettings.this);
                    drawingSettings = new DrawingSettingWindow(win);
                }
                drawingSettings.setVisible(true);
    
                // here you extract the data
                Object color = drawingSettings.getColor();
                boolean filled = drawingSettings.getFilled();
                textArea.append("Color: " + color + "\n");
                textArea.append("Filled: " + filled + "\n");                
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> createAndShowGui());
        }
    
        private static void createAndShowGui() {
            UseDrawingSettings mainPanel = new UseDrawingSettings();
            JFrame frame = new JFrame("UseDrawingSettings");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    }
    

    @SuppressWarnings("serial")
    class DrawingSettingWindow extends JDialog {
    
        private static final String TITLE = "Drawing Setting Window";
        private JComboBox<String> colorsList;
        private JRadioButton normal;
        private JRadioButton filled;
    
        // not sure what colors is, but I'll make it a String array for testing
        private String[] colors = {"Red", "Orange", "Yellow", "Green", "Blue"};
    
    
        public DrawingSettingWindow(Window win) {
            super(win, TITLE, ModalityType.APPLICATION_MODAL);
            // this.setTitle("Drawing Setting Window");
            this.setSize(550, 550); // !! this is not recommended
            this.setLocationRelativeTo(null);
    
            this.setModal(true);
    
            this.setLayout(new GridLayout(4, 1));
    
            JLabel selectColorText = new JLabel("Select Drawing Color");
    
            colorsList = new JComboBox(colors);
            JPanel panel1 = new JPanel();
            panel1.add(selectColorText);
            panel1.add(colorsList);
            add(panel1);
    
            JLabel selectStyleText = new JLabel("Select Drawing Style");
            JPanel panel2 = new JPanel();
    
            normal = new JRadioButton("Normal");
            normal.setSelected(true);
            filled = new JRadioButton("Filled");
            ButtonGroup bg = new ButtonGroup();
    
            bg.add(normal);
            bg.add(filled);
            panel2.add(selectStyleText);
            panel2.add(normal);
            panel2.add(filled);
            add(panel2);
    
            JButton ok = new JButton("OK");
    
            add(ok);
    
            ok.addActionListener(new ActionListener() {
    
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                }
            });
    
            this.pack();
            // this.setVisible(true); // this should be the calling code's responsibility
    
        }
    
        public Object getColor() {
            return colorsList.getSelectedItem();
        }
    
        public boolean getFilled() {
            return filled.isSelected();
        }
    
        public static void main(String[] args) {
            JFrame frame = new JFrame("Foo");
        }
    }
    

    Side notes:

    • I've changed your class's constructor to accept a Window parameter, the base class for JFrame, JDialog, and such, and have added a call to the super's constructor. This way, the dialog is a true child window of the calling code (or you can pass in null if you want it not to be).
    • I recommend not making the dialog visible within its constructor. It is the calling code's responsibility for doing this, and there are instances where the calling code will wish to not make the dialog visible after creating it, for example if it wanted to attach a PropertyChangeListener to it before making it visible. This is most important for modal dialogs, but is just good programming practice.
    • I didn't know the type of objects held by your combo box, and so made an array of String for demonstration purposes.