use of javafx.scene.control.Tooltip in project org.csstudio.display.builder by kasemir.
the class TooltipSupport method attach.
/**
* Attach tool tip
* @param node Node that should have the tool tip
* @param tooltip_property Tool tip to show
*/
public static void attach(final Node node, final WidgetProperty<String> tooltip_property) {
// Patch legacy tool tips that defaulted to pv name & value,
// even for static widgets
final StringWidgetProperty ttp = (StringWidgetProperty) tooltip_property;
if (legacy_tooltip.matcher(ttp.getSpecification()).matches() && !tooltip_property.getWidget().checkProperty("pv_name").isPresent())
ttp.setSpecification("");
// Avoid listener and code to remove/add tooltip at runtime.
if (tooltip_property.getValue().isEmpty())
return;
final Tooltip tooltip = new Tooltip();
tooltip.setWrapText(true);
// Evaluate the macros in tool tip specification each time
// the tool tip is about to show
tooltip.setOnShowing(event -> {
final String spec = ((MacroizedWidgetProperty<?>) tooltip_property).getSpecification();
final Widget widget = tooltip_property.getWidget();
final MacroValueProvider macros = widget.getMacrosOrProperties();
String expanded;
try {
expanded = MacroHandler.replace(macros, spec);
tooltip.setText(expanded);
} catch (Exception ex) {
logger.log(Level.WARNING, "Cannot evaluate tooltip of " + widget, ex);
tooltip.setText(spec);
}
});
Tooltip.install(node, tooltip);
if (!initialized_behavior) {
// Unfortunately, no API to control when tooltop shows, and for how long.
// http://stackoverflow.com/questions/26854301/control-javafx-tooltip-delay
// has the hack used in here, which only needs to be applied once
// because it changes a static BEHAVIOR inside the Tooltip.
// Java 9 will offer API, https://bugs.openjdk.java.net/browse/JDK-8090477
hack_behavior(tooltip);
initialized_behavior = true;
}
}
use of javafx.scene.control.Tooltip in project org.csstudio.display.builder by kasemir.
the class StringTable method createToolbarButton.
private Button createToolbarButton(final String id, final String tool_tip, final EventHandler<ActionEvent> handler) {
final Button button = new Button();
try {
// TODO Icons are not centered inside the button until the
// button is once pressed, or at least focused via "tab"
button.setGraphic(new ImageView(Activator.getIcon(id)));
// Using the image as a background like this centers the image,
// but replaces the complete characteristic button outline with just the icon.
// button.setBackground(new Background(new BackgroundImage(new Image(Activator.getIcon(id)),
// BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT,
// BackgroundPosition.CENTER,
// new BackgroundSize(16, 16, false, false, false, false))));
button.setTooltip(new Tooltip(tool_tip));
// Without defining the button size, the buttons may start out zero-sized
// until they're first pressed/tabbed
button.setMinSize(35, 25);
} catch (Exception ex) {
logger.log(Level.WARNING, "Cannot load icon for " + id, ex);
button.setText(tool_tip);
}
button.setOnAction(handler);
return button;
}
use of javafx.scene.control.Tooltip in project org.csstudio.display.builder by kasemir.
the class RulesDialog method createRulesTable.
/**
* @return Node for UI elements that edit the rules
*/
private Node createRulesTable() {
// Create table with editable rule 'name' column
final TableColumn<RuleItem, String> name_col = new TableColumn<>(Messages.RulesDialog_ColName);
name_col.setCellValueFactory(new PropertyValueFactory<RuleItem, String>("name"));
name_col.setCellFactory(list -> new TextFieldTableCell<RuleItem, String>(new DefaultStringConverter()) {
private final ChangeListener<? super Boolean> focusedListener = (ob, o, n) -> {
if (!n)
cancelEdit();
};
@Override
public void cancelEdit() {
((TextField) getGraphic()).focusedProperty().removeListener(focusedListener);
super.cancelEdit();
}
@Override
public void commitEdit(final String newValue) {
((TextField) getGraphic()).focusedProperty().removeListener(focusedListener);
super.commitEdit(newValue);
Platform.runLater(() -> btn_add_pv.requestFocus());
}
@Override
public void startEdit() {
super.startEdit();
((TextField) getGraphic()).focusedProperty().addListener(focusedListener);
}
});
name_col.setOnEditCommit(event -> {
final int row = event.getTablePosition().getRow();
rule_items.get(row).name.set(event.getNewValue());
fixupRules(row);
});
rules_table = new TableView<>(rule_items);
rules_table.getColumns().add(name_col);
rules_table.setEditable(true);
rules_table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
rules_table.setTooltip(new Tooltip(Messages.RulesDialog_RulesTT));
rules_table.setPlaceholder(new Label(Messages.RulesDialog_NoRules));
// Buttons
btn_add_rule = new Button(Messages.Add, JFXUtil.getIcon("add.png"));
btn_add_rule.setMaxWidth(Double.MAX_VALUE);
btn_add_rule.setAlignment(Pos.CENTER_LEFT);
btn_add_rule.setOnAction(event -> {
final RuleItem newItem = new RuleItem(attached_widget, selected_rule_item == null ? ((propinfo_ls.size() == 0) ? "" : propinfo_ls.get(0).getPropID()) : selected_rule_item.prop_id.get());
rule_items.add(newItem);
rules_table.getSelectionModel().select(newItem);
final int newRow = rules_table.getSelectionModel().getSelectedIndex();
ModelThreadPool.getTimer().schedule(() -> {
Platform.runLater(() -> rules_table.edit(newRow, name_col));
}, 123, TimeUnit.MILLISECONDS);
});
btn_remove_rule = new Button(Messages.Remove, JFXUtil.getIcon("delete.png"));
btn_remove_rule.setMaxWidth(Double.MAX_VALUE);
btn_remove_rule.setAlignment(Pos.CENTER_LEFT);
btn_remove_rule.setDisable(true);
btn_remove_rule.setOnAction(event -> {
final int sel = rules_table.getSelectionModel().getSelectedIndex();
if (sel >= 0) {
rule_items.remove(sel);
fixupRules(sel);
}
});
btn_move_rule_up = new Button(Messages.MoveUp, JFXUtil.getIcon("up.png"));
btn_move_rule_up.setMaxWidth(Double.MAX_VALUE);
btn_move_rule_up.setAlignment(Pos.CENTER_LEFT);
btn_move_rule_up.setDisable(true);
btn_move_rule_up.setOnAction(event -> TableHelper.move_item_up(rules_table, rule_items));
btn_move_rule_down = new Button(Messages.MoveDown, JFXUtil.getIcon("down.png"));
btn_move_rule_down.setMaxWidth(Double.MAX_VALUE);
btn_move_rule_down.setAlignment(Pos.CENTER_LEFT);
btn_move_rule_down.setDisable(true);
btn_move_rule_down.setOnAction(event -> TableHelper.move_item_down(rules_table, rule_items));
btn_dup_rule = new Button(Messages.Duplicate, JFXUtil.getIcon("file-duplicate.png"));
btn_dup_rule.setMaxWidth(Double.MAX_VALUE);
btn_dup_rule.setAlignment(Pos.CENTER_LEFT);
btn_dup_rule.setDisable(true);
btn_dup_rule.setOnAction(event -> {
if (selected_rule_item != null) {
final RuleItem newItem = RuleItem.forInfo(attached_widget, selected_rule_item.getRuleInfo(), undo);
if (!newItem.nameProperty().get().endsWith(" (duplicate)"))
newItem.nameProperty().set(newItem.nameProperty().get() + " (duplicate)");
rule_items.add(newItem);
rules_table.getSelectionModel().select(newItem);
final int newRow = rules_table.getSelectionModel().getSelectedIndex();
ModelThreadPool.getTimer().schedule(() -> {
Platform.runLater(() -> rules_table.edit(newRow, name_col));
}, 123, TimeUnit.MILLISECONDS);
}
});
btn_show_script = new Button(Messages.RulesDialog_ShowScript, JFXUtil.getIcon("file.png"));
btn_show_script.setMaxWidth(Double.MAX_VALUE);
btn_show_script.setMinWidth(120);
btn_dup_rule.setAlignment(Pos.CENTER_LEFT);
btn_show_script.setDisable(true);
btn_show_script.setOnAction(event -> {
final int sel = rules_table.getSelectionModel().getSelectedIndex();
if (sel >= 0) {
final String content = rule_items.get(sel).getRuleInfo().getTextPy(attached_widget);
final SyntaxHighlightedMultiLineInputDialog dialog = new SyntaxHighlightedMultiLineInputDialog(btn_show_script, content, Language.Python, false);
DialogHelper.positionDialog(dialog, btn_show_script, -200, -300);
dialog.setTextHeight(600);
dialog.show();
}
});
final VBox buttons = new VBox(10, btn_add_rule, btn_remove_rule, btn_move_rule_up, btn_move_rule_down, new Pane(), btn_dup_rule, btn_show_script);
final HBox content = new HBox(10, rules_table, buttons);
HBox.setHgrow(rules_table, Priority.ALWAYS);
HBox.setHgrow(buttons, Priority.NEVER);
return content;
}
use of javafx.scene.control.Tooltip in project org.csstudio.display.builder by kasemir.
the class PropertyPanelSection method createPropertyUI.
/**
* Add UI items for displaying or editing property
* @param property Property (on primary widget)
* @param other Zero or more additional widgets that have same type of property
* @param structureIndex Index of the array structure (element) being added. It is meaningful
* only for properties instance of {@link StructuredWidgetProperty}.
*/
private void createPropertyUI(final UndoableActionManager undo, final WidgetProperty<?> property, final List<Widget> other, final int structureIndex, final int indentationLevel) {
// Skip runtime properties
if (property.getCategory() == WidgetPropertyCategory.RUNTIME)
return;
final Label label = new Label(property.getDescription());
label.setMaxWidth(Double.MAX_VALUE);
final String tooltip = property.getDescription() + " (" + property.getPath() + ")";
label.setTooltip(new Tooltip(tooltip));
// setGridLinesVisible(true); // For debugging the layout
Node field = bindSimplePropertyField(undo, bindings, property, other);
if (field != null) {
// do nothing
} else if (property instanceof MacrosWidgetProperty) {
final MacrosWidgetProperty macros_prop = (MacrosWidgetProperty) property;
final Button macros_field = new Button();
macros_field.setMaxWidth(Double.MAX_VALUE);
final MacrosPropertyBinding binding = new MacrosPropertyBinding(undo, macros_field, macros_prop, other);
bindings.add(binding);
binding.bind();
field = macros_field;
} else if (property instanceof ActionsWidgetProperty) {
final ActionsWidgetProperty actions_prop = (ActionsWidgetProperty) property;
final Button actions_field = new Button();
actions_field.setMaxWidth(Double.MAX_VALUE);
final ActionsPropertyBinding binding = new ActionsPropertyBinding(undo, actions_field, actions_prop, other, autocomplete_menu);
bindings.add(binding);
binding.bind();
field = actions_field;
} else if (property instanceof ScriptsWidgetProperty) {
final ScriptsWidgetProperty scripts_prop = (ScriptsWidgetProperty) property;
final Button scripts_field = new Button();
scripts_field.setMaxWidth(Double.MAX_VALUE);
final ScriptsPropertyBinding binding = new ScriptsPropertyBinding(undo, scripts_field, scripts_prop, other, autocomplete_menu);
bindings.add(binding);
binding.bind();
field = scripts_field;
} else if (property instanceof RulesWidgetProperty) {
final RulesWidgetProperty rules_prop = (RulesWidgetProperty) property;
final Button rules_field = new Button();
rules_field.setMaxWidth(Double.MAX_VALUE);
final RulesPropertyBinding binding = new RulesPropertyBinding(undo, rules_field, rules_prop, other, autocomplete_menu);
bindings.add(binding);
binding.bind();
field = rules_field;
} else if (property instanceof StructuredWidgetProperty) {
// Don't allow editing structures and their elements in class mode
if (class_mode)
return;
final StructuredWidgetProperty struct = (StructuredWidgetProperty) property;
final Label header = new Label(struct.getDescription() + (structureIndex > 0 ? " " + String.valueOf(1 + structureIndex) : ""));
header.getStyleClass().add("structure_property_name");
header.setMaxWidth(Double.MAX_VALUE);
final int row = getNextGridRow();
fillIndent(indentationLevel, row);
add(header, 0 + indentationLevel, row, 7 - 2 * indentationLevel, 1);
final Separator separator = new Separator();
separator.getStyleClass().add("property_separator");
add(separator, 0 + indentationLevel, getNextGridRow(), 7 - 2 * indentationLevel, 1);
for (WidgetProperty<?> elem : struct.getValue()) this.createPropertyUI(undo, elem, other, -1, indentationLevel);
return;
} else if (property instanceof ArrayWidgetProperty) {
// Don't allow editing arrays and their elements in class mode
if (class_mode)
return;
@SuppressWarnings("unchecked") final ArrayWidgetProperty<WidgetProperty<?>> array = (ArrayWidgetProperty<WidgetProperty<?>>) property;
// UI for changing array size
final Spinner<Integer> spinner = new Spinner<>(array.getMinimumSize(), 100, 0);
final ArraySizePropertyBinding count_binding = new ArraySizePropertyBinding(this, undo, spinner, array, other);
bindings.add(count_binding);
count_binding.bind();
// set size of array
int row = getNextGridRow();
label.getStyleClass().add("array_property_name");
label.setMaxWidth(Double.MAX_VALUE);
label.setMaxHeight(Double.MAX_VALUE);
spinner.getStyleClass().add("array_property_value");
spinner.setMaxWidth(Double.MAX_VALUE);
fillHeaderIndent(indentationLevel, row);
add(label, indentationLevel, row, 4 - indentationLevel, 1);
add(spinner, 4, row, 2 - indentationLevel, 1);
Separator separator = new Separator();
separator.getStyleClass().add("property_separator");
add(separator, 1 + indentationLevel, getNextGridRow(), 5 - 2 * indentationLevel, 1);
// array elements
final List<WidgetProperty<?>> wpeList = array.getValue();
for (int i = 0; i < wpeList.size(); i++) {
final WidgetProperty<?> elem = wpeList.get(i);
createPropertyUI(undo, elem, other, i, indentationLevel + 1);
}
// mark end of array
row = getNextGridRow();
final Label endlabel = new Label();
endlabel.setMaxWidth(Double.MAX_VALUE);
GridPane.setHgrow(endlabel, Priority.ALWAYS);
endlabel.getStyleClass().add("array_property_end");
fillIndent(indentationLevel, row);
add(endlabel, 0 + indentationLevel, row, 7 - 2 * indentationLevel, 1);
separator = new Separator();
separator.getStyleClass().add("property_separator");
add(separator, 0 + indentationLevel, getNextGridRow(), 7 - 2 * indentationLevel, 1);
return;
} else // As new property types are added, they might need to be handled:
// else if (property instanceof SomeNewWidgetProperty) { ... }
{
// Fallback for unknown property: read-only
final TextField text = new TextField();
text.setText(String.valueOf(property.getValue()));
text.setEditable(false);
field = text;
}
// Display Label, Class indicator/checkbox, field
final int row = getNextGridRow();
label.getStyleClass().add("property_name");
field.getStyleClass().add("property_value");
// Allow label to shrink (can use tooltip to see),
// but show the value
// GridPane.setHgrow(label, Priority.ALWAYS);
GridPane.setHgrow(field, Priority.ALWAYS);
fillIndent(indentationLevel, row);
add(label, indentationLevel, row, 3 - indentationLevel, 1);
final Widget widget = property.getWidget();
if (!(property == widget.getProperty("type") || property == widget.getProperty("name"))) {
if (class_mode) {
// Class definition mode:
// Check box for 'use_class'
final CheckBox check = new CheckBox();
check.setTooltip(use_class_tooltip);
final WidgetPropertyBinding<?, ?> binding = new UseWidgetClassBinding(undo, check, field, property, other);
bindings.add(binding);
binding.bind();
add(check, 3, row);
} else {
// Display file mode:
// Show if property is set by the class, not editable.
final Label indicator = new Label();
indicator.setTooltip(using_class_tooltip);
final WidgetPropertyBinding<?, ?> binding = new ShowWidgetClassBinding(field, property, indicator);
bindings.add(binding);
binding.bind();
add(indicator, 3, row);
}
}
add(field, 4, row, 3 - indentationLevel, 1);
final Separator separator = new Separator();
separator.getStyleClass().add("property_separator");
add(separator, 0 + indentationLevel, getNextGridRow(), 7 - 2 * indentationLevel, 1);
}
use of javafx.scene.control.Tooltip in project org.csstudio.display.builder by kasemir.
the class DisplayEditor method createToggleButton.
private ToggleButton createToggleButton(final ActionDescription action) {
final ToggleButton button = new ToggleButton();
try {
button.setGraphic(new ImageView(new Image(ResourceUtil.openPlatformResource(action.getIconResourcePath()))));
} catch (final Exception ex) {
logger.log(Level.WARNING, "Cannot load action icon", ex);
}
button.setTooltip(new Tooltip(action.getToolTip()));
button.setSelected(true);
button.selectedProperty().addListener((observable, old_value, enabled) -> action.run(this, enabled));
return button;
}
Aggregations