i tried to build a FileChooser with java and RMI to browse the file system of a remote machine.
What I did until now is best shown in the following diagram. The exists()
method-call is an example and all methods of RemoteFileView
, RemoteFileSystemView
and RemoteFile
forward to the server.
In words:
I build a RemoteFileView
(extends FileView
), RemoteFileSystemView
(extends FileSystemView
) and a RemoteFile
(extends File
) and overrode all methods of the super-classes except File.hashCode()
and FileSystemView.createFileSystemRoot(File)
(this method is protected in FileSystemView
). All overridden methods call methods on the RMI-Server where the FileView
- and FileSystemView
from the server call the server-methods (like the JFileChooser
would do). I get the FileView
and the FileSystemView
on the server side from a dummy instantiated JFileChooser
.
So now what the system does:
- Start RMI-Server
- Start RMI-Client
- JFileChooser
gets the RemoteFileView
- JFileChooser
gets the RemoteFileSystemView
- JFileChooser
gets all the RemoteFiles
from the server and shows folders as well as files in the JFileChooser
So the behavior is good until now. And now the problem (where I can’t get rid of):
The initial view of the JFileChooser
(client) shows all Files of the home directory of the server. I can (per button click) switch to the parent directory until the system root (on windows for example the system drive „C:\“ ). From there (or from everywhere else) I can double-click on a folder to jump into it as long as this path exists on the client-system but the shown files and folders are from the server. If the path doesn’t exist on the client I can’t jump into it and browse this folder. So if anyone knows this behavior please help (I appreciate any solution :) ).
So I decided to code an own mouse listener that recognize double-clicks on the JFileChooser
. But if I double-click on a folder (in the JFileChooser
) nothing happens. If I highlight a folder (via click) and then double-click somewhere in the JFileChooser
(not in the File-View or a button) the listener recognize my double-click and jumps into the highlighted folder (hope this is clear enough).
I think the FileView
(on the JFileChooser
) lies over the JFileChooser
and should get it’s own listeners. Or I forgot something to code out.
The RMI-interface holds all methods which are called from the RemoteFileView
, RemoteFileSystemView
and the RemoteFile
and from the behavior of the system this should be ok.
I can of course poste some codes as well as more informations about the whole program. Posting all codes would be too much I guess.
EDIT: As this question may be "too broad" the more concrete version (which may solve my problem): Which listener fires on double click a folder in the JFileChooser? Can this listener be removed or set?
EDIT2:
I saw in this question: Repurposing JFileChooser that the JFileChooser fires on JFileChooser.APPROVE_SELECTION
whenever a file is choosen by double click. So I implemented this code:
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();
}
}
});
But unfortunately the action listener doesn't recognize any action inside the FileView (the component which shows the files) but does fire action events on button clicks (which I detected with the System.out..).
The problem as I described above are the components and their mouse listeners. So first you have to get your components and then add the listeners to it. So in a JFileChooser
we got a JList
and a JTable
. Both views can be switched by button klick. The JList
holds the files as well as the JTable
.
I found kind of solution here: https://community.oracle.com/thread/1350166?start=0&tstart=0
So I used some codes from there and implemented my mouse listeners:
The Listener for the 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);
And the listener for the 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);
}
}
});
With this solution I got the behavior I wanted.