Is there any way to handle what happens whenever I try to open a file. The file is a serialised ArrayList. when I open the file, it is de-serialised to an array then the information from the array is opened. The functionality for the actions to perform when opening this file and how to show it in an editor is already complete. I just wanted to be able to override the functionality in opening a file.
I started by simulating the problem using the code found here, i.e., I created a new Action that creates a serialized file consisting of a list of Patients:
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionRegistration; import org.openide.filesystems.FileUtil; import org.openide.util.NbBundle.Messages; @ActionID( category = "Tools", id = "org.patients.ser.SerializeAction") @ActionRegistration( displayName = "#CTL_SerializeAction") @ActionReference( path = "Menu/File", position = -100) @Messages("CTL_SerializeAction=Serialize") public final class SerializeAction implements ActionListener { List<Patient> pList = new ArrayList<>(); @Override public void actionPerformed(ActionEvent e) { pList.add(new Patient("Tom")); pList.add(new Patient("Dick")); pList.add(new Patient("Harry")); try { savePatientList(); } catch (FileNotFoundException ex) { } } private void savePatientList() throws FileNotFoundException { try { ObjectOutputStream os; //I created a "Serialized" folder in the layer, //so I know that the "Serialized" folder exists here: try (FileOutputStream fs = new FileOutputStream( FileUtil.toFile(FileUtil.getConfigFile("Serialized"). createData("Patients.ser")))) { os = new ObjectOutputStream(fs); os.writeObject(pList); } os.close(); System.out.println("Saved!"); } catch (IOException ex) { } } }
This leaves me with a "Patients.ser" file. And here is another Action, for deserializing the file and doing something with its content. Here, a TopComponent is created for each Patient in the List, but anything else could be done, of course.
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.List; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionRegistration; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; import org.openide.windows.TopComponent; @ActionID( category = "Build", id = "org.patients.ser.DeserializeAction") @ActionRegistration( displayName = "#CTL_DeserializeAction") @ActionReference( path = "Menu/File", position = 0) @Messages("CTL_DeserializeAction=Deserialize") public final class DeserializeAction implements ActionListener { private List<Patient> pList = new ArrayList<>(); @Override public void actionPerformed(ActionEvent e) { //Do some checking here to make sure the Serialized folder exists //and that it contains the ser files you're interested in: for (FileObject serialized : FileUtil.getConfigRoot().getFileObject("Serialized").getChildren()) { try { loadPatientList(serialized.getInputStream()); } catch (FileNotFoundException ex) { Exceptions.printStackTrace(ex); } } } private void loadPatientList(InputStream fs) { ObjectInputStream is; try { is = new ObjectInputStream(fs); pList = (List<Patient>) is.readObject(); for (Patient p : pList) { //As an example, //you can see that one TopComponent //is created for each Patient found in the List: TopComponent tc = new TopComponent(); tc.setDisplayName(p.getName()); tc.open(); tc.requestActive(); } fs.close(); is.close(); } catch (IOException | ClassNotFoundException ex) { } } }
Finally, to complete the scenario, here is the Patient class used by both Actions above.
public class Patient implements Serializable { String name; public Patient(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
A different approach is to create new File Type support (there's a tutorial and a wizard to help you do that) for SER files, using any MIME Type name you prefer, e.g., "application/x-ser". Then define the DataObject such that a text editor is not opened, assuming you don't want a text editor, while implementing Openable so that when the file is opened (via the "Open" action or by double-clicking on it), the same result as the above is produced:
public class SerDataObject extends MultiDataObject implements Openable { private List<Patient> pList = new ArrayList<>(); public SerDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { super(pf, loader); } @Override public void open() { try { loadPatientList(getPrimaryFile().getInputStream()); } catch (FileNotFoundException ex) { Exceptions.printStackTrace(ex); } } private void loadPatientList(InputStream fs) { ObjectInputStream is; try { is = new ObjectInputStream(fs); pList = (List<Patient>) is.readObject(); for (Patient p : pList) { //As an example, //you can see that one TopComponent //is created for each Patient found in the List: TopComponent tc = new TopComponent(); tc.setDisplayName(p.getName()); tc.open(); tc.requestActive(); } fs.close(); is.close(); } catch (IOException | ClassNotFoundException ex) { } } }