Issue Details (XML | Word | Printable)

Key: QUAQUA-166
Type: Bug Bug
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: trejkaz
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
quaqua

JSheet parented by the wrong window

Created: 17/Dec/13 05:23 AM   Updated: 17/Dec/13 05:35 AM
Component/s: None
Affects Version/s: current
Fix Version/s: None

Time Tracking:
Not Specified

Tags:
Participants: trejkaz


 Description  « Hide

When a JSheet is being displayed from a child dialog, for some reason, the sheet is displayed with the top-level frame as the parent.

Sample program below demonstrates the issue.

import java.awt.Dialog;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;

import ch.randelshofer.quaqua.JSheet;
import ch.randelshofer.quaqua.QuaquaLookAndFeel;
import ch.randelshofer.quaqua.SheetEvent;
import ch.randelshofer.quaqua.SheetListener;
import ch.randelshofer.quaqua.subset.Quaqua16LionFileChooserLAF;

public class QuaquaSheetParentTest implements Runnable
{
    public static void main(String[] args)
    {
        try
        {
            UIManager.setLookAndFeel(new QuaquaFileChooserOnlyLookAndFeel());
        }
        catch (Exception e)
        {
            throw new RuntimeException(e);
        }

        SwingUtilities.invokeLater(new QuaquaSheetParentTest());
    }

    @Override
    public void run()
    {
        final JFrame frame = new JFrame("Main");
        JButton button = new JButton("Open Dialog");

        button.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent event)
            {
                openDialog(frame);
            }
        });

        frame.setLayout(new FlowLayout());
        frame.add(button);
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private void openDialog(Window parent)
    {
        final JDialog dialog = new JDialog(parent, Dialog.ModalityType.DOCUMENT_MODAL);
        JButton button = new JButton("Open Sheet");

        button.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent event)
            {
                openSheet(dialog);
            }
        });

        dialog.setLayout(new FlowLayout());
        dialog.add(button);
        dialog.setSize(500, 300);
        dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        dialog.setLocationRelativeTo(parent);
        dialog.setVisible(true);
    }

    private void openSheet(Window parent)
    {
        JSheet.showOpenSheet(new JFileChooser(), parent, new SheetListener()
        {
            @Override
            public void optionSelected(SheetEvent sheetEvent)
            {

            }
        });
    }

    private static class QuaquaFileChooserOnlyLookAndFeel extends QuaquaLookAndFeel
    {
        private QuaquaFileChooserOnlyLookAndFeel()
        {
            setTarget(new Quaqua16LionFileChooserLAF());
        }
    }

}


trejkaz added a comment - 17/Dec/13 05:35 AM

Proposed patch:

Index: src/ch/randelshofer/quaqua/JSheet.java
===================================================================
--- src/ch/randelshofer/quaqua/JSheet.java	(revision 460)
+++ src/ch/randelshofer/quaqua/JSheet.java	(working copy)
@@ -1007,15 +1007,27 @@
         }
     }
 
-    private static JSheet createSheet(final JOptionPane pane, Component parentComponent,
-            int style) {
-        Window window = getWindowForComponent(parentComponent);
+    /**
+     * Calls the appropriate constructor depending on whether the parent is a frame or a dialog.
+     * Can remove this method once a sufficiently recent JRE can be assumed.
+     *
+     * @param window the parent window.
+     * @return the sheet.
+     */
+    private static JSheet createSheet(Window window) {
         final JSheet sheet;
         if (window instanceof Frame) {
             sheet = new JSheet((Frame) window);
         } else {
             sheet = new JSheet((Dialog) window);
         }
+        return sheet;
+    }
+    
+    private static JSheet createSheet(final JOptionPane pane, Component parentComponent,
+            int style) {
+        Window window = getWindowForComponent(parentComponent);
+        final JSheet sheet = createSheet(window);
 
         JComponent contentPane = (JComponent) sheet.getContentPane();
         contentPane.setLayout(new BorderLayout());
@@ -1151,13 +1163,11 @@
         }
 
         // Begin Create Dialog
-        Frame frame = parent instanceof Frame ? (Frame) parent
-                : (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parent);
-
         String title = chooser.getUI().getDialogTitle(chooser);
         chooser.getAccessibleContext().setAccessibleDescription(title);
 
-        final JSheet sheet = new JSheet(frame);
+        Window parentWindow = getWindowForComponent(parent);
+        final JSheet sheet = createSheet(parentWindow);
         sheet.addSheetListener(listener);
 
         Container contentPane = sheet.getContentPane();