Previous | Next |
Hello3 expands on Hello2 by giving your end user the ability to undo and redo changes made to the component, in this case, changing the string contained by the component's model. You enable undo and redo by using the command processing mechanism to effect any changes to the component. Hello3 implements a new class, StringCommand, that is used to reset the model's string field. The view creates a command and submits it to the component's command processor to be executed. The command processor is constructed and maintained by the component's controller. You don't need to do any work to build or activate the command processor--just use the framework defaults.
Using the command processing mechanism automatically causes the controller to enable the Undo and Redo functions in the component toolbar and Edit menu. The Undo function is enabled as soon as the user has issued at least one undoable command. The Redo function is enabled when the user has undone that command. The controller also creates customized menu items for Undo and Redo, based on the label you provide when you create each command:
Generating Hello3 code with the wizard
StringCommand.java
Hello3View.java
Hello3Model.java
Hello3.java
Hello3Resources.java
Hello3BeanInfo.java
You build and run Hello3 using wizard-generated batch files, as described in Step 1.
To generate the code for Hello3, use the wizard to create a new project named Hello3. Follow the instructions in Step 2 to set up the model and view.
You also need to generate the basic code for StringCommand. To do this:
The
wizard appends "Command" to the string you typed in the
name field. For example, if you type in "String," it
generates a command named "StringCommand".
You're ready now to generate the code from the code generation screen. The wizard generates StringCommand, Hello3Model, Hello3View, Hello3, and Hello3Resources, plus the WizGen.java and batch files. Press the Generate All Files button to generate the files.
The source code shown here differentiates between code generated by the wizard, and code you add or modify. Wizard-generated code is shown in green.
See WebRunner\BeanTools\samples\hello3 for full source code files for each class. The source code shown here does not show the comments generated by the wizard. Do NOT remove these comments from the source code files or you won't be able to reopen the project with the wizard.
To implement a command, you need to:
By default commands are serially undoable. This means
that the user can both undo and redo commands in the order in
which they were originally executed. You can also create commands
that specifically cannot be undone, or that are not maintained
within the command log (for example, commands that do not cause a
change in model data). Pass one of the variables kCantUndo or
kNoChange to create one of these types of commands.
Extend the default command class | public class StringCommand extends Command implements WizGen { |
Build a command with the new string for the specified model, getting the command label from the resource file | public StringCommand(Hello3Model model, String string) { ResourceBundle resources = ResourceBundle.getBundle("hello3.Hello3Resources"); setLabel(resources.getString("String Change")); this.model = model; this.string = string; } |
Saves the current string and performs the change | protected void handleDo() { oldString = model.getString(); handleRedo(); } |
Sets the string back to the data saved by handleDo | protected void handleUndo() { model.setString(oldString); } |
Redoes the command | protected void handleRedo() { model.setString(string); } |
Data used for undo and redo | private Hello3Model model; private String string; private String oldString; } |
The only difference between Hello2View and Hello3View is in the keyReleased method. In Hello3View, the keyReleased method creates a StringCommand to encapsulate the correct change to the model. To create the command object, it passes in:
To add the command to the command processor for execution, call the component controller's addAndDo method.
View methods for initialization, notification and event handling | public class Hello3View extends ModelView implements WizGen, KeyListener { public Hello3View() { textField = new TextField(30); add(textField); textField.addKeyListener(this); } public void handleModelChange(ModelChangeEvent event) { super.handleModelChange(event); repaint(); } public void handleModelSelectionChange(ModelChangeEvent event) { repaint(); } public void paint(Graphics g) { Hello3Model model = (Hello3Model)getModel(); g.drawString(model.getString(), 10, 50); } public Dimension getPreferredSize() { return new Dimension(400, 300); } public void keyTyped(KeyEvent evt) { } public void keyPressed(KeyEvent evt) { } |
When the user presses the enter (return) key, create a StringCommand with the input string, and send it to the command processor | public void keyReleased(KeyEvent evt) { if (evt.getKeyChar() == '\n') { getComponentController().addAndDo(new StringCommand ((Hello3Model)getModel(), textField.getText())); } } |
Data field used in the UI | private TextField textField; } |
Hello3Model is essentially identical to Hello2Model, providing methods for accessing and persisting the model's string data field.
Hello3Model | public class Hello3Model extends Model implements WizGen { public Hello3Model() { string = "Hello World!"; } public String getFileExtension() { return "hl3"; } public String getString() { return string; } public void setString(String string) { this.string = string; setModelChanged(true); notifyOfModelChange(null); } private String string; } |
The controller for Hello3 components is the same as the Hello2 controller, creating Hello3Model and Hello3View objects, and reading in the resources specified by Hello3Resources.
Set up a Hello3 component | public class Hello3 extends ComponentController implements WizGen, KeyListener { public Hello3() { try { setResourceBundle(ResourceBundle.getBundle("hello3.Hello3Resources")); } catch (MissingResourceException e) { new ExceptionDialog(null, "Can't find resource file", e); } setModel(new Hello3Model()); setView(new Hello3View()); } public static void main(String args[]) { setApplicationMain(true); new Hello3(); } public void keyTyped(KeyEvent evt) { ((KeyListener)getView()).keyTyped(evt); }public void keyPressed(KeyEvent evt) { ((KeyListener)getView()).keyPressed(evt); }public void keyReleased(KeyEvent evt) { ((KeyListener)getView()).keyReleased(evt); }public String getString() { return ((Hello3Model)getModel()).getString(); }public void setString(String string) { ((Hello3Model)getModel()).setString(string); } } |
Hello3Resources is almost identical to the resources file for Hello2, but uses the component name "Hello3" and the file extension "hl3".
Component name and command label for Hello3 components | public class Hello3Resources extends ListResourceBundle { public Object[][] getContents() { return contents; } static final Object[][] contents = { {"Application", "Hello3"}, {"String Change", "String Change"}, }; }; |
This file is generated to allow user to change the property, method, and event descriptors which are displayed in a visual builder. By default, everything is displayed to the developer inside a builder or a tester like the Bean Tester.
Previous | Next |
Copyright ©
Taligent, Inc. 1996 - 1997.
Copyright © IBM Corporation 1996 - 1997.
All Rights Reserved.