Java 是否禁用JFileChooser中的打开按钮?
我扩展了一个Java 是否禁用JFileChooser中的打开按钮?,java,swing,jfilechooser,Java,Swing,Jfilechooser,我扩展了一个JFileChooser并覆盖了approveSelection方法,因此当用户选择一个无效目录,然后单击打开按钮时,JOptionPane中将显示一条错误消息。但是我想让我的JFileChooser更加用户友好,当用户单击无效目录时,使“打开”按钮变为禁用,然后当用户单击有效目录时,使其重新启用。是否可以进一步自定义我的JFileChooser并访问“打开”按钮,以便我可以相应地更改按钮的状态(可能通过侦听目录选择的侦听器) 当检测到文件/目录上的任何选择更改时,可以通过调用cho
JFileChooser
并覆盖了approveSelection
方法,因此当用户选择一个无效目录,然后单击打开按钮时,JOptionPane
中将显示一条错误消息。但是我想让我的JFileChooser
更加用户友好,当用户单击无效目录时,使“打开”按钮变为禁用,然后当用户单击有效目录时,使其重新启用。是否可以进一步自定义我的JFileChooser
并访问“打开”按钮,以便我可以相应地更改按钮的状态(可能通过侦听目录选择的侦听器)
当检测到文件/目录上的任何选择更改时,可以通过调用chooser.setControlButtonsAreShown(false)隐藏接受/取消按钮:
myChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
myChooser.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
File file = (File) evt.getNewValue();
if (file != null && file.isFile()) { // your condition
myChooser.setControlButtonsAreShown(false);
}
else if ( file != null ) {
System.out.println(file.getName());
myChooser.setControlButtonsAreShown(true);
}
}
myChooser.repaint();
}
});
但这可能会让用户感到困惑,最好使用自定义文件过滤器,只显示所需的文件/目录:
public static class MyDirectoryFilter extends javax.swing.filechooser.FileFilter {
@Override
public boolean accept( File file ) {
return file.isDirectory() && customeCondition(file) ;
}
@Override
public String getDescription() {
return "this only my custom dir";
}
}
myChooser.setFileFilter( new MyDirectoryFilter () );
编辑:
我找到了一种禁用按钮的方法,通过迭代组件并获取打开按钮的句柄:
例如:
myChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
myChooser.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
File file = (File) evt.getNewValue();
if (file != null && file.isFile()) {
setOpenButtonState(myChooser, false);
}
else if ( file != null ) {
setOpenButtonState(myChooser, true);
System.out.println(file.getName());
}
}
myChooser.repaint();
}
});
public static void setOpenButtonState(Container c, boolean flag) {
int len = c.getComponentCount();
for (int i = 0; i < len; i++) {
Component comp = c.getComponent(i);
if (comp instanceof JButton) {
JButton b = (JButton) comp;
if ( "Open".equals(b.getText()) ) {
b.setEnabled(flag);
}
} else if (comp instanceof Container) {
setOpenButtonState((Container) comp, flag);
}
}
}
myChooser.setFileSelectionMode(JFileChooser.FILES\u和\u目录);
myChooser.addPropertyChangeListener(新的PropertyChangeListener(){
公共作废属性更改(属性更改事件evt){
if(JFileChooser.SELECTED\u FILE\u CHANGED\u PROPERTY.equals(evt.getPropertyName())){
File File=(File)evt.getNewValue();
如果(file!=null&&file.isFile()){
setOpenButtonState(myChooser,false);
}
else if(文件!=null){
setOpenButtonState(myChooser,true);
System.out.println(file.getName());
}
}
myChooser.repaint();
}
});
公共静态void setOpenButtonState(容器c,布尔标志){
int len=c.getComponentCount();
对于(int i=0;i
正如Wajdy Essam已经回答的那样,您通常可以使用
但这种方法并不适用于所有的外观,至少不适用于我正在使用的外观
我写了一个快速解决方案,在大多数情况下都能奏效
此外,您还可以完全访问文件选择器的取消和批准按钮
public class JFileChooserTest extends JFileChooser {
private JButton approveButton, cancelButton;
public JFileChooserTest() {
// Lookup the Buttons
if (approveButton == null) {
approveButton = lookupButton(JFileChooserTest.this, getUI().getApproveButtonText(this));
}
if (cancelButton == null) {
cancelButton = lookupButton(JFileChooserTest.this, UIManager.getString("FileChooser.cancelButtonText"));
}
setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
//Creating the Listener
PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
//Do action only if the selected file changed
if (evt.getPropertyName().equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
File newFile = (File) evt.getNewValue();
//Validate the new File
boolean validate = validateFile(newFile);
//Enable/Disable the buttons
if (approveButton != null) {
approveButton.setEnabled(validate);
}
if (cancelButton != null) {
cancelButton.setEnabled(validate);
}
}
}
};
//Adding the listeners
addPropertyChangeListener(SELECTED_FILE_CHANGED_PROPERTY, propertyChangeListener);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JFileChooserTest test = new JFileChooserTest();
test.showOpenDialog(null);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
Logger.getLogger(JFileChooserTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
/**
* Simple validation method; only for testing purpose
*
* @param f
* @return
*/
private boolean validateFile(File f) {
return f != null && !f.getName().startsWith("A");
}
/**
* Looksup the first JButton in the specific Container (and sub-containers)
* with the given text.
*
* @param c
* @param text
* @return
*/
private JButton lookupButton(Container c, String text) {
JButton temp = null;
for (Component comp : c.getComponents()) {
if (comp == null) {
continue;
}
if (comp instanceof JButton && (temp = (JButton) comp).getText() != null && temp.getText().equals(text)) {
return temp;
} else if (comp instanceof Container) {
if ((temp = lookupButton((Container) comp, text)) != null) {
return temp;
}
}
}
return temp;
}
}
我还建议使用来验证所选文件,而不是覆盖approveSelection()
是否禁用JFileChooser中的打开按钮
更好的是,安装一个自定义文件来隐藏无效目录。查看覆盖情况。为什么不使用文件过滤器呢。它甚至不允许用户选择无效的目录。看,我有相同的要求,但对我来说,我只需要允许选择满足某些条件的目录。我不能使用文件过滤器,因为如果我使用了,用户将无法在文件系统的任何位置导航!我需要允许完整目录导航,但仅允许选择(即,单击“打开”按钮)符合我标准的目录。有什么想法吗?@MatthewWise A
FileSystemView
可以显示文件和目录。是的,但我需要显示所有目录以允许完全导航,但只能选择某些目录,即单击“打开”按钮。我的解决方法是重写approveSelection(),将条件逻辑放在此处,如果所选目录不满足条件,则显示错误消息。希望这能让我更清楚地了解我需要实现什么…很好的示例,但不要使用b.getText().equals(“Open”)
,使用b.getText().equals(chooser.getApproveButtonText())
来支持国际化。
public class JFileChooserTest extends JFileChooser {
private JButton approveButton, cancelButton;
public JFileChooserTest() {
// Lookup the Buttons
if (approveButton == null) {
approveButton = lookupButton(JFileChooserTest.this, getUI().getApproveButtonText(this));
}
if (cancelButton == null) {
cancelButton = lookupButton(JFileChooserTest.this, UIManager.getString("FileChooser.cancelButtonText"));
}
setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
//Creating the Listener
PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
//Do action only if the selected file changed
if (evt.getPropertyName().equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
File newFile = (File) evt.getNewValue();
//Validate the new File
boolean validate = validateFile(newFile);
//Enable/Disable the buttons
if (approveButton != null) {
approveButton.setEnabled(validate);
}
if (cancelButton != null) {
cancelButton.setEnabled(validate);
}
}
}
};
//Adding the listeners
addPropertyChangeListener(SELECTED_FILE_CHANGED_PROPERTY, propertyChangeListener);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JFileChooserTest test = new JFileChooserTest();
test.showOpenDialog(null);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
Logger.getLogger(JFileChooserTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
/**
* Simple validation method; only for testing purpose
*
* @param f
* @return
*/
private boolean validateFile(File f) {
return f != null && !f.getName().startsWith("A");
}
/**
* Looksup the first JButton in the specific Container (and sub-containers)
* with the given text.
*
* @param c
* @param text
* @return
*/
private JButton lookupButton(Container c, String text) {
JButton temp = null;
for (Component comp : c.getComponents()) {
if (comp == null) {
continue;
}
if (comp instanceof JButton && (temp = (JButton) comp).getText() != null && temp.getText().equals(text)) {
return temp;
} else if (comp instanceof Container) {
if ((temp = lookupButton((Container) comp, text)) != null) {
return temp;
}
}
}
return temp;
}
}