Skip to content

Commit a56058b

Browse files
committed
Alarm tree: Fix vanishing open/close tirangle and 'cursor'
#2608
1 parent cc28ab9 commit a56058b

File tree

1 file changed

+34
-25
lines changed

1 file changed

+34
-25
lines changed
Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,51 @@
11
/*******************************************************************************
2-
* Copyright (c) 2018 Oak Ridge National Laboratory.
2+
* Copyright (c) 2018-2023 Oak Ridge National Laboratory.
33
* All rights reserved. This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v1.0
55
* which accompanies this distribution, and is available at
66
* http://www.eclipse.org/legal/epl-v10.html
77
*******************************************************************************/
88
package org.phoebus.applications.alarm.ui.tree;
99

10+
import javafx.scene.control.Label;
11+
import javafx.scene.control.TreeCell;
12+
import javafx.scene.image.ImageView;
1013
import javafx.scene.layout.Background;
14+
import javafx.scene.layout.HBox;
15+
import javafx.scene.paint.Color;
16+
1117
import org.phoebus.applications.alarm.client.AlarmClientLeaf;
1218
import org.phoebus.applications.alarm.client.AlarmClientNode;
1319
import org.phoebus.applications.alarm.client.ClientState;
1420
import org.phoebus.applications.alarm.model.AlarmTreeItem;
1521
import org.phoebus.applications.alarm.model.SeverityLevel;
1622
import org.phoebus.applications.alarm.ui.AlarmUI;
1723

18-
import javafx.scene.control.TreeCell;
19-
import javafx.scene.image.Image;
20-
import javafx.scene.image.ImageView;
21-
import javafx.scene.paint.Color;
22-
2324
/** TreeCell for AlarmTreeItem
2425
* @author Kay Kasemir
2526
*/
2627
@SuppressWarnings("nls")
2728
class AlarmTreeViewCell extends TreeCell<AlarmTreeItem<?>>
2829
{
30+
// Originally, the tree cell "graphics" were used for the icon,
31+
// and the built-in label/text that can be controlled via
32+
// setText and setBackground for the text.
33+
// But using that built-in label/text background intermittently removes
34+
// the "triangle" for expanding/collapsing subtrees
35+
// as well as the "cursor" for selecting tree cells or navigating
36+
// cells via cursor keys.
37+
// So we add our own "graphics" to hold an icon and text
38+
private final Label label = new Label();
39+
private final ImageView image = new ImageView();
40+
private final HBox content = new HBox(image, label);
41+
2942
@Override
3043
protected void updateItem(final AlarmTreeItem<?> item, final boolean empty)
3144
{
3245
super.updateItem(item, empty);
33-
// Note: Cannot use background because that's used by style sheet and selection/cursor
46+
3447
if (empty || item == null)
35-
{
36-
setText(null);
3748
setGraphic(null);
38-
setBackground(Background.EMPTY);
39-
}
4049
else
4150
{
4251
final SeverityLevel severity;
@@ -46,7 +55,6 @@ protected void updateItem(final AlarmTreeItem<?> item, final boolean empty)
4655
final ClientState state = leaf.getState();
4756

4857
final StringBuilder text = new StringBuilder();
49-
final Image icon;
5058
text.append("PV: ").append(leaf.getName());
5159

5260
if (leaf.isEnabled() && !state.isDynamicallyDisabled())
@@ -61,31 +69,32 @@ protected void updateItem(final AlarmTreeItem<?> item, final boolean empty)
6169
.append(state.current_severity).append('/').append(state.current_message)
6270
.append(")");
6371
}
64-
setTextFill(AlarmUI.getColor(state.severity));
65-
setBackground(AlarmUI.getBackground(state.severity));
66-
icon = AlarmUI.getIcon(state.severity);
72+
label.setTextFill(AlarmUI.getColor(state.severity));
73+
label.setBackground(AlarmUI.getBackground(state.severity));
74+
image.setImage(AlarmUI.getIcon(state.severity));
6775
}
6876
else
6977
{
7078
text.append(" (disabled)");
71-
setTextFill(Color.GRAY);
72-
setBackground(Background.EMPTY);
73-
icon = AlarmUI.disabled_icon;
79+
label.setTextFill(Color.GRAY);
80+
label.setBackground(Background.EMPTY);
81+
image.setImage(AlarmUI.disabled_icon);
7482
}
75-
setText(text.toString());
76-
setGraphic(icon == null ? null : new ImageView(icon));
83+
label.setText(text.toString());
7784
}
7885
else
7986
{
8087
final AlarmClientNode node = (AlarmClientNode) item;
81-
setText(item.getName());
88+
label.setText(item.getName());
8289

8390
severity = node.getState().severity;
84-
setTextFill(AlarmUI.getColor(severity));
85-
setBackground(AlarmUI.getBackground(severity));
86-
final Image icon = AlarmUI.getIcon(severity);
87-
setGraphic(icon == null ? null : new ImageView(icon));
91+
label.setTextFill(AlarmUI.getColor(severity));
92+
label.setBackground(AlarmUI.getBackground(severity));
93+
image.setImage(AlarmUI.getIcon(severity));
8894
}
95+
// Profiler showed small advantage when skipping redundant 'setGraphic' call
96+
if (getGraphic() != content)
97+
setGraphic(content);
8998
}
9099
}
91100
}

0 commit comments

Comments
 (0)