public void register(Application app) { super.register(app); importMenuActions = new Vector(1); importMenuActions.add(new ImportImageAction("Image")); } public Object getStaticMenuElements(String menu) { if (menu.equals(PluginElementTypes.OPEN_ACTIONS)) return importMenuActions; else return null; }Now we will return directly the
AbstractMDIAction
:public void register(MDIApplication app) { super.register(app); importImageAction = new ImportImageAction((GUIApplication) app, "Image"); } public Object getStaticMenuElements(String menu) { if (menu.equals(PluginElementTypes.OPEN_ACTIONS)) return importImageAction else return null; }
public void run() throws Exception { app.stopTime(this); // don't show the progress bar JFileChooser chooser = new JFileChooser("Open Image"); chooser.setDialogTitle("Open Image"); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); if (chooser.showOpenDialog(app.getApplicationWindow()) == JFileChooser.APPROVE_OPTION) { app.startTime(this); // show the progress bar and start to count File file = chooser.getSelectedFile(); BufferedImage image = ImageIO.read(file); if (image == null) throw new Exception("Bad File type"); JScrollPane pane = new JScrollPane(new ImagePanel(image)); app.addTab(pane, image, file.getName()); } else { app.noWriteMessages(); } }
public class ImportDocumentAction extends AbstractMDIAction { public ImportDocumentAction(String name) { super(appli, name); this.setDescription("Open Document", "Open Document"); } public void run() throws Exception { } }And the Plugin itself:
public class OpenDocumentPlugin extends AbstractPlugin { public static final String OPEN_DOCUMENTS = "OpenDocuments"; public static final String OPEN_DOCUMENTS_DESC = "Open Documents Plugin"; private AbstractAction importDocAction; // Plugin importMenuItem public OpenDocumentPlugin() { } public String getPluginName() { return OPEN_DOCUMENTS; } public Object getPluginProperty(String prop) { if (prop.equals(PluginElementTypes.PROPERTY_DATE)) return "undef"; else if (prop.equals(PluginElementTypes.PROPERTY_DESC)) return OPEN_DOCUMENTS_DESC; else if (prop.equals(PluginElementTypes.PROPERTY_VERSION)) return "0.1"; else return null; } public void register(MDIApplication appli) { super.register(appli); importDocAction = new ImportDocumentAction((GUIApplication)appli, "Document"); JToolBar tbar = new JToolBar("OpenDocument"); tbar.add(analyseDocAction); appli.getToolBarPanel().add(tbar); } public Object getStaticMenuElements(String menu) { if (menu.equals(PluginElementTypes.OPEN_ACTIONS)) return importDocAction; else return null; } public Object getDynamicMenuElements(String menuKey, FileProperties tab) { return null; } }To be able to load this new Plugin in the Application, we must create another jar for the Plugin with this class in the "plugins" directory. Also we must create a Manifest for this Plugin like:
MDIPluginClass: org.samples.plugins.OpenDocumentPluginWe can now properly implement the
run()
method for our Action. There is nothing new here:public void run() throws Exception { app.stopTime(this); JFileChooser chooser = new JFileChooser("Open Document"); chooser.setDialogTitle("Save Document"); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); if (chooser.showOpenDialog(app.getApplicationWindow()) == JFileChooser.APPROVE_OPTION) { app.startTime(this); URL url = chooser.getSelectedFile().toURL(); File file = chooser.getSelectedFile(); JEditorPane pane = new JEditorPane(); JScrollPane scroll = new JScrollPane(pane); pane.setEditable(true); pane.setPage(url); app.addTab(pane, pane.getDocument(), file.getName()); } else { app.noWriteMessages(); } }Text files can now be opened and we have the following result:
public interface ElementTypes { public String IMAGE = "image"; public String TEXT = "text"; }Now we will add a MetaData, with the TEXT type, to our opened text files:
protected class ImportDocumentAction extends AbstractMDIAction { public void run() throws Exception { ... pane.setEditable(true); pane.setPage(url); MetaData meta = new MetaData(2); meta.put(ElementTypes.TEXT, Boolean.TRUE); FileProperties prop = new FileProperties(file.getName(), scroll, pane.getDocument(), meta); app.addTab(pane, prop); ...The
FileProperties
contains all the properties of the tab. Before now, it was created "under the hood" by the Application when we called the TabbedApplication.addTab(JComponent, Object, String) method. We will now handle this ourselves. The FileProperties is initialized with:public class ImportImageAction extends AbstractMDIAction { public void run() throws Exception { ... JScrollPane pane = new JScrollPane(new ImagePanel(image)); MetaData meta = new MetaData(2); meta.put(ElementTypes.IMAGE, Boolean.TRUE); FileProperties prop = new FileProperties(file.getName(), pane, image, meta); app.addTab(pane, prop); ... } }We will now need to use this MetaDatas for our
AnalyseAction
, else we will still have the same Exception.
public class SecondMenuFactory extends AbstractMDIMenuFactory { private static MetaData acceptAnalyseMeta = new MetaData(); static { acceptAnalyseMeta.put(ElementTypes.IMAGE, Boolean.TRUE); } ... }Now the Analyse action will not be a static element any more. Instead, it will be added to the dynamic menus, such that we will be able to compare our static Metadata template to the selected MetaData dynamically:
public class SecondMenuFactory extends AbstractMDIMenuFactory { protected void initMenus() { ... analyseImageAction = new AnalyseImageAction(appli, "Analyse"); this.addToDynamicMenuMap("AnalyseKey", analyseImageAction); ... } ... protected Object getDynamicMenuItems(FileProperties prop, String menuKey) { if (menuKey.equals(ElementTypes.ANALYSE_IMAGE_KEY)) { MetaData properties = prop.getMetaData(); if (properties.isCompatibleWith(acceptAnalyseMeta, false)) return analyseImageAction; else return null; } else return null; } }We now test the compatibility of the MetaData with our static "template" before trying to analyse it:
public class SecondMenuFactory extends AbstractMDIMenuFactory { ... private JMenu savemenu = new JMenu("SaveAs"); ... protected void initMenus() { ... dynamicMenuKeyMap.put(PluginElementTypes.SAVEAS_ACTIONS, savemenu); ... filemenu.add(savemenu); }We added the savemenu to the AbstractMDIMenuFactory.dynamicMenuKeyMap, mapped to the PluginElementTypes.SAVEAS_ACTIONS key. Now we will look for dynamic content under this menu, for the plugins and the main application.
public class SaveImageAction extends AbstractMDIAction { public SaveImageAction(String name) { super(appli, name); this.setDescription("Save Image", "Save Image"); } public void run() throws Exception { if (app.getSelectedProperties() != null) { app.stopTime(this); JFileChooser chooser = new JFileChooser("Save Image"); chooser.setDialogTitle("Save Image"); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); if (chooser.showSaveDialog(app.getApplicationWindow()) == JFileChooser.APPROVE_OPTION) { app.startTime(this); BufferedImage image = (BufferedImage)app.getSelectedProperties().getObject(); File file = chooser.getSelectedFile(); ImageIO.write(image, "jpg", file); } else { app.noWriteMessages(); } } else { app.noWriteMessages(); } } }And we use your newly creatd action in the OpenImagePlugin:
public class OpenImagePlugin extends AbstractMDIPlugin { public static final String OPEN_IMAGES = "OpenImages"; public static final String OPEN_IMAGES_DESC = "Second Open Images Plugin"; private ImportImageAction importImageAction; private SaveImageAction saveImageAction = new SaveImageAction("Image"); ; private static MetaData acceptSaveAsMeta = new MetaData(); static { acceptSaveAsMeta.put(ElementTypes.IMAGE, Boolean.TRUE); } public OpenImagePlugin() { } ... public Object getDynamicMenuElements(String menuKey, FileProperties prop) { if (menuKey.equals(PluginElementTypes.SAVEAS_ACTIONS)) { MetaData properties = prop.getMetaData(); if (properties.isCompatibleWith(acceptSaveAsMeta, false)) return saveImageAction; else return null; } else return null; } }We return null if the properties are not compatible, in other words if the selected tab is not of the IMAGE type. But if the selected tab is of the IMAGE type, we return the
saveImageAction
Action. The SaveAs menu will be constructed dynamically, depending on the type of the selected tab.public class SaveDocumentAction extends AbstractMDIAction { public SaveDocumentAction(String name) { super(appli, name); this.setDescription("Save Document", "Save Document As Plain text File"); } public void run() throws Exception { if (app.getSelectedProperties() != null) { app.stopTime(this); JFileChooser chooser = new JFileChooser("Save Document"); chooser.setDialogTitle("Save Document"); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); if (chooser.showSaveDialog(app.getApplicationWindow()) == JFileChooser.APPROVE_OPTION) { app.startTime(this); File file = chooser.getSelectedFile(); Document doc = (Document)app.getSelectedProperties().getObject(); String text = doc.getText(0, doc.getLength()); BufferedWriter writer = new BufferedWriter(new FileWriter(file)); writer.write(text); writer.flush(); writer.close(); } } else app.noWriteMessages(); } }And the Plugin itself:
public class OpenDocumentPlugin extends AbstractMDIPlugin { public static final String OPEN_DOCUMENTS = "OpenDocuments"; public static final String OPEN_DOCUMENTS_DESC = "Open Documents Plugin"; private AbstractAction importDocAction; private AbstractAction saveDocAction; private static MetaData acceptSaveAsMeta = new MetaData(); static { acceptSaveAsMeta.put(ElementTypes.TEXT, Boolean.TRUE); } public OpenDocumentPlugin() { } @Override public void register(MDIApplication appli) throws Exception { super.register(appli); importDocAction = new ImportDocumentAction((GUIApplication) appli, "Document"); saveDocAction = new SaveDocumentAction((GUIApplication) appli, "Document"); } public Object getDynamicMenuElements(String menuKey, FileProperties tab) { if (menuKey.equals(PluginElementTypes.SAVEAS_ACTIONS)) { MetaData properties = tab.getMetaData(); if (properties.isCompatibleWith(acceptSaveAsMeta, false)) return saveDocAction; else return null; } else return null; } } }Now the SaveAs menu will depend on the selected tab.
AbstractMDIMenuFactory
to get the toolbar:public class SecondMenuFactory extends AbstractMDIMenuFactory { protected void initMenus() { ... analyseImageAction = new AnalyseImageAction(appli, "Analyse"); // create toolbar JToolBar tbar = new JToolBar("Standard"); tbar.add(analyseImageAction); this.getToolBarPanel().add(tbar); ... } }This is done! Now we have a Toolbar, and it will react as the Analyse item:
public class OpenDocumentPlugin extends AbstractPlugin { ... protected AbstractAction analyseDocAction; public void register(MDIApplication appli) { super.register(appli); importDocAction = new ImportDocumentAction((GUIApplication) appli, "Document"); saveDocAction = new SaveDocumentAction((GUIApplication) appli, "Document"); analyseDocAction = new AnalyseDocumentAction((GUIApplication) appli, "Document"); appli.getMenuFactory().addToDynamicMenuMap("Analyse", analyseDocAction); JToolBar tbar = new JToolBar("OpenDocument"); tbar.add(analyseDocAction); appli.getToolBarPanel().add(tbar); } public Object getDynamicMenuElements(String menuKey, FileProperties tab) { if (menuKey.equals("Analyse")) { MetaData properties = tab.getMetaData(); if (properties.isCompatibleWith(acceptSaveAsMeta, false)) return analyseDocAction; else return null; } else if (menuKey.equals(PluginElementTypes.SAVEAS_ACTIONS)) { MetaData properties = tab.getMetaData(); if (properties.isCompatibleWith(acceptSaveAsMeta, false)) return saveDocAction; else return null; } else return null; } }As for other dynamic menus (and even if there it is only a button on a Toolbar), we have to register the associated Action under a specific key, and return it when asked by the Application in the AbstractMDIPlugin.getDynamicMenuElements(String, FileProperties) method.
Copyright 2006-2023 Herve Girod. All Rights Reserved. Documentation and source under the LGPL v2 and Apache 2.0 licences