JFileChooser 和 RMI
JFileChooser and RMI
我尝试用 java 和 RMI 构建一个 FileChooser 来浏览远程机器的文件系统。
我到目前为止所做的最好地显示在下图中。 exists()
方法调用是一个示例,RemoteFileView
、RemoteFileSystemView
和 RemoteFile
的所有方法都转发到服务器。
言下之意:
我构建了一个 RemoteFileView
(extends FileView
)、RemoteFileSystemView
(extends FileSystemView
) 和一个 RemoteFile
(extends File
) 并覆盖了 super- 类 除了 File.hashCode()
和 FileSystemView.createFileSystemRoot(File)
(此方法在 FileSystemView
中受保护)。所有覆盖的方法都调用 RMI-Server 上的方法,其中来自服务器的 FileView
- 和 FileSystemView
调用服务器方法(就像 JFileChooser
那样)。我从虚拟实例化的 JFileChooser
.
获得服务器端的 FileView
和 FileSystemView
那么现在系统做了什么:
- 启动 RMI 服务器
- 启动 RMI 客户端
- JFileChooser
得到 RemoteFileView
- JFileChooser
得到 RemoteFileSystemView
- JFileChooser
从服务器获取所有 RemoteFiles
并显示 JFileChooser
中的文件夹和文件
所以到目前为止,行为都很好。现在的问题(我无法摆脱的地方):
JFileChooser
(客户端)的初始视图显示服务器主目录的所有文件。我可以(单击按钮)切换到父目录,直到系统根目录(在 windows 上,例如系统驱动器“C:\”)。从那里(或从其他地方)我可以双击一个文件夹跳转到它,只要这个路径存在于客户端系统上,但显示的文件和文件夹来自服务器。如果客户端上不存在该路径,我将无法跳转到该路径并浏览该文件夹。因此,如果有人知道这种行为,请提供帮助(我感谢任何解决方案 :))。
所以我决定编写一个自己的鼠标侦听器来识别 JFileChooser
上的双击。但是,如果我双击一个文件夹(在 JFileChooser
中),什么也不会发生。如果我突出显示一个文件夹(通过单击)然后双击 JFileChooser
中的某处(而不是在文件视图或按钮中),听众会识别出我的双击并跳转到突出显示的文件夹(希望这是够清楚了)。
我认为 FileView
(在 JFileChooser
上)位于 JFileChooser
之上,应该有自己的听众。或者我忘记了要编码的东西。
RMI 接口包含从 RemoteFileView
、RemoteFileSystemView
和 RemoteFile
调用的所有方法,从系统的行为来看,这应该没问题。
我当然可以发布一些代码以及有关整个程序的更多信息。我想发布所有代码会太多。
编辑:
由于这个问题可能是 "too broad" 更具体的版本(可能会解决我的问题):双击 JFileChooser 中的文件夹时会触发哪个侦听器?可以删除或设置此侦听器吗?
编辑2:
我在这个问题中看到: 只要通过双击选择文件,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.. 检测到)。
我上面描述的问题是组件和它们的鼠标监听器。所以首先你必须得到你的组件,然后向它添加监听器。所以在 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);
}
}
});
通过这个解决方案,我得到了我想要的行为。
我尝试用 java 和 RMI 构建一个 FileChooser 来浏览远程机器的文件系统。
我到目前为止所做的最好地显示在下图中。 exists()
方法调用是一个示例,RemoteFileView
、RemoteFileSystemView
和 RemoteFile
的所有方法都转发到服务器。
言下之意:
我构建了一个 RemoteFileView
(extends FileView
)、RemoteFileSystemView
(extends FileSystemView
) 和一个 RemoteFile
(extends File
) 并覆盖了 super- 类 除了 File.hashCode()
和 FileSystemView.createFileSystemRoot(File)
(此方法在 FileSystemView
中受保护)。所有覆盖的方法都调用 RMI-Server 上的方法,其中来自服务器的 FileView
- 和 FileSystemView
调用服务器方法(就像 JFileChooser
那样)。我从虚拟实例化的 JFileChooser
.
FileView
和 FileSystemView
那么现在系统做了什么:
- 启动 RMI 服务器
- 启动 RMI 客户端
- JFileChooser
得到 RemoteFileView
- JFileChooser
得到 RemoteFileSystemView
- JFileChooser
从服务器获取所有 RemoteFiles
并显示 JFileChooser
所以到目前为止,行为都很好。现在的问题(我无法摆脱的地方):
JFileChooser
(客户端)的初始视图显示服务器主目录的所有文件。我可以(单击按钮)切换到父目录,直到系统根目录(在 windows 上,例如系统驱动器“C:\”)。从那里(或从其他地方)我可以双击一个文件夹跳转到它,只要这个路径存在于客户端系统上,但显示的文件和文件夹来自服务器。如果客户端上不存在该路径,我将无法跳转到该路径并浏览该文件夹。因此,如果有人知道这种行为,请提供帮助(我感谢任何解决方案 :))。
所以我决定编写一个自己的鼠标侦听器来识别 JFileChooser
上的双击。但是,如果我双击一个文件夹(在 JFileChooser
中),什么也不会发生。如果我突出显示一个文件夹(通过单击)然后双击 JFileChooser
中的某处(而不是在文件视图或按钮中),听众会识别出我的双击并跳转到突出显示的文件夹(希望这是够清楚了)。
我认为 FileView
(在 JFileChooser
上)位于 JFileChooser
之上,应该有自己的听众。或者我忘记了要编码的东西。
RMI 接口包含从 RemoteFileView
、RemoteFileSystemView
和 RemoteFile
调用的所有方法,从系统的行为来看,这应该没问题。
我当然可以发布一些代码以及有关整个程序的更多信息。我想发布所有代码会太多。
编辑: 由于这个问题可能是 "too broad" 更具体的版本(可能会解决我的问题):双击 JFileChooser 中的文件夹时会触发哪个侦听器?可以删除或设置此侦听器吗?
编辑2:
我在这个问题中看到: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.. 检测到)。
我上面描述的问题是组件和它们的鼠标监听器。所以首先你必须得到你的组件,然后向它添加监听器。所以在 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);
}
}
});
通过这个解决方案,我得到了我想要的行为。