我有一个名为MyFileChooser的单例模式类,根据构造函数参数,如果JFileChooser为FILES_ONLY
或DIRECTORIES_ONLY
则适应。
我希望在JFrame中有JFileChooser,所以我可以在JFileChooser框架的上方和下方添加其他信息,因此结构将会显示:
JFrame
| JLabel
| JFileChooser
| JLabel
// end of JFrame
import javax.swing.JFrame;
import javax.swing.JFileChooser;
public class MyFileChooser {
private JFrame frame;
private boolean isFilesOnly;
private static final MyFileChooser instance_files = new MyFileChooser( true );
private static final MyFileChooser instance_dirs = new MyFileChooser( false );
private JFileChooser dynamicChooser;
private MyFileChooser( boolean filesOnly ) {
this.frame = new JFrame();
this.isFilesOnly = filesOnly;
this.dynamicChooser = new JFileChooser();
this.frameSetup();
this.chooserSetup();
}
public MyFileChooser getInstance( boolean filesOnly ) {
if ( filesOnly ) {
return MyFileChooser.instance_files;
} else {
return MyFileChooser.instance_dirs;
}
}
public void frameSetup() {
// jframe and labels setup code
this.frame.getContentPane().add( this.dynamicChooser );
}
public void chooserSetup() {
if ( this.isFilesOnly ) {
this.dynamicChooser.setFileSelectionMode( JFileChooser.FILES_ONLY );
} else {
this.dynamicChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
}
this.dynamicChooser.setMultiSelectionEnabled(true);
this.dynamicChooser.setDialogType(JFileChooser.CUSTOM_DIALOG);
}
问题是我不知道如何为JFileChooser的“关闭”和“打开”按钮附加处理程序。我发现的唯一一件事是:
public void handleSelectedFiles() {
int returnVal = this.dynamicChooser.showDialog(this.frame, "Open");
if (returnVal == JFileChooser.APPROVE_OPTION) {
File[] files = this.dynamicChooser.getSelectedFiles();
// do something
}
}
但是,如果调用此方法,它会打开两个实例,即使没有JFrame wrap& JLabels来自所需的结构。 所以我的问题是如何从JFileChooser获取“打开”和“关闭”按钮以附加处理程序(实例不同)或如何通过其他方式处理所选文件。
答案 0 :(得分:3)
你的第一个问题就在这里
int returnVal = this.dynamicChooser.showDialog(this.frame, "Open");
它会调用基础JFileChooser
的{{1}}方法,因此它会构建自己的窗口,忽略你的窗口
更好的解决方案是按需创建showDialog
并使用它来容纳文件选择器和其他控件
更像是......
JDialog
目的是模仿来自public class MyFileChooser {
private final boolean isFilesOnly;
private static final MyFileChooser INSTANCE_FILES = new MyFileChooser(true);
private static final MyFileChooser INSTANCE_DIRS = new MyFileChooser(false);
private final JFileChooser dynamicChooser;
private MyFileChooser(boolean filesOnly) {
this.isFilesOnly = filesOnly;
this.dynamicChooser = new JFileChooser();
dynamicChooser.setControlButtonsAreShown(false);
this.chooserSetup();
}
public MyFileChooser getInstance(boolean filesOnly) {
if (filesOnly) {
return MyFileChooser.INSTANCE_FILES;
} else {
return MyFileChooser.INSTANCE_DIRS;
}
}
public void frameSetup(Container parent) {
// jframe setup code
parent.add(this.dynamicChooser);
}
public void chooserSetup() {
if (this.isFilesOnly) {
this.dynamicChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
} else {
this.dynamicChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
this.dynamicChooser.setMultiSelectionEnabled(true);
this.dynamicChooser.setDialogType(JFileChooser.CUSTOM_DIALOG);
}
public File[] showOpenDialog(Component parent, String title) {
JDialog dialog = new JDialog(parent == null ? null : SwingUtilities.getWindowAncestor(parent), title);
dialog.setModal(true);
frameSetup(dialog);
dialog.pack();
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);
return dynamicChooser.getSelectedFiles();
}
}
的{{1}}的行为。在这个例子中,我隐藏了"正常"控制按钮,因为我假设您将提供自己的控制按钮,您可以通过它来更改返回文件
现在,如果您仍想使用标准按钮控件,则可以将showDialog
附加到JFileChooser
ActionListener
当我测试时,取消按钮返回JFileChooser
并选择按钮返回dynamicChooser.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
//...
}
});
现在,因为我的示例使用了动态对话框,您可能需要创建一个可以控制对话框的动态CancelSelection
,因为您不想继续将ApproveSelection
添加到ActionListener
没有移除它们,类似......
ActionListener
作为例子
因为我知道如果我不这样做,有人会劝我遏制......
Sington的Java是棘手的事情,关于这个问题有无数的线索,然而,人们普遍认为最好的方法(现在)是使用FileChooser
,这解决了旧的所有同步问题
所以,相反,您可以考虑使用类似的东西。
public File[] showOpenDialog(Component parent, String title) {
JDialog dialog = new JDialog(parent == null ? null : SwingUtilities.getWindowAncestor(parent), title);
dialog.setModal(true);
frameSetup(dialog);
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
//..
dialog.dispose();
}
};
dynamicChooser.addActionListener(listener);
dialog.pack();
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);
dynamicChooser.removeActionListener(listener);
return dynamicChooser.getSelectedFiles();
}
你可以简单地使用像...这样的东西来打电话。
enum
"我已经提到我希望选择器之间有JLabel,"
我原以为发表评论只是阅读成千上万的例子中的任何一个,显然我错了
因此,public static enum MyFileChooser {
INSTANCE_FILES(true),
INSTANCE_DIRS(false);
private final boolean isFilesOnly;
private final JFileChooser dynamicChooser;
private MyFileChooser(boolean filesOnly) {
this.isFilesOnly = filesOnly;
this.dynamicChooser = new JFileChooser();
//dynamicChooser.setControlButtonsAreShown(false);
this.chooserSetup();
}
public void frameSetup(Container parent) {
// jframe setup code
parent.add(this.dynamicChooser);
}
public void chooserSetup() {
if (this.isFilesOnly) {
this.dynamicChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
} else {
this.dynamicChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
}
this.dynamicChooser.setMultiSelectionEnabled(true);
this.dynamicChooser.setDialogType(JFileChooser.CUSTOM_DIALOG);
}
public File[] showOpenDialog(Component parent, String title) {
JDialog dialog = new JDialog(parent == null ? (JDialog)null : SwingUtilities.getWindowAncestor(parent), title);
dialog.setModal(true);
frameSetup(dialog);
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
//..
dialog.dispose();
}
};
dynamicChooser.addActionListener(listener);
dialog.pack();
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);
dynamicChooser.removeActionListener(listener);
return dynamicChooser.getSelectedFiles();
}
}
方法的简单更新解决了这个问题......
File[] files = MyFileChooser.INSTANCE_FILES.showOpenDialog(null, "Open");
有关详细信息,请查看How to Use BorderLayout
为确保其正常运行,我更新了frameSetup
方法以使用
public void frameSetup(Container parent) {
// jframe setup code
parent.setLayout(new BorderLayout());
parent.add(new JLabel("I'm on top"), BorderLayout.NORTH);
parent.add(this.dynamicChooser);
parent.add(new JLabel("I'm on bottom"), BorderLayout.SOUTH);
}
而不仅仅是传递showOpenDialog
的实例,这可以确保我们正在影响正确的容器