【问题标题】:JFileChooser and RMIJFileChooser 和 RMI
【发布时间】:2016-09-10 10:27:07
【问题描述】:

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

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

言下之意: 我构建了一个RemoteFileViewextends FileView)、RemoteFileSystemViewextends FileSystemView)和一个RemoteFileextends File)并覆盖了除File.hashCode()FileSystemView.createFileSystemRoot(File)之外的所有超类方法(这个方法受FileSystemView 保护)。所有被覆盖的方法都调用 RMI 服务器上的方法,其中来自服务器的 FileView- 和 FileSystemView 调用服务器方法(就像 JFileChooser 会做的那样)。我从一个虚拟实例化的JFileChooser 获得了服务器端的FileViewFileSystemView

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

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

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

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

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

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

编辑: 由于这个问题可能“太宽泛”,所以更具体的版本(这可能会解决我的问题):双击 JFileChooser 中的文件夹会触发哪个侦听器?可以删除或设置此侦听器吗?

编辑2: 我在这个问题中看到: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.. 检测到)。

【问题讨论】:

  • 这一切都归结为“您需要从头开始构建一个文件选择器”,当在您的服务器中使用时,它将显示客户端特定目录的所有文件。因此,传递所有文件的列表和客户端父目录的名称以在服务器端进行模仿。我认为这是可能的方法之一!
  • 我想显示和浏览服务器的文件系统(从客户端),而不是其他方式;)我在互联网上找到了一些解决方案(JFileChooser over RMI),人们说要自己构建FileView、FileSystemView 和 File,我做了)。
  • 这是否意味着这个问题已经被你解决了?
  • 对不起,不!上周我做了所有的编码工作,大部分时间都在尝试解决我的问题(包括研究),但没有任何帮助。不幸的是,我的问题还没有解决。
  • 好吧,这个问题纯粹是一个给我代码来实现的问题!我投票结束这个问题太宽泛了。到那时,您可以按照我在第一条评论中的建议进行尝试。而且,这里只问具体问题。祝你的项目好运,:)

标签: java file rmi remote-access jfilechooser


【解决方案1】:

我上面描述的问题是组件及其鼠标侦听器。因此,首先您必须获取组件,然后将侦听器添加到其中。所以在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);
    }
  }
});

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

【讨论】:

    猜你喜欢
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 2012-07-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多