Search code examples
javaswingjlabeljdialog

Is there a way to open multiple instances of modeless JDialog in java swing without disabling its components?


I have a GUI which consist of a JLabel named "View":

https://i.sstatic.net/FKwF5.png

with a mouseClickEvent attached to it. Upon clicking on the "View" JLabel, i can open multiple instances of a modeless JDialog.

The JDialog itself consist of several disabled JTextFields and a JLabel with a mouseClickEvent attached to it which act as a "Close" button:

https://i.sstatic.net/vZEbm.png

However upon opening more than one JDialog, the "close" JLabel is disabled and the mouseClickEvent does not work anymore.

Here is my code:

private void viewDoctorClickedEvent(java.awt.event.MouseEvent evt) 
{                                        
        javax.swing.JFrame topFrame = (javax.swing.JFrame) 
        javax.swing.SwingUtilities.getWindowAncestor(this);
        viewDoctorDialog = new javax.swing.JDialog(topFrame, "View Doctor Details", false);
        
        viewDoctorDialog.setMinimumSize(new java.awt.Dimension(580, 350));
        viewDoctorDialog.setResizable(false);
        
        viewDoctorDialog.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
        viewDoctorDialog.setLocationRelativeTo(topFrame);

        // This part is used to collect the values from the selected row of a Jtable and set the 
        // values to the disabled JTextFields in the JDialog
        try
        {
            int selectedTableRow = doctorListTB.getSelectedRow();

            String doctorName = doctorListTB.getValueAt(selectedTableRow, 0).toString();
            String doctorEmail = doctorListTB.getValueAt(selectedTableRow, 1).toString();
            String doctorPassword = doctorListTB.getValueAt(selectedTableRow, 2).toString();
            String doctorAddress = doctorListTB.getValueAt(selectedTableRow, 3).toString();
            String doctorPhone = doctorListTB.getValueAt(selectedTableRow, 4).toString();
            String doctorDepartment = doctorListTB.getValueAt(selectedTableRow, 5).toString();

            viewDoctorNameTF.setText(doctorName);
            viewDoctorEmailTF.setText(doctorEmail);
            viewDoctorPasswordTF.setText(doctorPassword);
            viewDoctorAddressTF.setText(doctorAddress);
            viewDoctorPhoneTF.setText(doctorPhone);
            viewDoctorDepartmentTF.setText(doctorDepartment);
            
            viewDoctorDialog.add(viewDoctorDialogPanel);
            viewDoctorDialog.setVisible(true);
        }
        catch(Exception e)
        {
            javax.swing.JOptionPane.showMessageDialog(viewDoctorDialogPanel, "Please select a row to view.", "No data to view.", javax.swing.JOptionPane.ERROR_MESSAGE);
        }
    }
    
    // Mouse Click Event to close the JDialog upon clicking on the "close" JLabel
    private void closeViewButtonClickedEvent(java.awt.event.MouseEvent evt) 
    {                                             
          viewDoctorDialog.dispose();
    }

Is there a way to open multiple instances while still retaining the mouseClickEvent of the "close" JLabel in each opened instance of the JDialog?


Solution

  • The JDialog itself consist of several disabled JTextFields and a JLabel with a mouseClickEvent attached to it which act as a "close" button.

    Why would use use a JLabel with a MouseListener to close the dialog? A JLabel was not designed to do processing like this.

    Use a JButton with an ActionListener for the "Close" functionality.

    If you want the button to look like a label then you can use:

    button.setBorderPainted( false );
    

    the mouseClickEvent does not work anymore.

    viewDoctorDialog = new javax.swing.JDialog(topFrame, "View Doctor Details", false);
        
    

    It looks to me like you have an instance variable to track the open dialog. When you create the second dialog, you change the reference of the variable to point to the second dialog so you no longer have a reference to the original dialog.

    So when using JButton, as suggested above, the code in your ActionListener for the "Close" button would then be something like:

    Jbutton button = (JButton)event.getSource();
    Window window = SwingUtilities.windowForComponent( button );
    window.dispose();
    

    So you don't even need a special variable to track the dialog.

    Your "View Doctor Detials" dialog should be defined in a separate class. All the variables needed for that class should be defined in that class, not your main class that displays the dialog. So when you create an instance of the class you would pass in the JTable.

    This will make it easier to structure your code so that each class only contains ActionListeners that are relevant to the class. So the main class will contain listeners to display the child dialogs. The child dialogs will have listener to "Close" the dialogs.