





















































(For more resources on NetBeans, see here.)
In Swing, an Action object provides an ActionListener for Action event handling, together with additional features, such as tool tips, icons, and the Action's activated state. One aim of Swing Actions is that they should be reusable, that is, can be invoked from a menu item as well as a related toolbar button and keyboard shortcut.
The NetBeans Platform provides an Action framework enabling you to organize Actions declaratively. In many cases, you can simply reuse your existing Actions exactly as they were before you used the NetBeans Platform, once you have declared them. For more complex scenarios, you can make use of specific NetBeans Platform Action classes that offer the advantages of additional features, such as more complex displays in toolbars and support for context-sensitive help.
Before you begin working with global Actions, let's make some changes to our application. It should be possible for the TaskEditorTopComponent to open for a specific task. You should therefore be able to pass a task into the TaskEditorTopComponent. Rather than the TaskEditorPanel creating a new task in its constructor, the task needs to be passed into it and made available to the TaskEditorTopComponent.
On the other hand, it may make sense for a TaskEditorTopComponent to create a new task, rather than providing an existing task, which can then be made available for editing. Therefore, the TaskEditorTopComponent should provide two constructors. If a task is passed into the TaskEditorTopComponent, the TaskEditorTopComponent and the TaskEditorPanel are initialized. If no task is passed in, a new task is created and is made available for editing.
Furthermore, it is currently only possible to edit a single task at a time. It would make sense to be able to work on several tasks at the same time in different editors. At the same time, you should make sure that the task is only opened once by the same editor. The TaskEditorTopComponent should therefore provide a method for creating new or finding existing editors. In addition, it would be useful if TaskEditorPanels were automatically closed for deleted tasks.
public TaskEditorPanel() {
initComponents();
this.pcs = new PropertyChangeSupport(this);
}
public void updateTask(Task task) {
Task oldTask = this.task;
this.task = task;
this.pcs.firePropertyChange(PROP_TASK, oldTask, this.task);
this.updateForm();
}
private static Map<Task, TaskEditorTopComponent> tcByTask =
new HashMap<Task, TaskEditorTopComponent>();
public static TaskEditorTopComponent findInstance(Task task) {
TaskEditorTopComponent tc = tcByTask.get(task);
if (null == tc) {
tc = new TaskEditorTopComponent(task);
}
if (null == taskMgr) {
taskMgr = Lookup.getDefault().lookup(TaskManager.class);
taskMgr.addPropertyChangeListener(newListenForRemovedNodes());
}
return tc;
}
private class ListenForRemovedNodes implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent arg0) {
if
(TaskManager.PROP_TASKLIST_REMOVE.equals
(arg0.getPropertyName())) {
Task task = (Task) arg0.getNewValue();
TaskEditorTopComponent tc = tcByTask.get(task);
if (null != tc) {
tc.close();
tcByTask.remove(task);
}
}
}
}
private TaskEditorTopComponent() {
this(Lookup.getDefault().lookup(TaskManager.class));
}
private TaskEditorTopComponent(TaskManager taskMgr) {
this((taskMgr != null) ? taskMgr.createTask() : null);
}
private TaskEditorTopComponent(Task task) {
initComponents();
// ...
((TaskEditorPanel) this.jPanel1).updateTask(task);
this.ic.add(((TaskEditorPanel) this.jPanel1).task);
this.associateLookup(new AbstractLookup(this.ic));
tcByTask.put(task, this);
}
public String getTaskId() {
Task task = ((TaskEditorPanel) this.jPanel1).task;
return (null != task) ? task.getId() : "";
}
With that our preparations are complete and you can turn to the following discussion on Actions.