author | wenzelm |
Tue, 19 Nov 2024 22:55:09 +0100 | |
changeset 81496 | 76f360c63dfe |
parent 81495 | 57dc2c8ba7c6 |
child 81497 | da807cf1e461 |
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:
81377
diff
changeset
|
23 |
case node: Node => Some(node.getUserObject) |
81329 | 24 |
case _ => None |
25 |
} |
|
26 |
} |
|
81496 | 27 |
|
28 |
def render_tree_cell(renderer: DefaultTreeCellRenderer): Unit = { |
|
29 |
renderer.setIcon(null) |
|
30 |
} |
|
81329 | 31 |
} |
32 |
||
81325 | 33 |
class Tree_View( |
81329 | 34 |
val root: Tree_View.Node = Tree_View.Node(), |
81325 | 35 |
single_selection_mode: Boolean = false |
36 |
) extends JTree(root) { |
|
37 |
def get_selection[A](which: PartialFunction[AnyRef, A]): Option[A] = |
|
38 |
getLastSelectedPathComponent match { |
|
81380
83012fe97282
revert 1206400b9b48: proper Node.unapply for Node.apply(null);
wenzelm
parents:
81377
diff
changeset
|
39 |
case Tree_View.Node(obj) if obj != null && which.isDefinedAt(obj) => Some(which(obj)) |
81325 | 40 |
case _ => None |
41 |
} |
|
81323 | 42 |
|
81483 | 43 |
def init_model(body: => Unit): Unit = { |
81325 | 44 |
clearSelection() |
45 |
root.removeAllChildren() |
|
81483 | 46 |
body |
47 |
expandRow(0) |
|
48 |
reload_model() |
|
81325 | 49 |
} |
50 |
||
51 |
def reload_model(): Unit = |
|
81326 | 52 |
getModel match { |
53 |
case model: DefaultTreeModel => model.reload(root) |
|
54 |
case _ => |
|
55 |
} |
|
81325 | 56 |
|
57 |
||
81494 | 58 |
/* cell renderer */ |
59 |
||
81496 | 60 |
def render_tree_cell(renderer: DefaultTreeCellRenderer): Unit = |
61 |
Tree_View.render_tree_cell(renderer) |
|
81494 | 62 |
|
63 |
private val tree_cell_renderer: TreeCellRenderer = new DefaultTreeCellRenderer { |
|
64 |
override def getTreeCellRendererComponent( |
|
65 |
tree: JTree, |
|
66 |
value: AnyRef, |
|
67 |
selected: Boolean, |
|
68 |
expanded: Boolean, |
|
69 |
leaf: Boolean, |
|
70 |
row: Int, |
|
71 |
hasFocus: Boolean |
|
72 |
): java.awt.Component = { |
|
73 |
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus) |
|
74 |
render_tree_cell(this) |
|
75 |
this |
|
76 |
} |
|
77 |
} |
|
78 |
||
79 |
||
81325 | 80 |
/* init */ |
81 |
||
81494 | 82 |
setCellRenderer(tree_cell_renderer) |
83 |
||
81325 | 84 |
setRowHeight(0) |
81323 | 85 |
|
86 |
if (single_selection_mode) { |
|
81325 | 87 |
getSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION) |
81323 | 88 |
} |
89 |
||
90 |
// follow jEdit |
|
91 |
if (!GUI.is_macos_laf) { |
|
81325 | 92 |
putClientProperty("JTree.lineStyle", "Angled") |
81323 | 93 |
} |
94 |
} |