我尝试用java和RMI构建一个FileChooser来浏览远程计算机的文件系统。
到目前为止,我所做的最好的显示在下面的图表中。exists()
方法调用是一个示例,所有的RemoteFileView
、RemoteFileSystemView
和RemoteFile
方法都转发到服务器。
换句话说:我构建了一个RemoteFileView
(extends FileView
)、RemoteFileSystemView
(extends FileSystemView
)和RemoteFile
(extends File
),并覆盖了超类的所有方法,除了File.hashCode()
和FileSystemView.createFileSystemRoot(File)
(这个方法在FileSystemView
中是受保护的)。所有重写的方法都调用RMI上的方法,其中FileView
和来自服务器的FileSystemView
调用服务器-方法(就像JFileChooser
所做的那样)。我从虚拟实例化的FileView
获得服务器端的FileSystemView
和JFileChooser
。
那么现在这个系统所做的是:
JFileChooser
获得RemoteFileView
JFileChooser
获得RemoteFileSystemView
JFileChooser
从服务器获取所有RemoteFiles
,并显示JFileChooser
中的文件夹和文件。所以到目前为止行为都很好。现在问题(我无法摆脱):JFileChooser
(客户端)的初始视图显示服务器主目录的所有文件。我可以(按一下按钮)切换到父目录,直到系统根目录(例如,在windows上,系统驱动器“C:\”)。从那里(或其他任何地方),我可以双击一个文件夹跳入它,只要这个路径存在于客户端系统,但显示的文件和文件夹来自服务器。如果客户端上不存在路径,我就不能跳入其中浏览这个文件夹。因此,如果有人知道这种行为,请提供帮助(我感谢任何解决方案:)。
所以我决定编写一个自己的鼠标监听器来识别JFileChooser
上的双击。但是如果我双击一个文件夹(在JFileChooser
中),什么都不会发生。如果我高亮显示一个文件夹(通过单击),然后双击JFileChooser
中的某个地方(而不是文件视图或按钮),侦听器识别我的双击并跳入突出显示的文件夹(希望这足够清楚)。
我认为FileView
(在JFileChooser
上)位于JFileChooser
之上,应该有自己的侦听器。或者我忘了一些东西来编码。
RMI-接口包含从RemoteFileView
、RemoteFileSystemView
和RemoteFile
调用的所有方法,从系统的行为来看,这应该是正常的。
当然,我可以发布一些代码以及更多关于整个程序的信息。我想把所有的密码都贴出来太过分了。
编辑:由于这个问题可能“太宽泛”,所以更具体的版本(这可能解决了我的问题):哪个侦听器在双击JFileChooser中的文件夹时触发?可以删除或设置此侦听器吗?
EDIT2:我在这个问题:Repurposing JFileChooser中看到,只要通过双击选择文件,JFileChooser就会在JFileChooser.APPROVE_SELECTION
上触发。因此,我实现了以下代码:
fileChooser.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Some action");
String command = e.getActionCommand();
if (command.equals(JFileChooser.APPROVE_SELECTION)) {
File file = fileChooser.getSelectedFile();
fileChooser.setCurrentDirectory(file);
fileChooser.rescanCurrentDirectory();
}
}
});
但是不幸的是,动作侦听器不识别FileView中的任何动作(显示文件的组件),而是在单击按钮时触发动作事件(我用System.out.检测到)。
发布于 2016-09-12 22:09:05
我上面描述的问题是组件和它们的鼠标侦听器。因此,首先您必须得到您的组件,然后将侦听器添加到其中。所以在一个JFileChooser
中,我们得到了一个JList
和一个JTable
。两种视图都可以通过按钮转换。JList
保存文件以及JTable
。
我在这里找到了一种解决方案:https://community.oracle.com/thread/1350166?start=0&tstart=0
因此,我使用了一些代码,并实现了我的鼠标侦听器:
JList的侦听器:
JList<?> list = SwingUtils.getDescendantOfType(JList.class, fileChooser, "Enabled", true);
MouseListener listener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
File file = fileChooser.getSelectedFile();
if (e.getClickCount() == 2 && file != null) {
if (e.getSource() == list) {
// Do your stuff
operateOnFile(file);
}
else {
// Default operation
}
}
}
};
list.addMouseListener(listener);
以及JTable的侦听器:
final Container filePane = SwingUtilities.getAncestorOfClass(sun.swing.FilePane.class, list);
filePane.addContainerListener(new ContainerAdapter() {
@Override
public void componentAdded(ContainerEvent e) {
JTable table = SwingUtils.getDescendantOfType(JTable.class, fileChooser, "Enabled", true);
if (table != null) {
for (MouseListener l : table.getMouseListeners()) {
if (l == listener) {
return;
}
}
table.addMouseListener(listener);
}
}
});
通过这个解决方案,我得到了我想要的行为。
https://stackoverflow.com/questions/39425114
复制