Java 如何在其他窗口上生成独立的JFileChooser对话框?
和问过类似问题的人一样,我也疯狂地试图“修复”我的JFileChooser对话框生成代码,直到我注意到它正在生成,但它出现在所有其他窗口下面,并且没有相关的任务栏图标(因此根本没有它存在的线索!) 我知道这些类似的问题:Java 如何在其他窗口上生成独立的JFileChooser对话框?,java,swing,focus,jfilechooser,taskbar,Java,Swing,Focus,Jfilechooser,Taskbar,和问过类似问题的人一样,我也疯狂地试图“修复”我的JFileChooser对话框生成代码,直到我注意到它正在生成,但它出现在所有其他窗口下面,并且没有相关的任务栏图标(因此根本没有它存在的线索!) 我知道这些类似的问题: …但这些问题的答案似乎过于复杂,涉及到创建更多的GUI元素,我认为这是不必要的 我也知道关于不要混合控制台和Swing接口的建议,但我希望尽可能简单 我想知道如何生成位于其他窗口之上的JFileChooser(showOpenDialog)对话框,而不必创建其他GUI
我想知道如何生成位于其他窗口之上的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);
}
注释代码是我尝试过的所有不起作用的东西,包括
- 调用对话框前后不同类型的焦点请求,以及
- 提供对话框对象本身作为它自己的父对象,而不是传递null(我认为这值得一试)
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
向调用者提供反馈另一个配置对话框的选项:将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)-无论我怎么做,对话框都会出现在所有东西的顶部,可能高度依赖操作系统。如果其他人偶然发现这个问题,我有一个可行的解决方案来创建一个带有相当优雅的任务栏图标的JFileChooser
JFileChooser chooser = new JFileChooser();
JDialog wrapper = new JDialog((Window)null);
wrapper.setVisible(true);
chooser.showDialog(wrapper);
显然,
wrapper
可以通过各种方式进行操作,例如设置位置、是否可调整大小等。使用(Window)null
作为JDialog的父级会使对话框在任务栏中有一个图标,当您使用showDialog
或showOpenDialog
或任何您需要的东西时,JFileChooser会继承它,其父级是包装器
对话框。大多数情况下,我只想让事情保持简单。。。而且:如果您可以创建一个没有父对象(null)的文件选择器,那么您应该能够创建一个没有父对象的可用文件选择器。(否则,在没有父对象的情况下创建它有什么意义呢?)创建自己的对话框,将其始终设置在顶部,并向其添加一个JFileChooser
it@MadProgrammer这听起来有点像,这很好(这正是我现在正在实现的),但它仍然需要一个额外的“片段”。我认为一个无关的对话框比一个无关的JFrame(如链接中所示)更整洁,因此,如果没有其他部分你绝对不能做到这一点,那么我会接受它作为一个答案(特别是如果这会产生一个任务栏项)。@MadProgrammer顺便说一句,你基本上是说一些对话框可以设置在顶部(它甚至不必是“始终在顶部”),但文件选择器对话框由于某些原因缺少这种功能。如果是真的,那就很奇怪了。我没有测试过它,但这听起来不错(如果比我希望的窗口正常运行要复杂得多的话)。setAlwaysOnTop在这里是必不可少的吗?难道没有办法让它像99%出现的其他新窗口一样工作,也就是说,一开始在顶部,但不总是在顶部吗?(我想将setAlwaysOnTop设置为true,然后立即再次设置为false可能会这样做,但这似乎是一个难题。)这也很好(尽管如此,如果仅仅为了阻止窗口以我不相信任何人会希望的方式运行,就需要这么多的复杂性,那真是太遗憾了)。我猜您的代码中需要setAlwaysOnTop,但我会很快试用它(包括不使用它)。@a.M.-正如我所说的:对我来说,它总是按照预期的方式运行(我努力让它显示在一个框架下;),所以在您的上下文/操作系统中可能有什么东西让它行为不端,这可能值得也可能不值得追踪