Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup Maven and Java Action
uses: s4u/setup-maven-action@v1.18.0
with:
java-version: '17'
java-version: '21'
maven-version: '3.9.6'
- name: Build
run: mvn --batch-mode install -DskipTests
2 changes: 1 addition & 1 deletion .github/workflows/build_latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: Setup Maven and Java Action
uses: s4u/setup-maven-action@v1.18.0
with:
java-version: '17'
java-version: '21'
maven-version: '3.9.6'
- name: Build
run: mvn --batch-mode install -DskipTests
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
package org.phoebus.applications.alarm.ui.tree;

import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import org.phoebus.applications.alarm.client.AlarmClient;
import org.phoebus.applications.alarm.model.AlarmTreeItem;
import org.phoebus.ui.dialog.ExceptionDetailsErrorDialog;

import java.util.Optional;

/**
* Dialog for configuring alarm tree items with path selection.
* Displays the alarm tree structure and allows user to select a path from the tree.
*/
public class AlarmTreeConfigDialog extends Dialog<String>
{
private final TextField pathInput;

/**
* Constructor for AlarmTreeConfigDialog
*
* @param alarmClient The alarm client model to display the tree
* @param currentPath The current path (initial value for text input)
* @param title The title of the dialog
* @param headerText The header text of the dialog
*/
public AlarmTreeConfigDialog(AlarmClient alarmClient, String currentPath, String title, String headerText)
{
setTitle(title);
setHeaderText(headerText);
setResizable(true);

// Create content
VBox content = new VBox(10);
content.setPadding(new Insets(15));

// Add AlarmTreeConfigView
AlarmTreeConfigView configView = new AlarmTreeConfigView(alarmClient);
configView.setPrefHeight(300);
configView.setPrefWidth(400);

// Initialize path input first
pathInput = new TextField();
pathInput.setText(currentPath != null ? currentPath : "");
pathInput.setStyle("-fx-font-family: monospace;");
pathInput.setPromptText("Select a path from the tree above or type manually");
pathInput.setEditable(true);

// Extract the last segment from the initial currentPath to preserve across selections
final String selectedTreeItem;
if (currentPath != null && !currentPath.isEmpty()) {
int lastSlashIndex = currentPath.lastIndexOf('/');
if (lastSlashIndex >= 0 && lastSlashIndex < currentPath.length() - 1) {
selectedTreeItem = currentPath.substring(lastSlashIndex + 1);
} else {
selectedTreeItem = "";
}
} else {
selectedTreeItem = "";
}

// Store the listener in a variable
ChangeListener<TreeItem<AlarmTreeItem<?>>> selectionListener = (obs, oldVal, newVal) -> {
if (newVal != null && newVal.getValue() != null)
{
String selectedPath = newVal.getValue().getPathName();
if (selectedPath != null && !selectedPath.isEmpty())
{
// Only update if not focused
if (!pathInput.isFocused()) {
// Append the preserved last segment to the selected path
String newPath = selectedPath;
if (!selectedTreeItem.isEmpty()) {
newPath = selectedPath + "/" + selectedTreeItem;
}

pathInput.setText(newPath);
}
}
}
};
configView.addTreeSelectionListener(selectionListener);
// Remove the listener when the dialog is closed
this.setOnHidden(e -> configView.removeTreeSelectionListener(selectionListener));

// Add text input for path
Label pathLabel = new Label("Selected Path:");

content.getChildren().addAll(
configView,
pathLabel,
pathInput
);

// Make tree view grow to fill available space
VBox.setVgrow(configView, Priority.ALWAYS);

getDialogPane().setContent(content);
getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
getDialogPane().setPrefSize(500, 600);

// Set result converter
setResultConverter(this::handleResult);
}

/**
* Handle the dialog result
*/
private String handleResult(ButtonType buttonType)
{
if (buttonType == ButtonType.OK)
{
String path = pathInput.getText().trim();
if (path.isEmpty())
{
ExceptionDetailsErrorDialog.openError("Invalid Path",
"Path cannot be empty.",
null);
return null;
}
return path;
}
return null;
}

/**
* Show the dialog and get the result
*
* @return Optional containing the path if OK was clicked, empty otherwise
*/
public Optional<String> getPath()
{
return showAndWait();
}
}
Loading
Loading