Files
allwpilib/networktables/OutlineViewer/src/edu/wpi/first/tableviewer/OutlineFrame.java

166 lines
6.3 KiB
Java
Raw Normal View History

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.wpi.first.tableviewer;
import edu.wpi.first.tableviewer.TableEntryData.EntryType;
import edu.wpi.first.tableviewer.dialog.AbstractAddDialog;
import edu.wpi.first.wpilibj.networktables2.NetworkTableNode;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.prefs.Preferences;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import org.netbeans.swing.outline.DefaultOutlineModel;
import org.netbeans.swing.outline.Outline;
import org.netbeans.swing.outline.OutlineModel;
public class OutlineFrame extends JFrame implements ITableListener {
private final Outline outline;
private final BranchNode rootBranch;
private final NetworkTableNode node;
private final boolean showMetadata;
private final Preferences prefs = Preferences.userNodeForPackage(getClass());
public OutlineFrame(String title, NetworkTableNode node, boolean showMetadata) {
this.node = node;
this.showMetadata = showMetadata;
setTitle(title);
setDefaultCloseOperation(EXIT_ON_CLOSE);
rootBranch = new BranchNode(node, "", "Root");
DefaultTreeModel outlineTreeModel = new DefaultTreeModel(rootBranch);
OutlineModel outlineModel = DefaultOutlineModel.createOutlineModel(
outlineTreeModel, new NetworkTableRowModel(), true, "Key");
outline = new Outline();
outline.setModel(outlineModel);
AbstractAddDialog.setOutline(outline);
AbstractTreeNode.setOutline(outline);
AbstractTreeNode.setTreeModel(outlineTreeModel);
outline.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
TreePath path = outline.getClosestPathForLocation(e.getX(), e.getY());
AbstractTreeNode node = (AbstractTreeNode) path.getLastPathComponent();
if (e.getClickCount() == 2) { // toggle boolean value
// commented out because the deselection makes double clicking
// difficult and annoying to do accurately
// if (node instanceof LeafNode) {
// LeafNode l = (LeafNode) node;
// if (l.getData().getType() == EntryType.BOOLEAN) {
// l.getData().setValue(!(boolean) l.getData().getValue());
// }
// }
} else if (SwingUtilities.isRightMouseButton(e)) { // create a menu
if (node instanceof BranchNode) {
((BranchNode) node).getMenu(path).show(outline, e.getX(), e.getY());
}
}
}
});
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
prefs.putInt("WindowX", getX());
prefs.putInt("WindowY", getY());
prefs.putInt("Width", getWidth());
prefs.putInt("Height", getHeight());
}
@Override
public void windowOpened(WindowEvent e) {
// default to top-left corner
setLocation(prefs.getInt("WindowX", 0),
prefs.getInt("WindowY", 0));
// default to 600x400
setSize(prefs.getInt("Width", 600),
prefs.getInt("Height", 400));
}
});
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewportView(outline);
add(scrollPane, BorderLayout.CENTER);
node.addTableListener(this, true);
}
@Override
public void valueChanged(ITable source, final String key, final Object value, boolean isNew) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getBranchesToEntry(key, value);
}
});
}
private void getBranchesToEntry(final String fullKey, Object value) {
// a list of all the subtable names leading up to the entry in the given key
// this splits by / and removes empty // elements
CustomList<String> subTableNames = splitDiscardingEmpty(fullKey, "/");
String key = "";
AbstractTreeNode currentNode = rootBranch, parentNode;
for (String name : subTableNames) {
parentNode = currentNode;
currentNode = currentNode.get(name);
key += "/" + name;
if (subTableNames.getLast() == name) { // leaf
if (currentNode == null) {
currentNode = new LeafNode(node, key, new TableEntryData(name, value));
if (currentNode.data.isMetadata() && !showMetadata) {
// don't show metadata directly
// instead, show the value in the branch's "Type" field
parentNode.data.setType(EntryType.getEntryType(currentNode.data.getValue().toString()));
} else {
parentNode.add(currentNode);
TreePath path = new TreePath(currentNode.getPath());
outline.expandPath(path);
}
} else {
((LeafNode) currentNode).updateValue(value);
}
} else if (currentNode == null) {
currentNode = new BranchNode(node, key, name);
parentNode.add(currentNode);
}
}
}
private CustomList<String> splitDiscardingEmpty(String str, String separator) {
CustomList<String> results = new CustomList<>();
for (String string : str.split(separator)) {
if (string.length() > 0) {
results.add(string);
}
}
return results;
}
private class CustomList<E> extends ArrayList<E> {
public E getLast() {
return get(size() - 1);
}
}
}