重新利用JFileChooser [英] Repurposing JFileChooser
问题描述
我需要在我的应用程序中实现文件浏览功能,虽然我知道可以制作一个JList项并手动执行,但我有一个想法就是为此实现JFileChooser.我设法将JFileChooser缩小为目录和文件列表,但无法覆盖其中的某些功能.我一直在查看源代码,但没有运气.我的想法是按以下方式进行处理:在列表的顶部具有/...目录,因此在单击该目录时,它会返回到父文件夹.同样,双击目录会将其设置为当前目录.双击文件后,它将返回选定的文件.
I need to implement file browsing feature in my app and while I am aware of possibility of making a JList item and doing it manually I had an idea to just implement JFileChooser for this. I managed to reduce the JFileChooser just to list of directories and files but I wasn't able to override some of it's functionalities. I have been going through source code but no luck. My idea is for it to handle as following: On the top of the list to have a /... directory so when clicked on it it returns to parent folder. Also when double clicked on directory it sets it as current directory. When double clicked on file it returns the file as selected.
这是我到目前为止使用的代码:
This is the code I used so far:
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中,但这没有用.
I tried adding custom MouseListener to the JFileChooser but it didn't work.
这是我到目前为止的结果:
This is the result I have so far:
有什么想法可以覆盖/替换哪些类或侦听器,这样我可以达到2种期望的效果吗?
Any idea which classes or listeners to overwrite/replace so I can achieve 2 desired effects?
这就是我在视觉上寻找的东西:
This is what I am looking for in visual terms:
推荐答案
在列表顶部有一个/...目录,因此在单击i时 它返回到父文件夹.
On the top of the list to have a /... directory so when clicked on i it returns to parent folder.
JFileChooser
具有名称为changeToParentDirectory()
的方法.因此,您只需添加一个Button并调用该方法即可.
JFileChooser
has method with name changeToParentDirectory()
. So you could simply add a Button and call that method.
JButton toParent = new JButton("/..");
toParent.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent a) {
fc.changeToParentDirectory();
}
});
fc.add(toParent, BorderLayout.NORTH);
还双击目录会将其设置为当前目录.
Also when double clicked on directory it sets it as current directory.
您可以将PropertyChangeListener
设置为侦听JFileChooser.DIRECTORY_CHANGED_PROPERTY
属性,该属性会在使用双击或内部命令更改了当前目录时触发.
You can set a PropertyChangeListener
to listen for JFileChooser.DIRECTORY_CHANGED_PROPERTY
property that is fired whenever the current directory has changed using double click or the internal commands.
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());
}
}
});
双击文件会返回所选文件.
When double clicked on file it returns the file as selected.
您可以将ActionListener
设置为侦听双击选择文件时触发的JFileChooser.APPROVE_SELECTION
操作.
You can set an ActionListener
to listen for JFileChooser.APPROVE_SELECTION
action that is fired whenever a file is chosen by double click.
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());
}
}
});
您误解了我对父文件夹操作的理解. 这是图片 描述它.
这可以通过使用受操纵的FileSystemView
与JFileChooser
来实现,该cc负责与文件系统的内容进行交互.我的实现操纵getFiles
方法在列表中走私特殊的File
,该列表具有已定义的名称并指向父目录.
我不太确定这是否是个好主意,因为这实际上并不意味着要包含在JFileChooser
代码中,但是我们可以开始了.
This could be achieved by using a manipulated FileSystemView
with the JFileChooser
that is responsible for interacting with the content of the filesystem. My implementation manipulates the getFiles
method to smuggle a special File
in the list that has a defined name and points to the parent directory.
I'm not quite sure if this is a very good idea, since this is really not meant to be in the JFileChooser
Code but here we go.
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();
}
});
有没有一种快速的解决方案可以将滚动从水平方向设置为垂直 JFileChooser?
is there a quick solution to set scroll from horizontal to vertical for JFileChooser?
有两种可能性.简单的方法是通过添加以下代码将JFileChooser
的样式更改为Details View
:
There are two possibilities. The simple one is to change the style of your JFileChooser
to the Details View
by adding this code:
Action details = fc.getActionMap().get("viewTypeDetails");
details.actionPerformed(null);
更复杂的方法是更改文件视图JList
的LayoutOrientation
,该文件视图是sun.swing.FilePane
的组成部分,而sun.swing.FilePane
是Component
,而JFileChooser
在JFileChooser
中.
这里的一个问题是FilePane
不是Java库的一部分,而是Core库的一部分,并且默认情况下不可访问.但是您可以使用Reflection在FilePane
中获取字段private JList list;
,并使用以下代码将其LayoutOrientation
更改为JList.VERTICAL
:
The more complex one is to change the LayoutOrientation
of the file view JList
that is a component of sun.swing.FilePane
that is the Component
with ID:2
in the JFileChooser
.
One problem here is that FilePane
is not part of the Java Library but part of the Core Library and not accessible by default. But you can use Reflection to get the field private JList list;
in the FilePane
and change its LayoutOrientation
to JList.VERTICAL
with this code:
// 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);
这篇关于重新利用JFileChooser的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!