Javaв„ў EE 5 Tutorial, The (3rd Edition)
Our next step will be to build a table of objects like the list I showed in the The Plan section and to build the menu from that. I expect this to be a bit tricky, because I foresee that we ll have to change the code for everyone who is now using that Tags enum:
public enum Tags { Pre = 1, Section = 2, UnorderedList = 3, ListItem = 4, Paragraph = 5, OrderedList = 6 }
We ll allow the compiler to tell us what to do, and we ll rely on the tests to get things working. First, let s build a little class. This class is so dull that it could even be a struct, but we ll use a class anyway:
class InsertAction { private string menuString; private string[] tagsToInsert; private string[] tagsToSkip; public InsertAction(string menu, string[] inserts, string[] skips) { menuString = menu; tagsToInsert = inserts; tagsToSkip = skips; } public string MenuString { get { return menuString; } } public string[] TagsToInsert { get { return tagsToInsert; } } public string[] TagsToSkip { get { return tagsToSkip; } } }
There s nothing special here; this is just a simple no-behavior structure class. For now, it s actually inside the TextModel.cs file, but we might move it out later. Now let s make a table of these objects in TextModel class:
private static InsertAction[] insertActions = new InsertAction[] { new InsertAction("Insert &Pre", new string[] { "<pre></pre>" }, new string[] { "<pre>" }), new InsertAction("Insert &Section", new string[] {"<sect1><title></title>","</sect1>" }, new string[] {"<sect1><title>" }), new InsertAction("Insert &UL", new string[] {"<UL>","<LI></LI>","</UL>"}, new string[] {"<UL>", "<LI>" }), new InsertAction("Insert &OL", new string[] {"<OL>","<LI></LI>","</OL>"}, new string[] {"<OL>", "<LI>" }) };
I m not sure why, but Microsoft Visual Studio can t seem to figure out how to format those lines. The code compiles just fine but formats all over to the right side, the way it does when it thinks there s something wrong. Anyway, that s the table. We ll add a property to get it:
public InsertAction[] InsertActions { get { return insertActions; } }
Now comes the tricky part. We want to use this table to create our menus . When we do that, some things are likely to break. Let s just go ahead and do it:
foreach (InsertAction action in model.InsertActions) { insertMenus.Add(new NotepadMenuItem ( action.MenuString, new EventHandler(MenuInsertTags), action)); }
That s certainly what we want to say: just create a new menu item with the action s string and attach the action to the menu item. Our NotepadMenuItem constructor won t like that. It looks like this:
class NotepadMenuItem : MenuItem { private TextModel.Tags command; public NotepadMenuItem (String menuString, EventHandler handler, TextModel.Tags tag) :base(menuString, handler){ command = tag; } public TextModel.Tags Command { get { return command; } } }
It needs to look like this:
class NotepadMenuItem : MenuItem { private InsertAction action; public NotepadMenuItem (String menuString, EventHandler handler, InsertAction act) :base(menuString, handler){ action = act; } public InsertAction Action { get { return action; } } }
We change it that way and compile to see who complains. The compiler points here:
void MenuInsertTags(object obj, EventArgs ea) { NotepadMenuItem item = (NotepadMenuItem) obj; GetText(); model.InsertTags(item.Command); PutText(textbox, model.LinesArray(), model.SelectionStart); }
The NotepadMenuItem no longer understands Command. Here, we ll just pass the action back to the TextModel and require TextModel to deal with it. We start here:
public void InsertTags(Tags command) { int cursorLine = LineContainingCursor(); lines.InsertRange(cursorLine+1, InsertStrings(command)); selectionStart = NewSelectionStart(cursorLine + 1, SkipStrings(command)); }
That needs to become this:
public void InsertTags( InsertAction action ) { int cursorLine = LineContainingCursor(); lines.InsertRange(cursorLine+1, action.TagsToInsert ); selectionStart = NewSelectionStart(cursorLine + 1, action.TagsToSkip ); }
I m adding that method, not replacing it, because I know that some methods are calling the InsertTags() method that uses a Tags variable. This change makes the compiler messages go away. And the tests run!
Категории