JFileChooser 和 RMI

JFileChooser and RMI

我尝试用 java 和 RMI 构建一个 FileChooser 来浏览远程机器的文件系统。

我到目前为止所做的最好地显示在下图中。 exists() 方法调用是一个示例,RemoteFileViewRemoteFileSystemViewRemoteFile 的所有方法都转发到服务器。

言下之意: 我构建了一个 RemoteFileView (extends FileView)、RemoteFileSystemView (extends FileSystemView) 和一个 RemoteFile (extends File) 并覆盖了 super- 类 除了 File.hashCode()FileSystemView.createFileSystemRoot(File)(此方法在 FileSystemView 中受保护)。所有覆盖的方法都调用 RMI-Server 上的方法,其中来自服务器的 FileView- 和 FileSystemView 调用服务器方法(就像 JFileChooser 那样)。我从虚拟实例化的 JFileChooser.

获得服务器端的 FileViewFileSystemView

那么现在系统做了什么:
- 启动 RMI 服务器
- 启动 RMI 客户端
- JFileChooser 得到 RemoteFileView
- JFileChooser 得到 RemoteFileSystemView
- JFileChooser 从服务器获取所有 RemoteFiles 并显示 JFileChooser

中的文件夹和文件

所以到目前为止,行为都很好。现在的问题(我无法摆脱的地方): JFileChooser(客户端)的初始视图显示服务器主目录的所有文件。我可以(单击按钮)切换到父目录,直到系统根目录(在 windows 上,例如系统驱动器“C:\”)。从那里(或从其他地方)我可以双击一个文件夹跳转到它,只要这个路径存在于客户端系统上,但显示的文件和文件夹来自服务器。如果客户端上不存在该路径,我将无法跳转到该路径并浏览该文件夹。因此,如果有人知道这种行为,请提供帮助(我感谢任何解决方案 :))。

所以我决定编写一个自己的鼠标侦听器来识别 JFileChooser 上的双击。但是,如果我双击一个文件夹(在 JFileChooser 中),什么也不会发生。如果我突出显示一个文件夹(通过单击)然后双击 JFileChooser 中的某处(而不是在文件视图或按钮中),听众会识别出我的双击并跳转到突出显示的文件夹(希望这是够清楚了)。

我认为 FileView(在 JFileChooser 上)位于 JFileChooser 之上,应该有自己的听众。或者我忘记了要编码的东西。

RMI 接口包含从 RemoteFileViewRemoteFileSystemViewRemoteFile 调用的所有方法,从系统的行为来看,这应该没问题。

我当然可以发布一些代码以及有关整个程序的更多信息。我想发布所有代码会太多。

编辑: 由于这个问题可能是 "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 中我们得到了 JListJTable。两种视图都可以通过单击按钮来切换。 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);
    }
  }
});

通过这个解决方案,我得到了我想要的行为。