| author | wenzelm | 
| Tue, 10 Dec 2024 21:06:04 +0100 | |
| changeset 81572 | 693a95492008 | 
| parent 81497 | da807cf1e461 | 
| child 82142 | 508a673c87ac | 
| permissions | -rw-r--r-- | 
| 81323 | 1 | /* Title: Pure/GUI/tree_view.scala | 
| 2 | Author: Makarius | |
| 3 | ||
| 81330 | 4 | Tree view with sensible defaults. | 
| 81323 | 5 | */ | 
| 6 | ||
| 7 | package isabelle | |
| 8 | ||
| 9 | import javax.swing.JTree | |
| 81329 | 10 | import javax.swing.tree.{MutableTreeNode, DefaultMutableTreeNode, DefaultTreeModel,
 | 
| 81494 | 11 | TreeSelectionModel, TreeCellRenderer, DefaultTreeCellRenderer} | 
| 81323 | 12 | |
| 13 | ||
| 81329 | 14 | object Tree_View {
 | 
| 15 | type Node = DefaultMutableTreeNode | |
| 16 | ||
| 17 |   object Node {
 | |
| 18 | def apply(obj: AnyRef = null): Node = | |
| 19 | if (obj == null) new DefaultMutableTreeNode else new DefaultMutableTreeNode(obj) | |
| 20 | ||
| 21 | def unapply(tree_node: MutableTreeNode): Option[AnyRef] = | |
| 22 |       tree_node match {
 | |
| 81380 
83012fe97282
revert 1206400b9b48: proper Node.unapply for Node.apply(null);
 wenzelm parents: 
81377diff
changeset | 23 | case node: Node => Some(node.getUserObject) | 
| 81329 | 24 | case _ => None | 
| 25 | } | |
| 26 | } | |
| 81496 | 27 | |
| 81497 | 28 |   class Cell_Renderer extends DefaultTreeCellRenderer {
 | 
| 29 | def setup(value: AnyRef): Unit = setIcon(null) | |
| 30 | ||
| 31 | override def getTreeCellRendererComponent( | |
| 32 | tree: JTree, | |
| 33 | value: AnyRef, | |
| 34 | selected: Boolean, | |
| 35 | expanded: Boolean, | |
| 36 | leaf: Boolean, | |
| 37 | row: Int, | |
| 38 | hasFocus: Boolean | |
| 39 |     ): java.awt.Component = {
 | |
| 40 | super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus) | |
| 41 | setup(value) | |
| 42 | this | |
| 43 | } | |
| 81496 | 44 | } | 
| 81329 | 45 | } | 
| 46 | ||
| 81325 | 47 | class Tree_View( | 
| 81329 | 48 | val root: Tree_View.Node = Tree_View.Node(), | 
| 81325 | 49 | single_selection_mode: Boolean = false | 
| 50 | ) extends JTree(root) {
 | |
| 51 | def get_selection[A](which: PartialFunction[AnyRef, A]): Option[A] = | |
| 52 |     getLastSelectedPathComponent match {
 | |
| 81380 
83012fe97282
revert 1206400b9b48: proper Node.unapply for Node.apply(null);
 wenzelm parents: 
81377diff
changeset | 53 | case Tree_View.Node(obj) if obj != null && which.isDefinedAt(obj) => Some(which(obj)) | 
| 81325 | 54 | case _ => None | 
| 55 | } | |
| 81323 | 56 | |
| 81483 | 57 |   def init_model(body: => Unit): Unit = {
 | 
| 81325 | 58 | clearSelection() | 
| 59 | root.removeAllChildren() | |
| 81483 | 60 | body | 
| 61 | expandRow(0) | |
| 62 | reload_model() | |
| 81325 | 63 | } | 
| 64 | ||
| 65 | def reload_model(): Unit = | |
| 81326 | 66 |     getModel match {
 | 
| 67 | case model: DefaultTreeModel => model.reload(root) | |
| 68 | case _ => | |
| 69 | } | |
| 81325 | 70 | |
| 71 | ||
| 72 | /* init */ | |
| 73 | ||
| 81497 | 74 | setCellRenderer(new Tree_View.Cell_Renderer) | 
| 81494 | 75 | |
| 81325 | 76 | setRowHeight(0) | 
| 81323 | 77 | |
| 78 |   if (single_selection_mode) {
 | |
| 81325 | 79 | getSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION) | 
| 81323 | 80 | } | 
| 81 | ||
| 82 | // follow jEdit | |
| 83 |   if (!GUI.is_macos_laf) {
 | |
| 81325 | 84 |     putClientProperty("JTree.lineStyle", "Angled")
 | 
| 81323 | 85 | } | 
| 86 | } |