如何在其他窗口的顶部生成独立的JFileChooser对话框?

时间:2013-07-03 02:09:41

标签: java swing focus jfilechooser taskbar

就像问过类似问题的some other people一样,我一直在努力“修复”我的JFileChooser对话框生成代码,直到我注意到 正在生成,但它出现了在所有其他窗口下面没有相关的任务栏图标(所以它根本就没有任何线索!)。

我知道这些类似的问题:

...但这些问题的答案似乎过于复杂,涉及创建更多的GUI元素,我无法相信这些元素。

我也知道有关不混合控制台和Swing接口的建议here,但我希望尽可能简单。


我想知道如何生成一个JFileChooser(showOpenDialog)对话框,该对话框位于其他窗口之上,而无需创建其他GUI元素(JPanel等)。

注1:This site似乎在讨论解决方案,但很难遵循 注意2:如果我要求的是不可能的,那么关于如何至少给对话框一个任务栏图标的信息(同样不需要它有父母)将会很棒。

我的代码,现在创建一个隐藏的对话框,在这里:

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

class Client {
    String currentDirectoryFolderPath = "H:\\myFolder";
    javax.swing.JFileChooser jFileChooser =
            new JFileChooser(currentDirectoryFolderPath);
    jFileChooser.setVisible(true); //defaults to invisible?!?
    javax.swing.filechooser.FileNameExtensionFilter fileExtensionFilter
            = new FileNameExtensionFilter(
              comma-separated values and text files",
              "csv", "txt");
    jFileChooser.setFileFilter(fileExtensionFilter);

    //int returnVal = jFileChooser.showOpenDialog(jFileChooser);
    //jFileChooser.showDialog(null, "testing 1--2--3");
    //jFileChooser.requestFocusInWindow();
    //jFileChooser.requestFocus();
    //jFileChooser.showOpenDialog(null);
    //jFileChooser.requestFocus();
    int returnVal = jFileChooser.showOpenDialog(null);

    if(returnVal == JFileChooser.APPROVE_OPTION) {
        System.out.println("You chose to open this file: " +
                           jFileChooser.getSelectedFile().getName());
    }

    System.out.println(JFileChooser.APPROVE_OPTION);
    System.out.println(jFileChooser);
}

评论代码是我尝试过的所有没有用过的东西,包括

  • 在调用对话框之后之前的 之后的不同类型的焦点请求
  • 提供对话框对象本身作为它自己的父对象而不是传递null(我认为值得一试。)。

3 个答案:

答案 0 :(得分:3)

首先,您可以创建自己的对话框并使用setAlwaysOnTop将窗口置于窗口z-order的顶部。这是特定于操作系统的,因此可能无法在所有操作系统上运行...

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;

                }
            }
        });
    }
}

其次。如果您想获得任务图标,我认为您需要创建JFrame而不是JDialog。这意味着框架在显示时不会阻止,您需要依靠ActionListener向调用者提供反馈

答案 1 :(得分:3)

配置对话框的另一个选项:子类化JFileChooser并使用自定义设置覆盖其createDialog:

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); 
}

不能说这是否有帮助,因为我无法重现问题(Windows Vista,jdk7) - 无论我尝试什么,对话框都会显示在所有内容之上,可能与操作系统有很大关系。

答案 2 :(得分:0)

万一遇到其他人,我有一个可行的解决方案,可以创建一个带有优雅的任务栏图标的JFileChooser。

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

很显然,wrapper可以通过多种方式进行操作,例如设置位置,是否可调整大小等。使用(Window)null作为JDialog的父级会导致对话框在任务栏中有一个图标,当您showDialog或{{1}时,它将由JFileChooser继承。 }或您需要的任何内容,父级为showOpenDialog对话框。