How to generate a stand-alone JFileChooser dialog box on top of other windows?

不打扰是莪最后的温柔 提交于 2019-12-04 18:09:35

Firstly, you could create your own dialog and use setAlwaysOnTop to bring the window to the top of the window z-order. This is OS specific so it might not work on all OSes...

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
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.UnsupportedLookAndFeelException;

public class FileChooser {

    public static void main(String[] args) {
        new FileChooser();
    }
    private int state = JFileChooser.ERROR_OPTION;

    public FileChooser() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFileChooser chooser = new JFileChooser();
                chooser.addPropertyChangeListener(new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        System.out.println(evt.getPropertyName());
                    }
                });
                chooser.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (JFileChooser.CANCEL_SELECTION.equals(e.getActionCommand())) {
                            state = JFileChooser.CANCEL_OPTION;
                            SwingUtilities.windowForComponent((JFileChooser) e.getSource()).dispose();
                        } else if (JFileChooser.APPROVE_SELECTION.equals(e.getActionCommand())) {
                            state = JFileChooser.APPROVE_OPTION;
                            SwingUtilities.windowForComponent((JFileChooser) e.getSource()).dispose();
                        }
                    }
                });
                JDialog dialog = new JDialog();
                dialog.setAlwaysOnTop(true);
                dialog.setTitle("Open it sucker");
                dialog.setModal(true);
                dialog.add(chooser);
                dialog.pack();
                dialog.setLocationRelativeTo(null);
                dialog.setVisible(true);
                switch (state) {

                    case JFileChooser.APPROVE_OPTION:
                        System.out.println("approved");
                        break;
                    case JFileChooser.CANCEL_OPTION:
                        System.out.println("cancled");
                        break;
                    default:
                        System.out.println("Broken");
                        break;

                }
            }
        });
    }
}

Secondly. If you want to get a task icon, I think you need to create a JFrame instead of a JDialog. This means that the frame won't block when made visible and you will need to rely on the ActionListener to provide feedback to the caller

Another option to configure the dialog: which is to subclass JFileChooser and override its createDialog with custom settings:

public static void main(String[] args) throws AWTException {
    Action action = new AbstractAction("open in tray") {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Please select the file");
            JFileChooser fc = new JFileChooser() {

                @Override
                protected JDialog createDialog(Component parent)
                        throws HeadlessException {
                    JDialog dialog = super.createDialog(parent);
                    // config here as needed - just to see a difference
                    dialog.setLocationByPlatform(true);
                    // might help - can't know because I can't reproduce the problem
                    dialog.setAlwaysOnTop(true);
                    return dialog;
                }

            };
            int retValue = fc.showOpenDialog(null);
            if(retValue == JFileChooser.APPROVE_OPTION){
                System.out.println(fc.getSelectedFile());
            }else {
                System.out.println("Next time select a file.");
            }
        }
    };
    TrayIcon trayIcon = new TrayIcon(XTestUtils.loadDefaultImage(), "open in tray");
    trayIcon.addActionListener(action);
    SystemTray.getSystemTray().add(trayIcon); 
}

Can't say if that might help because I can't reproduce the problem (Windows Vista, jdk7) - whatever I tried, the dialog appears on top of everything, probably highly OS dependent.

In the event that anyone else stumbles across this, I have a working solution to create a JFileChooser with taskbar icon that's fairly elegant.

JFileChooser chooser = new JFileChooser();
JDialog wrapper = new JDialog((Window)null);
wrapper.setVisible(true);
chooser.showDialog(wrapper);

Obviously wrapper can be manipulated in various ways, e.g. setting location, whether it's resizable, etc. Using (Window)null as the parent of the JDialog causes the dialog to have an icon in the taskbar, which is inherited by the JFileChooser when you showDialog or showOpenDialog or whatever you need, with the parent being the wrapper dialog.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!