Modality of popups not respected by externalized dockable. App permanently locked

Hey Beni. I’m hoping you can help with this one I ran into this week. Basically, consider a button exists on a dockable that launches a modal popup. If the dockable is not externalized, the modal popup is open, and a user clicks on the dockable the input is ignored because of the modality. However, externalize that same dockable. Then launch the popup. Click behind the popup on the dockable and it will come forward, obscuring the modal popup if they are at the same location. If the dockable is larger than the popup, your application is now locked awaiting input on a modal dialog that cannot be accessed.

Check out the example below to see this in action. To see the bug, tear off dockable 2. Then click the LAUNCH POPUP button on the dockable. This was tested with java 6 and 7 on RHEL 6 with DockingFrames Preview Version 1.1.2 17b.

{
  public Test3()
  {
    super();
    setMinimumSize(new Dimension(500,500));
    CControl control = new CControl(this);

    add(control.getContentArea(), BorderLayout.CENTER);
    control.setGroupBehavior(new TopMostGroupBehavior());
    control.putProperty(StackDockStation.TAB_PLACEMENT,
                        TabPlacement.TOP_OF_DOCKABLE);

    CPerspective layout =
      control.getPerspectives().createEmptyPerspective();
    CGridPerspective center = layout.getContentArea().getCenter();
    Path path = new Path("custom", "flightlist");

    center.gridPlaceholder(0, 0, 1, 1, path);
    control.getPerspectives().setPerspective(layout, true);
    PlaceholderGrouping group = new PlaceholderGrouping(control, path);

    JPanel panel1 = new JPanel();
  
    DefaultSingleCDockable dockable =
      new DefaultSingleCDockable("1", null, "1", panel1, null);

    CLocation location;
    if (control.getCDockableCount() > 0)
    {
      location =
        control.getCDockable(control.getCDockableCount() -
                             1).getBaseLocation();
    }
    else
    {
      location = control.getDefaultLocation();
    }

    dockable.setCloseable(false);
    dockable.setMaximizable(false);
    dockable.setMinimizable(false);
    dockable.setTitleShown(false);
    dockable.setGrouping(group);
    dockable.setSingleTabShown(true);
    dockable.setLocation(location);
    control.addDockable(dockable);

    dockable.setVisible(true);

    JPanel panel2 = new JPanel();
    JButton button = new JButton("LAUNCH POPUP");
    button.addActionListener(new ActionListener(){
      @Override
      public void actionPerformed(ActionEvent actionEvent)
      {
        Window parentWindow = (Window)SwingUtilities.getRoot((JButton)actionEvent.getSource());
        JDialog popup = new JDialog(parentWindow, Dialog.ModalityType.APPLICATION_MODAL);
        popup.setMinimumSize(new Dimension(200,200));
        popup.pack();
        popup.setLocationRelativeTo(parentWindow);
        popup.setVisible(true);
      }
    });
    
    panel2.add(button);

    DefaultSingleCDockable dockable2 =
      new DefaultSingleCDockable("2", null, "2", panel2, null);

    CLocation location2;
    if (control.getCDockableCount() > 0)
    {
      location2 =
        control.getCDockable(control.getCDockableCount() -
                             1).getBaseLocation();
    }
    else
    {
      location2 = control.getDefaultLocation();
    }

    dockable2.setCloseable(false);
    dockable2.setMaximizable(false);
    dockable2.setMinimizable(false);
    dockable2.setTitleShown(false);
    dockable2.setGrouping(group);
    dockable2.setSingleTabShown(true);
    dockable2.setLocation(location2);
    control.addDockable(dockable2);

    dockable2.setVisible(true);
    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        pack();
        setVisible(true);
      }
    });
  }
  
  public static void main(String[] args)
  {
    new Test3();
  }
}```

Thanks for your help!

Uh, I was unable to reproduce this issue. I tried 1.7 and 1.8 on Ubuntu.

Hm, I suggest…

  • try 1.8
  • ensure using Oracle-Java, and not one of the open source JVMs

In any case, DockingFrames does not do anything “evil” with modal dialogs (at least not in my understanding of dialogs). The externalized Dockables are shown on JDialogs that are MODELESS, and the main-JFrame is not modified by DockingFrames.

Can you reproduce the bug with an application that works without DockingFrames? If you can, than I really cannot help - and otherwise I would not have any idea where to start searching for the bug.

Thanks for the quick reply. I am using the official oracle JRE/JDKs. I did as you suggested and tried with 1.8, same result. I also mocked up a test where a JFrame launches a JDialog, which launches another modal JDialog to see if the issue exists without DockingFrames, and it does not. All behaves as expected. To demonstrate this issue I have captured my screen. First, I demo the bug with the code sample from my original post. You can see at 22s into the video my modal popup is dropped to the back when i click on the externalized dockable. From that point forward I can’t take any action on the parent dialogs, can’t even move the externalized dockable to get back to the popup awaiting input.

At 40s I run the purely java test, launching a JFrame with a child JDialog, which then launches its own child JDialog. No action on either parent window pushes the top-most modal dialog to the back. Also, I am still allowed to move the parents in the background in case somehow the top-most JDialog was incorrectly obscured I can still get to it.

[video=youtube_share;_1-sw0QLCAs]https://youtu.be/_1-sw0QLCAs[/video]

Here is the code for my purely java comparison

{
  public Test4()
  {
    super();
    setMinimumSize(new Dimension(500,500));
    
    JButton button = new JButton("LAUNCH POPUP");
    button.addActionListener(new ActionListener(){
      @Override
      public void actionPerformed(ActionEvent actionEvent)
      {
        Window parentWindow = (Window)SwingUtilities.getRoot((JButton)actionEvent.getSource());
        JDialog popup = new JDialog(parentWindow, Dialog.ModalityType.APPLICATION_MODAL);
        JButton button2 = new JButton("LAUNCH POPUP 2");
        button2.addActionListener(new ActionListener(){
          @Override
          public void actionPerformed(ActionEvent actionEvent)
          {
            Window parentWindow = (Window)SwingUtilities.getRoot((JButton)actionEvent.getSource());
            JDialog popup = new JDialog(parentWindow, Dialog.ModalityType.APPLICATION_MODAL);
            popup.setMinimumSize(new Dimension(200,200));
            popup.pack();
            popup.setLocationRelativeTo(parentWindow);
            popup.setVisible(true);
          }
        });
        popup.getContentPane().add(button2);
        popup.setMinimumSize(new Dimension(200,200));
        popup.pack();
        popup.setLocationRelativeTo(parentWindow);
        popup.setVisible(true);
      }
    });
    
    getContentPane().add(button);
    
    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        pack();
        setVisible(true);
      }
    });
  }
  
  public static void main(String[] args)
  {
    new Test4();
  }
}```

Sorry, I was not around during the weekend.

Really strange, and I have no explanation at all. I’ll try to reproduce the issue, but I do not have much hope. I probably need to setup a VM for a RHEL, hm, that might need some time. Please don’t expect any solution in the next few days.


One idea though, how about using the JFrame as parent window for the Dialog? I did not try, but I thought that a modal dialog disables all the other windows, so it should not matter which window is the parent.

Pfff, my Redhat account got immediately flagged as “bad” (well, I may have did input some random data in the phone-number and address field…). So no Redhat for me :-/

Edit: yay, randomly changing “my” companies name resolved the issue…