我需要在我的应用程序中实现文件浏览功能,虽然我知道有可能制作一个JList项目并手动执行,但我有一个想法就是为此实现JFileChooser。我设法将JFileChooser简化为目录和文件列表,但我无法覆盖其中的一些功能。我一直在浏览源代码,但没有运气。我的想法是它处理如下:在列表的顶部有一个/ ...目录所以当点击它时它返回到父文件夹。此外,当双击目录时,它将其设置为当前目录。双击文件时,它会将文件返回为选中状态。
这是我到目前为止使用的代码:
final JFileChooser fc = new JFileChooser();
fc.setControlButtonsAreShown(false);
fc.setCurrentDirectory(paths[list.getSelectedIndex()]);
/*remove unwanted components*/
for(int i = 0; i < fc.getComponentCount(); i++) {
fc.getComponent(0).setVisible(false);
fc.getComponent(1).setVisible(false);
fc.getComponent(3).setVisible(false);
}
add(fc, BorderLayout.CENTER);
我尝试将自定义MouseListener添加到JFileChooser但它没有用。
这是我到目前为止的结果:
知道哪些类或听众要覆盖/替换所以我可以实现2个想要的效果?
这就是我用视觉术语寻找的东西:
答案 0 :(得分:3)
在列表的顶部有一个/ ...目录所以当点击i时 它返回父文件夹。
JFileChooser
包含名为changeToParentDirectory()
的方法。所以你可以简单地添加一个Button并调用该方法。
JButton toParent = new JButton("/..");
toParent.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent a) {
fc.changeToParentDirectory();
}
});
fc.add(toParent, BorderLayout.NORTH);
当双击目录时,它将其设置为当前目录。
您可以设置PropertyChangeListener
以侦听当使用双击或内部命令更改当前目录时触发的JFileChooser.DIRECTORY_CHANGED_PROPERTY
属性。
fc.addPropertyChangeListener(new PropertyChangeListener(){
@Override
public void propertyChange(PropertyChangeEvent e) {
String command = e.getPropertyName();
if (command.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) {
File currentDir = fc.getCurrentDirectory();
System.out.println(currentDir.getAbsolutePath());
}
}
});
双击文件时,它会将文件返回为选中状态。
您可以设置ActionListener
来监听通过双击选择文件时触发的JFileChooser.APPROVE_SELECTION
操作。
fc.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals(JFileChooser.APPROVE_SELECTION)) {
File selectedFile = fc.getSelectedFile();
System.out.println(selectedFile.getAbsolutePath());
}
}
});
编辑:
你误解我的父文件夹操作。 Here is an image 描述它。
这可以通过使用负责与文件系统内容交互的FileSystemView
的操作JFileChooser
来实现。我的实现操作getFiles
方法来走私列表中具有已定义名称并指向父目录的特殊File
。
我不太确定这是否是一个非常好的主意,因为这实际上并不属于JFileChooser
代码,而是我们去了。
fc.setFileSystemView(new FileSystemView(){
// this method is abstract but since you don't
// want to create directories here you don't
// need to implement it.
@Override
public File createNewFolder(File f) throws IOException {
return null;
}
// manipulate the default getFiles method that creates
// the list of files in the current directory
@Override
public File[] getFiles(File dir, boolean useFileHiding){
// get the list of files from default implementation
File[] files = super.getFiles(dir,useFileHiding);
// get the parent directory of current
File parent = getParentDirectory(dir);
// skip the next for problematic folders with
// empty names and root folders
if(!dir.getName().isEmpty() && !isRoot(dir)){
// create a new list of files with one extra place
File[] nfiles = new File[files.length + 1];
// add a special file to list that points to parent directory
nfiles[0] = new File(parent.getAbsolutePath()){
// set a special name for that file
@Override
public String getName(){return "...";}
};
// add the rest of files to list
for(int i = 0; i < files.length; i++)
nfiles[i+1] = files[i];
// use the new list
files = nfiles;
}
// return list of files
return files;
}
// some special folders like "c:" gets converted
// in shellfolders.Then our setted name "..." would
// get converted to "local drive (c:)". This garantees
// that our setted name will be used.
@Override
public String getSystemDisplayName(File f) {
return f.getName();
}
});
EDIT2:
是否有快速解决方案将滚动设置为从水平到垂直 对于JFileChooser?
有两种可能性。简单的方法是通过添加以下代码将JFileChooser
的样式更改为Details View
:
Action details = fc.getActionMap().get("viewTypeDetails");
details.actionPerformed(null);
更复杂的是更改文件视图LayoutOrientation
的{{1}},JList
是sun.swing.FilePane
的组件Component
,ID:2
in JFileChooser
FilePane
这里的一个问题是private JList list;
不是Java库的一部分,而是核心库的一部分,默认情况下不可访问。但您可以使用反射来获取FilePane
中的字段LayoutOrientation
,并使用以下代码将其JList.VERTICAL
更改为// get the FilePane Component of JFileChooser
Object filepane = fc.getComponent(2);
// get the list field with reflection
Field field_list = filepane.getClass().getDeclaredField("list");
// get access to this private field
field_list.setAccessible(true);
// read the value of the field
JList<?> list = (JList<?>)field_list.get(filepane);
// change the layout orientation
list.setLayoutOrientation(JList.VERTICAL);
:
abstract class Vehicle {
// Some vars
public abstract void draw();
}
class Car : Vehicle {
// Some vars
public override void draw() { /* Draw function */ }
}
class Truck : Vehicle {
// Some vars
public override void draw() { /* Another draw function */ }
}