2

其他一些问过类似问题的人一样,我疯狂地试图“修复”我的 JFileChooser 对话框生成代码,直到我注意到它正在生成,但它出现在所有其他窗口下方并且没有关联的任务栏图标(所以根本不知道它存在!)。

我知道这些类似的问题:

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

我也知道这里关于不要混合控制台和 Swing 界面的建议,但我想让事情尽可能简单。


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

注意 1: 该站点似乎在讨论解决方案,但很难遵循。
注意 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);
}

注释代码是我尝试过的所有无效的东西,包括

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

3 回答 3

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) - 无论我尝试了什么,对话框都会出现在所有内容之上,可能高度依赖于操作系统。

于 2013-07-03T08:47:19.003 回答
3

首先,您可以创建自己的对话框并使用setAlwaysOnTop将窗口带到窗口 z 顺序的顶部。这是特定于操作系统的,因此它可能不适用于所有操作系统...

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向调用者提供反馈

于 2013-07-03T03:37:16.350 回答
1

如果其他人偶然发现这一点,我有一个可行的解决方案来创建一个带有相当优雅的任务栏图标的 JFileChooser。

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

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

于 2019-06-09T18:21:57.980 回答