-
Notifications
You must be signed in to change notification settings - Fork 81
#1784 implement java fx based progress bars for the GUI #1935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
laim2003
wants to merge
85
commits into
devonfw:main
Choose a base branch
from
laim2003:#1784-Implement-JavaFX-based-progress-bars-for-the-GUI
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
85 commits
Select commit
Hold shift + click to select a range
029f03d
#1296: implemented basic IdeDialog Class
laim2003 89cfb67
#1296: Added basic context state manager class
laim2003 a53296d
#1785: Added basic question/confirmation modal implementation
laim2003 37cad74
#1296: implemented basic IdeDialog Class
laim2003 55a50ce
#1296: Added basic context state manager class
laim2003 3f1569f
#1785: Added basic question/confirmation modal implementation
laim2003 6ce99b3
Merge remote-tracking branch 'origin/#1296-implement-idecontext-for-g…
laim2003 7ef65f3
#1785: - Added logging to IdeGuiStateManager.
laim2003 1764b2f
#1724: implemented basic gui state management
laim2003 ddd3e5f
#1802: implemented basic gui state management
laim2003 9c5a720
Merge remote-tracking branch 'origin/#1802-state-management-implement…
laim2003 b28e216
#1802: removed a few changes so this branch can be the base for other…
laim2003 53dd605
#1784: Added basic progress bar structure
laim2003 5fb0201
#1784: Added Task Management system
laim2003 b38bda7
#1784: TaskOverviewWindow can now only be opened once
laim2003 97a3f81
#1784: TaskOverviewWindows now uses data binding for displaying progr…
laim2003 234e98b
#1802: disabled javadoc warning
laim2003 1c4e766
#1802: - fixed AppBaseTest being stuck
laim2003 6fc3884
Merge branch 'main' into #1802-state-management-implementation
laim2003 2026757
#1802: Added ProjectManager class to handle business logic of reading…
laim2003 c76e185
#1802: Updated IdeGuiStateManager to also update its projectManager, …
laim2003 6f92d93
#1802: javafx updated to java 25
laim2003 f3eef9f
#1784: - fixed main-view minimum layout bounds (for progress bar)
laim2003 9f741a5
Merge branch 'main' into #1802-state-management-implementation
laim2003 48fe018
Revert "#1802: javafx updated to java 25"
laim2003 e0ad015
#1803: added DI for IDE_ROOT in GuiStateManager
laim2003 2c9fc55
#1802: added DI for IDE_ROOT in GuiStateManager
laim2003 2b62c60
Merge remote-tracking branch 'origin/#1802-state-management-implement…
laim2003 40ff54e
#1802: Workaround for IDE_ROOT=null issue. The ideRoot in GuiStateMan…
laim2003 0b67210
#1802: removed redundant DI variant of switchContext() (DI via getIns…
laim2003 2e15d60
#1802: Added tests for GuiStateManager
laim2003 10cf940
Merge branch 'main' into #1802-state-management-implementation
laim2003 5f0b40a
#1802: Extracted mock IDE_ROOT logic into seperate class that can be …
laim2003 3b567ef
Merge remote-tracking branch 'origin/#1802-state-management-implement…
laim2003 e406b65
#1802: added ProjectManagerTest
laim2003 e0e2d9d
#1802: Detached startContext creation from switchContext in IdeGuiSta…
laim2003 d70f460
#1802: Fixed bug in IdeGuiStateManagerTest leading to test failure
laim2003 d6aace2
Merge branch 'main' into #1802-state-management-implementation
laim2003 9c78eac
#1802: Added ContextChangeListener; improved thread safety of IdeGuiS…
laim2003 4c84bb9
Merge branch 'main' into #1802-state-management-implementation
laim2003 69055d9
#1802: tests now use AbstractIdeContextTest
laim2003 9978ce9
#1802: Updated UI logic to:
laim2003 ac3a045
#1802: cleaned up ProjectManagerTest, fixed AppBaseTest to follow new…
laim2003 6c44432
#1802: cleaned up IdeGuiStateManagerTest
laim2003 c30c2ea
Merge branch 'main' into #1802-state-management-implementation
laim2003 1e8b556
#1802: cleaned up ProjectManagerTest to use FileUtils instead of own …
laim2003 d51111d
Merge remote-tracking branch 'origin/#1802-state-management-implement…
laim2003 880ad96
Merge branch '#1802-state-management-implementation' into #1784-Imple…
laim2003 98a7072
Merge branch 'main' into #1802-state-management-implementation
laim2003 2d293f0
#1784: improved seperation of concerns in TaskOverviewWindow, added d…
laim2003 860ac85
#1784: small fixes
laim2003 dbd7374
#1784: switched listener system to javafx ObservableList
laim2003 c55a3a3
Merge branch 'main' into #1802-state-management-implementation
laim2003 39fa408
#1784: improved TaksManager for UI Thread safety, added documentation…
laim2003 a02d248
#1784: cleanup
laim2003 4747bae
#1802: cleaned up test folders, fixed wrong Logger used in ProjectMan…
laim2003 e03949d
#1802: cleaned up test folders #2
laim2003 e4e5bd9
#1802: cleaned up test folders nr. 3
laim2003 44791ef
Merge branch 'main' into #1802-state-management-implementation
laim2003 dab292f
#1802: removed caching from ProjectManager
laim2003 11a9546
#1802: cleanup
laim2003 4781ea5
#1802: cleanup
laim2003 9ee0bc2
#1802: cleanup of ide.properties
laim2003 9a76bfc
Merge branch 'main' into #1802-state-management-implementation
laim2003 f504d35
Merge branch 'main' into #1802-state-management-implementation
hohwille 99b617d
Merge branch 'main' into #1802-state-management-implementation
hohwille dbe8c85
#1802: applied recommendations from @hohwille
laim2003 666f0a7
#1802: applied recommendations from @hohwille
laim2003 f9422b5
Merge branch 'main' into #1802-state-management-implementation
laim2003 f2522db
#1802: fix ProjectManagerTest
laim2003 4cfc84b
Merge branch '#1802-state-management-implementation' into #1784-Imple…
laim2003 4e19a43
#1784: Added TaskManagerTest
laim2003 3711a64
#1784: Added test for TaskWindow
laim2003 d9ea676
#1784: Added test for status label
laim2003 e5187c2
#1784: fixed window positioning logic
laim2003 24ff9b1
#1784: updated Changelog
laim2003 3d6d064
Merge branch 'main' into #1784-Implement-JavaFX-based-progress-bars-f…
laim2003 3ac55f5
#1784: Changed singleton design to DI for GuiStateManager and TaskMan…
laim2003 afd910f
#1784: moved gui documentation UML files into seperate branch/PR #2035
laim2003 1f64d4f
#1987: Refactored use of TaskManager in App.java.
laim2003 20cd303
#1987: Refactored listener setup into separate method.
laim2003 cd389f9
Merge branch 'main' into #1784-Implement-JavaFX-based-progress-bars-f…
laim2003 6f4c54f
#1987: updated CHANGELOG.adoc
laim2003 c71855d
Merge remote-tracking branch 'origin/main' into #1784-Implement-JavaF…
maybeec 24a24e4
Merge remote-tracking branch 'upstream/main' into #1784-Implement-Jav…
maybeec File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.devonfw.ide.gui; | ||
|
|
||
| import javafx.application.Platform; | ||
|
|
||
| /** | ||
| * Helper class containing tools for interacting with JavaFX | ||
| */ | ||
| public class FxHelper { | ||
|
|
||
| /** | ||
| * Allows running operations on the Fx Application Thread, but only if the call is originating from the Fx Application Thread. Idea: Some tasks that are doing | ||
| * (potentially heavy) background work might not originate from the Fx Application (UI) Thread but will still interact with javafx observable collections. | ||
| * | ||
| * @param runnable code to execute | ||
| */ | ||
| public static void runFxSafe(Runnable runnable) { | ||
| if (Platform.isFxApplicationThread()) { | ||
| runnable.run(); | ||
| } else { | ||
| Platform.runLater(runnable); | ||
| } | ||
| } | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,25 +4,36 @@ | |
| import java.nio.file.NotDirectoryException; | ||
| import java.nio.file.Path; | ||
| import java.util.List; | ||
| import javafx.application.Platform; | ||
| import javafx.collections.ListChangeListener; | ||
| import javafx.concurrent.Task; | ||
| import javafx.fxml.FXML; | ||
| import javafx.scene.control.Alert.AlertType; | ||
| import javafx.scene.control.Button; | ||
| import javafx.scene.control.ComboBox; | ||
| import javafx.scene.control.Label; | ||
| import javafx.scene.control.ProgressBar; | ||
|
|
||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| import com.devonfw.ide.gui.context.IdeGuiStateManager; | ||
| import com.devonfw.ide.gui.context.GuiStateManager; | ||
| import com.devonfw.ide.gui.context.ProjectManager; | ||
| import com.devonfw.ide.gui.context.TaskManager; | ||
| import com.devonfw.ide.gui.modal.IdeDialog; | ||
| import com.devonfw.ide.gui.progress.ProgressBarTask; | ||
| import com.devonfw.ide.gui.progress.taskwindow.TaskOverviewWindow; | ||
|
|
||
| /** | ||
| * Controller of the main screen of the dashboard GUI. | ||
| */ | ||
| public class MainController { | ||
|
|
||
| private static Logger LOG = LoggerFactory.getLogger(MainController.class); | ||
| private static final Logger LOG = LoggerFactory.getLogger(MainController.class); | ||
|
|
||
| private ProjectManager projectManager; | ||
| private final GuiStateManager guiStateManager; | ||
| private final ProjectManager projectManager; | ||
| private final TaskManager taskManager; | ||
|
|
||
|
|
||
| @FXML | ||
|
|
@@ -43,19 +54,60 @@ public class MainController { | |
| @FXML | ||
| private Button vsCodeOpen; | ||
|
|
||
| private final String directoryPath; | ||
| @FXML | ||
| private Label statusLabel; | ||
|
|
||
| @FXML | ||
| private ProgressBar statusProgressBar; | ||
| private final double PROGRESSBAR_VISIBLE_WIDTH = 150.0; | ||
|
|
||
| private final String ideRootPath; | ||
| private Path projectValue; | ||
| private Path workspaceValue; | ||
|
|
||
| /** | ||
| * Constructor | ||
| * | ||
| * @param ideRoot the IDE_ROOT path | ||
| * @param guiStateManager the {@link GuiStateManager} to be used in this application instance | ||
| */ | ||
| public MainController(String directoryPath) { | ||
| public MainController(String ideRoot, GuiStateManager guiStateManager) { | ||
|
|
||
| LOG.debug("IDE_ROOT path={}", directoryPath); | ||
| this.directoryPath = directoryPath; | ||
| LOG.debug("IDE_ROOT path={}", ideRoot); | ||
| this.ideRootPath = ideRoot; | ||
| this.guiStateManager = guiStateManager; | ||
| this.taskManager = guiStateManager.getTaskManager(); | ||
| this.projectManager = guiStateManager.getProjectManager(); | ||
|
|
||
| this.projectManager = IdeGuiStateManager.getInstance().getProjectManager(); | ||
| setUpTaskListListener(); | ||
| } | ||
|
|
||
| private void setUpTaskListListener() { | ||
|
|
||
| ListChangeListener<ProgressBarTask> taskListChangeListener = change -> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Small suggestion: Maybe we could extract this listener setup into a separate method to improve readability
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed this in the latest commits |
||
| List<ProgressBarTask> tasks = taskManager.getTasks(); | ||
|
|
||
| while (change.next()) { | ||
| if (change.wasAdded()) { | ||
| LOG.debug("Added: {}", change.getAddedSubList()); | ||
|
|
||
| for (ProgressBarTask product : change.getAddedSubList()) { | ||
| product.currentProgressProperty().addListener((_, _, _) -> | ||
| updateStatusLabel(tasks) | ||
| ); | ||
| } | ||
| updateStatusLabel(tasks); | ||
| } else if (change.wasRemoved()) { | ||
| LOG.debug("Removed: {}", change.getRemoved()); | ||
|
|
||
| updateStatusLabel(tasks); | ||
| } else if (change.wasUpdated()) { | ||
|
|
||
| updateStatusLabel(tasks); | ||
| } | ||
| } | ||
| }; | ||
| taskManager.getTasks().addListener(taskListChangeListener); | ||
| } | ||
|
|
||
| @FXML | ||
|
|
@@ -90,7 +142,7 @@ private void openVsCode() { | |
|
|
||
| private void setProjectsComboBox() { | ||
|
|
||
| assert (directoryPath != null) : "directoryPath is null! Please check the setup of your environment variables (IDE_ROOT)"; | ||
| assert (ideRootPath != null) : "directoryPath is null! Please check the setup of your environment variables (IDE_ROOT)"; | ||
|
|
||
| List<String> projects = projectManager.getProjectNames(); | ||
|
|
||
|
|
@@ -107,7 +159,7 @@ private void setProjectsComboBox() { | |
|
|
||
| private void setWorkspaceComboBox() { | ||
|
|
||
| List<String> workspaces = null; | ||
| List<String> workspaces; | ||
| try { | ||
| workspaces = projectManager.getWorkspaceNames(selectedProject.getValue()); | ||
| } catch (NotDirectoryException e) { | ||
|
|
@@ -129,20 +181,89 @@ private void setWorkspaceComboBox() { | |
|
|
||
| private void openIDE(String inIde) { | ||
|
|
||
| IdeGuiStateManager | ||
| .getInstance() | ||
| .getCurrentContext() | ||
| .getCommandletManager() | ||
| .getCommandlet(inIde) | ||
| .run(); | ||
| Task<Void> downloadTask = runIdeCommandTask(inIde); | ||
|
|
||
| new Thread(downloadTask).start(); | ||
| } | ||
|
|
||
| private Task<Void> runIdeCommandTask(String inIde) { | ||
|
|
||
| try (ProgressBarTask task = (ProgressBarTask) guiStateManager.getCurrentContext() | ||
| .newProgressBarIndeterminate("Starting " + inIde)) { | ||
| Task<Void> downloadTask = new Task<>() { | ||
| @Override | ||
| protected Void call() { | ||
| guiStateManager | ||
| .getCurrentContext() | ||
| .getCommandletManager() | ||
| .getCommandlet(inIde) | ||
| .run(); | ||
| task.close(); | ||
| return null; | ||
| } | ||
| }; | ||
|
|
||
| downloadTask.setOnFailed(_ -> Platform.runLater(() -> { | ||
| task.close(); | ||
| IdeDialog errorDialog = new IdeDialog(AlertType.ERROR, "Error occurred while launching " + inIde); | ||
| errorDialog.showAndWait(); | ||
| })); | ||
| return downloadTask; | ||
| } | ||
| } | ||
|
|
||
| private void updateContext(String selectedProjectName, String selectedWorkspaceName) { | ||
|
|
||
| try { | ||
| IdeGuiStateManager.getInstance().switchContext(selectedProjectName, selectedWorkspaceName); | ||
| guiStateManager.switchContext(selectedProjectName, selectedWorkspaceName); | ||
| } catch (FileNotFoundException e) { | ||
| IdeDialog errorDialog = new IdeDialog(IdeDialog.AlertType.ERROR, e.getMessage()); | ||
| IdeDialog errorDialog = new IdeDialog(AlertType.ERROR, e.getMessage()); | ||
| errorDialog.showAndWait(); | ||
| } | ||
| } | ||
|
|
||
| private void updateStatusLabel(List<ProgressBarTask> taskList) { | ||
|
|
||
| Platform.runLater(() -> { | ||
|
|
||
| if (taskList.size() > 1) { | ||
| statusLabel.setOnMouseClicked(e -> TaskOverviewWindow.getInstance(taskManager).showRelativeToReferenceNode(statusLabel)); | ||
|
|
||
| statusProgressBar.setVisible(false); | ||
| statusProgressBar.setPrefWidth(0); | ||
| statusLabel.setText(taskList.size() + " tasks running..."); | ||
|
|
||
| statusLabel.setUnderline(true); | ||
| statusLabel.setStyle( | ||
| "-fx-text-fill: blue;" | ||
| + "-fx-cursor: hand" | ||
| ); | ||
| } else if (taskList.size() == 1) { | ||
| statusLabel.setOnMouseClicked(null); | ||
|
|
||
| ProgressBarTask task = taskList.getFirst(); | ||
| statusLabel.setText(String.format( | ||
| ProgressBarTask.TASK_DESCRIPTION_STRING_FORMAT, | ||
| task.getTitle(), | ||
| task.getCurrentProgress(), | ||
| task.getMaxSize(), | ||
| task.getUnitName()) | ||
| ); | ||
| statusLabel.setUnderline(false); | ||
| statusLabel.setStyle(""); | ||
|
|
||
| statusProgressBar.setVisible(true); | ||
| statusProgressBar.setPrefWidth(PROGRESSBAR_VISIBLE_WIDTH); | ||
| statusProgressBar.setProgress((double) (task.getCurrentProgress()) / task.getMaxSize()); | ||
| } else { | ||
| statusLabel.setOnMouseClicked(null); | ||
| statusLabel.setText("IDEasy is ready."); | ||
| statusProgressBar.setVisible(false); | ||
| statusProgressBar.setPrefWidth(0); | ||
|
|
||
| statusLabel.setUnderline(false); | ||
| statusLabel.setStyle(""); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I already have this in my PR #2027, wrapping the
startmethod logic in atry-catchwould allow startup errors to be caught and shown properly in the dialogThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we use proper logging (SLF4J)?
Calling
printStackTrace()(and alsoSystem.out) directly is typically discouraged.