import bluej.extensions.*; import bluej.extensions.event.*; import java.net.URL; import javax.swing.*; import java.awt.event.*; /* * This is the starting point of a BlueJ Extension */ public class SimpleExtension extends Extension implements PackageListener { /* * When this method is called, the extension may start its work. */ public void startup (BlueJ bluej) { bluej.setMenuGenerator(new MenuBuilder()); Preferences myPreferences = new Preferences(bluej); bluej.setPreferenceGenerator(myPreferences); bluej.addPackageListener(this); } /* * A package has been opened. Print the name of the project it is part of. */ public void packageOpened ( PackageEvent ev ) { try { System.out.println ("Project " + ev.getPackage().getProject().getName() + " opened."); } catch (ExtensionException e) { System.out.println("Project closed by BlueJ"); } } /* * A package is closing. */ public void packageClosing ( PackageEvent ev ) { } /* * This method must decide if this Extension is compatible with the * current release of the BlueJ Extensions API */ public boolean isCompatible () { return true; } /* * Returns the version number of this extension */ public String getVersion () { return ("2003.11"); } /* * Returns the user-visible name of this extension */ public String getName () { return ("Simple Extension"); } public void terminate() { System.out.println ("Simple extension terminates"); } public String getDescription () { return ("A simple extension"); } /* * Returns a URL where you can find info on this extension. * The real problem is making sure that the link will still be alive in three years... */ public URL getURL () { try { return new URL("http://www.bluej.org/doc/writingextensions.html"); } catch ( Exception eee ) { // There is no reason at all that this should trow exception... System.out.println ("Simple extension: getURL: Exception="+eee.getMessage()); return null; } } } /* * This class implements the preference panel behaviour for a BlueJ extension */ class Preferences implements PreferenceGenerator { private JPanel myPanel; private JTextField color; private BlueJ bluej; public static final String PROFILE_LABEL="Favorite-Colour"; // Construct the panel, and initialise it from any stored values public Preferences(BlueJ bluej) { this.bluej = bluej; myPanel = new JPanel(); myPanel.add (new JLabel ("Favorite Colour")); color = new JTextField (40); myPanel.add (color); // Load the default value loadValues(); } public JPanel getPanel () { return myPanel; } public void saveValues () { // Save the preference value in the BlueJ properties file bluej.setExtensionPropertyString(PROFILE_LABEL, color.getText()); } public void loadValues () { // Load the property value from the BlueJ proerties file, default to an empty string color.setText(bluej.getExtensionPropertyString(PROFILE_LABEL,"")); } } /* This class shows how you can bind different menus to different parts of BlueJ * It is important to remembar the rules you have to follow. * - getToolsMenuItem, getClassMenuItem, getObjectMenuItem can be called at any time. * - They must generate a new JMenuItem every time. * - No reference to the JMenuItem should be stored in the extension. * - You must be quick in generating your menu. */ class MenuBuilder extends MenuGenerator { private ToolsAction aToolsAction; private ClassAction aClassAction; private ObjectAction aObjectAction; private BPackage curPackage; private BClass curClass; private BObject curObject; MenuBuilder() { aToolsAction = new ToolsAction("Click Tools"); aClassAction = new ClassAction("Click Class"); aObjectAction = new ObjectAction("Click Object"); } public JMenuItem getToolsMenuItem(BPackage aPackage) { return new JMenuItem(aToolsAction); } public JMenuItem getClassMenuItem(BClass aClass) { return new JMenuItem(aClassAction); } public JMenuItem getObjectMenuItem(BObject anObject) { return new JMenuItem(aObjectAction); } // A utility method which prints the objects involved in the current // menu invocation. private void printCurrentStatus(String header) { try { if (curObject != null) curClass = curObject.getBClass(); if (curClass != null) curPackage = curClass.getPackage(); System.out.println(header); if (curPackage != null) System.out.println(" Current Package=" + curPackage); if (curClass != null) System.out.println(" Current Class=" + curClass); if (curObject != null) System.out.println(" Current Object=" + curObject); } catch (Exception exc) { } } // Now the nested classes that instantiate the different menus. class ToolsAction extends AbstractAction { public ToolsAction(String menuName) { putValue(AbstractAction.NAME, menuName); } public void actionPerformed(ActionEvent anEvent) { printCurrentStatus("Tools menu:"); } } class ClassAction extends AbstractAction { public ClassAction(String menuName) { putValue(AbstractAction.NAME, menuName); } public void actionPerformed(ActionEvent anEvent) { printCurrentStatus("Class menu:"); } } class ObjectAction extends AbstractAction { public ObjectAction(String menuName) { putValue(AbstractAction.NAME, menuName); } public void actionPerformed(ActionEvent anEvent) { printCurrentStatus("Object menu:"); } } // and the methods which will be called in the main class when // each of the different menus are about to be invoked. public void notifyPostToolsMenu(BPackage bp, JMenuItem jmi) { System.out.println("Post on Tools menu"); curPackage = bp ; curClass = null ; curObject = null; } public void notifyPostClassMenu(BClass bc, JMenuItem jmi) { System.out.println("Post on Class menu"); curPackage = null ; curClass = bc ; curObject = null; } public void notifyPostObjectMenu(BObject bo, JMenuItem jmi) { System.out.println("Post on Object menu"); curPackage = null ; curClass = null ; curObject = bo; } }