以下代码中的itemTree.stopEditing()出现问题。
我可以很好地编辑设备。编辑将Node文本从仅IP地址更改为beIP地址+主机名(使字符串变长)。问题是,编辑后,JTree显示IP,然后显示“ ...”
似乎树未更新其UI。我以为使用树的编辑功能会自动更新UI?我该如何解决?
this.setShowsRootHandles(true);
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
System.out.println("\n[MyItemTree]mousePressed");
MyItemTree itemTree = (MyItemTree) e.getSource();
TreePath tp = itemTree.getPathForLocation(e.getX(), e.getY());
Rectangle pathBounds = itemTree.getUI().getPathBounds(itemTree, tp);
TreePath[] selectionPaths = itemTree.getSelectionPaths();//what if this is empty?
Object lastPathComponent = tp.getLastPathComponent();// what if this is empty?
digOutNodesForSelection((DefaultMutableTreeNode) lastPathComponent, itemTree);
itemTree.setEditable(true);
ArrayList<DefaultMutableTreeNode> nodes = new ArrayList();
for (int i = 0; i < selectionPaths.length; i++) {
Object lastPathComponent1 = selectionPaths[i].getLastPathComponent();
//Should only be adding the Leaf Nodes here
if (lastPathComponent1 instanceof DefaultMutableTreeNode) {
nodes.add((DefaultMutableTreeNode) lastPathComponent1);
}
}
try {
DeviceEditor deviceEditor = new DeviceEditor(nodes);
itemTree.setCellEditor(deviceEditor);
deviceEditor.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent fe) {
// throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void focusLost(FocusEvent fe) {
itemTree.cancelEditing();
}
});
//add an actionListener to the deviceEditor for the cancel and update buttons
deviceEditor.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
System.out.println("ACTION COMMAND= " + ae.getActionCommand());
if ("Update".equals(ae.getActionCommand())) {
//get the Device From the editor.
//update all the nodes' userObjects to the values of the editor except the ones with <Multiple Values>
//stopEditing expects an Object from DeviceEditor. We need a way to stopEditing without providing an object.
itemTree.stopEditing(); //update the nodes
}
if ("Cancel".equals(ae.getActionCommand())) {
itemTree.cancelEditing();
}
}
});
} catch (NoSuchFieldException ex) {
}
// }
if (SwingUtilities.isRightMouseButton(e)) {
System.out.println("Right Mouse Button");
JPopupMenu itemMenu = new JPopupMenu();
{
JMenuItem deleteItem = new JMenuItem("Delete");
{
deleteItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
System.out.println("[MyItemTree]actionPerformed.deleteDevice");
TreePath[] selectionPaths = MyItemTree.this.getSelectionPaths();
System.out.println("[MyItemTree]SelectionPaths.length= " + selectionPaths.length);
for (TreePath path : selectionPaths) {
System.out.println("Here");
DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
Object userObject = node.getUserObject();
if (userObject instanceof MyItemTreeInterface) {
DefaultTreeModel model = (DefaultTreeModel) MyItemTree.this.getModel();
//model.nodeChanged(node);
DeviceCollection collection = (DeviceCollection) MyItemTree.this.collectionTreeInterface.getCollection();
System.out.println("Collection size before= " + collection.size());
collection.remove((DefaultDevice) userObject);
model.removeNodeFromParent(node);
System.out.println("Collection size after= " + collection.size());
MyItemTree.this.filter();
}
}
}
});
}
JMenuItem addMenuItem = new JMenuItem("Add");
itemMenu.add(addMenuItem);
itemMenu.add(deleteItem);
itemMenu.add(COPY_MENUITEM);
itemMenu.add(CUT_MENUITEM);
}
if (pathBounds != null && pathBounds.contains(e.getX(), e.getY())) {
EDIT_MENUITEM.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
//if a DefaultDevice cell was selected...
itemTree.startEditingAtPath(tp);
}
});
itemMenu.insert(EDIT_MENUITEM, 0);
itemMenu.addSeparator();
//build device popupmenu.
System.out.println("MENUITEMS= " + MyItemTreeInterface.MENUITEMS.size());
for (int i = 0; i < MyItemTreeInterface.MENUITEMS.size(); i++) {
itemMenu.add(MyItemTreeInterface.MENUITEMS.get(i));
}
itemMenu.show(itemTree, e.getX(), e.getY());//construct the popup and show.
System.out.println("number of selected paths= " + selectionPaths.length);
} else {
//Show the right click menu for the tree
System.out.println("[MyItemTree]rightButton on Tree");
itemTree.addMenusToPopup(collectionTreeInterface.getTreeMenu()).show(itemTree, e.getX(), e.getY());
}
}//end right click
if (SwingUtilities.isMiddleMouseButton(e)) {
System.out.println("[MyItemTree]middleButton");
if (pathBounds != null && pathBounds.contains(e.getX(), e.getY())) {
//Show middle click menu for Device
} else {
//Show middle click menu for Tree
}
}
}
});
DigoutNodes
private void digOutNodesForSelection(DefaultMutableTreeNode node, MyItemTree itemTree) {
System.out.println("DIG");
if (!node.isLeaf()) {
System.out.println("Node is not a Leaf");
int childCount = node.getChildCount();
System.out.println("Child Count= " + childCount);
DefaultTreeModel model = (DefaultTreeModel) itemTree.getModel();
for (int i = 0; i < childCount; i++) {
DefaultMutableTreeNode tempNode = (DefaultMutableTreeNode) node.getChildAt(i);
TreeNode[] pathToRoot = model.getPathToRoot(tempNode);
itemTree.getSelectionModel().addSelectionPath(new TreePath(pathToRoot));
if (tempNode.getChildCount() != 0) {
//Dig this node
System.out.println("Has Children, dig More...");
digOutNodesForSelection(tempNode, itemTree);
}
}
// System.out.println("SelectionPaths= " + itemTree.getSelectionPaths());
}
}
CollectionTreeInterface
public static interface CollectionTreeInterface<N> {
public TreeSet<SelectableFilterItem> getFilters();
public ArrayList<JMenuItem> getTreeMenu();
public ArrayList<JMenuItem> getDeviceMenu(Collection<N> c);
public void addPropertyChangeListener(PropertyChangeListener o);
// public Iterator iterator();
public TreeCellEditor getTreeCellEditor();
public TreeCellRenderer getTreeCellRenderer();
public Collection getCollection();
}
DeviceEdiotr实现TreeCellEditor。这是实现的方法
@Override
public Component getTreeCellEditorComponent(JTree jtree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
// this.tree = jtree;
return this;
}
@Override
public Object getCellEditorValue() {
DefaultMutableTreeNode node = this.nodes.get(0);
return (DefaultDevice) node.getUserObject();
}
@Override
public boolean isCellEditable(EventObject eo) {
//should be true only if it's a leaf.
return true;
}
@Override
public boolean shouldSelectCell(EventObject eo) {
//Don't Select
return false;
}
@Override
public boolean stopCellEditing() {
try {
System.out.println("\n [DeviceEditor] stopCellEditing()");
if (!this.addressField.getText().equals(DefaultDevice.MULTIVALUE)) {
multiValueDevice.setAddress(this.addressField.getText());
}
multiValueDevice.setHostName(this.hostNameField.getText());
multiValueDevice.setDeviceType(this.deviceTypeField.getText());
multiValueDevice.setLocation(this.locationField.getText());
multiValueDevice.setSerialNumber(this.serialField.getText());
multiValueDevice.setVendor(this.vendorField.getText());
multiValueDevice.setModel(this.modelField.getText());
multiValueDevice.setOS(this.osField.getText());
multiValueDevice.setDescription(this.descriptionField.getText());
multiValueDevice.setVersion(this.versionField.getText());
multiValueDevice.setDeviceType(this.deviceTypeField.getText());
// //Update Connect
multiValueDevice.setSelectedProtocol(this.currentProtocol);
//Update Display
multiValueDevice.setDisplayHostName(this.hostNameCheckBox.isSelected());
multiValueDevice.setDisplayIPV4Address(this.ipV4checkBox.isSelected());
multiValueDevice.setDisplayIPV6Address(this.ipV6CheckBox.isSelected());
ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Collection<Future<DefaultDevice>> futures = new ArrayList<>();
Iterator<DefaultMutableTreeNode> nodeC = nodes.iterator();
while (nodeC.hasNext()) {
//create Runnables for each nodeDevice to update it.
DefaultMutableTreeNode node = nodeC.next();
DefaultDevice nodeDevice = (DefaultDevice) node.getUserObject();
//update the node
futures.add((Future<DefaultDevice>) pool.submit(new UPDATE_RUNNABLE(nodeDevice, multiValueDevice)));
// SwingUtilities.invokeLater(new UPDATE_RUNNABLE(nodeDevice, editorDevice));
}
// DeviceEditor.UPDATE_DEVICES(nodes, multiValueDevice);
System.out.println("futures= " + futures.size());
for (Future<?> future : futures) {
try {
DefaultDevice get = (DefaultDevice) future.get();
} catch (InterruptedException ex) {
System.out.println("Exception 1");
return false;
} catch (ExecutionException ex) {
System.out.println("Exception 2");
return false;
}
}
return true;//only return true when all the tasks have been completed.
} catch (IPConverter.InvalidIPException ex) {
Exceptions.printStackTrace(ex);
return false;
}
}
@Override
public void cancelCellEditing() {
//do nothing
}
@Override
public void addCellEditorListener(CellEditorListener cl) {
this.cellListeners.add(cl);
}
@Override
public void removeCellEditorListener(CellEditorListener cl) {
this.cellListeners.remove(cl);
}