gpt4 book ai didi

java - 如何在 Java 中的自定义 JFrame 中附加 JFileChooser 按钮的处理程序

转载 作者:行者123 更新时间:2023-11-29 04:34:59 25 4
gpt4 key购买 nike

我有一个名为 MyFileChooser 的单例模式类,如果 JFileChooser 是 FILES_ONLYDIRECTORIES_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 包装和 JLabel,它也会打开这两个实例。所以我的问题是如何从 JFileChooser 获取“打开”和“关闭”按钮以附加处理程序(实例不同)或如何通过其他方式处理所选文件。

最佳答案

你的第一个问题在这里

int returnVal = this.dynamicChooser.showDialog(this.frame, "Open");

它调用底层 JFileChoosershowDialog 方法,所以它正在构建自己的窗口,忽略你的

更好的解决方案是根据需要创建一个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();
}
}

目的是模仿JFileChoosershowDialog 的操作。在此示例中,我隐藏了“普通”控制按钮,因为我假设您将提供自己的按钮,通过它您可以更改返回文件

现在,如果您仍想使用标准按钮控件,可以将 ActionListener 附加到 JFileChooser

dynamicChooser.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
//...
}
});

当我测试时,取消按钮返回 CancelSelection 并且选择按钮返回 ApproveSelection

现在,因为我的示例使用动态对话框,您可能需要创建一个动态的 ActionListener 来控制对话框,因为您不想继续添加 ActionListeners 到 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();
}

举个例子

观察

因为我知道如果我不...有人会踢我以遏制...

Sington 在 Java 中是棘手的事情,关于这个主题有无数线程,然而,人们普遍认为(现在)最好的方法是使用 enum,它解决了所有同步问题老

因此,您可能会考虑使用类似...

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

“我已经提到我希望在选择器之间有 JLabel,”

我原以为布局评论只是阅读数以千计可用示例中的任何一个的问题,显然我错了

因此,对 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);
}

Simple Layout

看看How to Use BorderLayout了解更多详情

为确保它正常工作,我更新了 showOpenDialog 方法以使用

frameSetup(dialog.getContentPane());

而不是仅仅传递 JDialog 的实例,这确保我们正在影响正确的容器

关于java - 如何在 Java 中的自定义 JFrame 中附加 JFileChooser 按钮的处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42035164/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com