New features - #527
Open
zaum wants to merge 18 commits into
Open
Conversation
…plement inline editing in ResultTable
…for setting and opening with default openers
… ResultTable and DetailsWindow
…alog - Introduced ColumnVisibilityMenu: a new context menu on the results table header that lets users show or hide individual columns (fetchers) in place, replacing the old SelectFetchersDialog with a faster, inline workflow. - Removed SelectFetchersDialog from MacApplicationMenu and MainWindow. - ResultTable now supports dynamic column visibility and reordering. - Cleaned up related references and menu/action wiring for the removed dialog.
- ScanningResultComparator now catches ClassCastException during a typed comparison and falls back to a case-insensitive text comparison (with a secondary sort on the first column), so sorting mixed-type values no longer crashes the UI. - ResultTable mouse handling now converts display-relative event coordinates to control-relative coordinates before hit-testing the header area. - ColumnsActions.ColumnClick was reworked: a left-click on a column header sorts by that column (toggling ascending/descending on repeated clicks), instead of opening the old ColumnsMenu. Sorting uses the fetcher (data) index rather than the visual column position, so reordering columns does not break sorting. The unused ColumnsMenu dependency was removed.
…plement inline editing in ResultTable - Comments are now persisted to a plain comments.txt file in the config directory instead of the OS Java Preferences store. This makes them survive program restarts and updates, and they are flushed to disk immediately on every change so they are never lost on crash. - Added Config.getConfigDir() which prefers a portable "config" directory next to the application (jar/exe) and falls back to ~/.ipscan in the user's home when that is not writable. - Added inline comment editing directly in the results table: clicking the comment cell opens a text editor in place. Press Enter or move focus to save, Escape to cancel. The change is written through CommentsConfig and the row is refreshed instantly.
Precompute a column-to-fetcher index map to avoid repeated `getFetcherIndex` calls during virtual table rendering. Batch UI updates in `populateNewFetcher` to reduce `asyncExec` overhead. Use a precomputed position map for fetcher reordering in `ScanningResultList` to replace `indexOf` calls inside loops.
…ups. Hide tooltip and reset internal state when the application window loses focus. Add `/bin` directory to .gitignore.
Collaborator
|
@copilot resolve the merge conflicts in this pull request |
There was a problem hiding this comment.
Pull request overview
This PR modernizes Angry IP Scanner’s UI layer by migrating from SWT to JavaFX, while adding several UX/features around comments, openers, and column management, plus moving some user settings from Java Preferences into plain files under a portable config directory.
Changes:
- Replace the SWT GUI stack with a JavaFX-based GUI (
net.azib.ipscan.gui.fx.*), updating app startup and DI registration accordingly. - Add file-backed persistence for user data/config (portable
config/dir near the app, comments stored incomments.txt, per-IP default openers stored inopeners-defaults.txt). - Add “default opener per IP” functionality, including opener-related fetchers and UI hooks for setting/launching.
Reviewed changes
Copilot reviewed 124 out of 130 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| test/net/azib/ipscan/gui/SWTTestCase.java | Removed SWT test base class as part of SWT deprecation. |
| test/net/azib/ipscan/gui/StatisticsDialogTest.java | Removed SWT StatisticsDialog test (dialog removed). |
| test/net/azib/ipscan/gui/SelectFetchersDialogTest.java | Removed test for removed SWT dialog. |
| test/net/azib/ipscan/gui/PreferencesDialogTest.java | Removed SWT preferences dialog tests. |
| test/net/azib/ipscan/gui/InputDialogTest.java | Removed SWT input dialog tests. |
| test/net/azib/ipscan/gui/GUITest.java | Removed SWT GUI error-localization test (SWT GUI removed). |
| test/net/azib/ipscan/gui/fetchers/PortTextFetcherPrefsTest.java | Removed tests tied to removed SWT fetcher prefs UI. |
| test/net/azib/ipscan/gui/feeders/FeederGUIRegistryTest.java | Replaced SWT GUI registry tests with minimal RangeFeeder assertions (misnamed now). |
| test/net/azib/ipscan/gui/feeders/AbstractFeederGUITest.java | Updated feeder GUI test to target FX feeder GUI base class. |
| test/net/azib/ipscan/gui/actions/StartStopScanningActionTest.java | Removed SWT action test. |
| test/net/azib/ipscan/gui/actions/OpenerLauncherTest.java | Removed SWT opener launcher tests (launcher removed/ported). |
| test/net/azib/ipscan/gui/actions/GotoActionsTest.java | Removed SWT go-to actions tests. |
| test/net/azib/ipscan/fetchers/FetcherRegistryTest.java | Updated for FetcherRegistry constructor signature changes. |
| test/net/azib/ipscan/exporters/TXTExporterTest.java | Updated TXT import test API from GUI feeder to FeederCreator; improved resource path handling. |
| test/net/azib/ipscan/config/GUIConfigTest.java | Updated to match GUIConfig’s new int[] sizing fields (no SWT Point). |
| test/net/azib/ipscan/config/ComponentRegistryTest.java | Removed SWT-dependent DI instantiation test. |
| src/net/azib/ipscan/util/GoogleAnalytics.java | Removed SWT-specific exception code handling from stack extraction. |
| src/net/azib/ipscan/Main.java | Switched app startup to JavaFX (FXGUI) and simplified error fallback behavior. |
| src/net/azib/ipscan/gui/util/LayoutHelper.java | Deleted SWT layout/icon helper. |
| src/net/azib/ipscan/gui/SWTAwareStateMachine.java | Deleted SWT-thread marshalling state machine. |
| src/net/azib/ipscan/gui/StatusBar.java | Deleted SWT status bar (replaced by FXStatusBar). |
| src/net/azib/ipscan/gui/StatisticsDialog.java | Deleted SWT statistics dialog. |
| src/net/azib/ipscan/gui/Startup.java | Deleted SWT startup flow (FX TODO remains). |
| src/net/azib/ipscan/gui/SelectFetchersDialog.java | Deleted SWT fetcher selection dialog. |
| src/net/azib/ipscan/gui/menu/ToolsMenu.java | Deleted SWT tools menu implementation. |
| src/net/azib/ipscan/gui/menu/ScanMenu.java | Deleted SWT scan menu implementation. |
| src/net/azib/ipscan/gui/menu/ResultsContextMenu.java | Deleted SWT results context menu wrapper. |
| src/net/azib/ipscan/gui/menu/OpenersMenu.java | Deleted SWT openers menu wrapper. |
| src/net/azib/ipscan/gui/menu/OpenersContextMenu.java | Deleted SWT openers context menu wrapper. |
| src/net/azib/ipscan/gui/menu/HelpMenu.java | Deleted SWT help menu implementation. |
| src/net/azib/ipscan/gui/menu/GotoMenu.java | Deleted SWT goto menu implementation. |
| src/net/azib/ipscan/gui/menu/FavoritesMenu.java | Deleted SWT favorites menu implementation. |
| src/net/azib/ipscan/gui/menu/ExtendableMenu.java | Deleted SWT menu base class. |
| src/net/azib/ipscan/gui/menu/CommandsMenu.java | Deleted SWT commands menu implementation. |
| src/net/azib/ipscan/gui/menu/ColumnsMenu.java | Deleted SWT columns menu implementation. |
| src/net/azib/ipscan/gui/menu/AbstractMenu.java | Deleted SWT abstract menu base class. |
| src/net/azib/ipscan/gui/MainMenu.java | Deleted SWT main menu wiring and enable/disable logic. |
| src/net/azib/ipscan/gui/MacApplicationMenu.java | Deleted SWT Mac application menu integration. |
| src/net/azib/ipscan/gui/InputDialog.java | Deleted SWT input dialog. |
| src/net/azib/ipscan/gui/InfoDialog.java | Deleted SWT info dialog. |
| src/net/azib/ipscan/gui/GUI.java | Deleted SWT GUI entrypoint/event loop. |
| src/net/azib/ipscan/gui/GettingStartedDialog.java | Deleted SWT getting started dialog. |
| src/net/azib/ipscan/gui/fx/FXStatusBar.java | Added JavaFX status bar replacement. |
| src/net/azib/ipscan/gui/fx/FXStateMachine.java | Added JavaFX-thread marshalling state machine. |
| src/net/azib/ipscan/gui/fx/FXOpenersDialog.java | Added JavaFX “Edit Openers” dialog. |
| src/net/azib/ipscan/gui/fx/FXGUI.java | Added JavaFX Application entrypoint and window wiring. |
| src/net/azib/ipscan/gui/fx/FXFavoritesDialog.java | Added JavaFX favorites management dialog. |
| src/net/azib/ipscan/gui/fx/FXDetailsDialog.java | Added JavaFX details dialog with comment editing. |
| src/net/azib/ipscan/gui/fx/feeders/FXRandomFeederGUI.java | Added JavaFX RandomFeeder UI. |
| src/net/azib/ipscan/gui/fx/feeders/FXFileFeederGUI.java | Added JavaFX FileFeeder UI. |
| src/net/azib/ipscan/gui/fx/feeders/FXFeederGUIRegistry.java | Added JavaFX feeder registry and persistence of feeder UI state. |
| src/net/azib/ipscan/gui/fx/feeders/FXAbstractFeederGUI.java | Added JavaFX feeder GUI base class implementing FeederCreator. |
| src/net/azib/ipscan/gui/fetchers/PortTextFetcherPrefs.java | Deleted SWT PortText fetcher preferences dialog. |
| src/net/azib/ipscan/gui/fetchers/PortsFetcherPrefs.java | Deleted SWT Ports fetcher preferences shim. |
| src/net/azib/ipscan/gui/fetchers/PingFetcherPrefs.java | Deleted SWT Ping fetcher preferences shim. |
| src/net/azib/ipscan/gui/fetchers/MACFetcherPrefs.java | Deleted SWT MAC fetcher preferences dialog. |
| src/net/azib/ipscan/gui/feeders/RandomFeederGUI.java | Deleted SWT RandomFeeder UI. |
| src/net/azib/ipscan/gui/feeders/FileFeederGUI.java | Deleted SWT FileFeeder UI. |
| src/net/azib/ipscan/gui/feeders/FeederSelectionCombo.java | Deleted SWT feeder selection combo wrapper. |
| src/net/azib/ipscan/gui/feeders/FeederGUIRegistry.java | Deleted SWT feeder registry. |
| src/net/azib/ipscan/gui/feeders/FeederArea.java | Deleted SWT feeder area composite. |
| src/net/azib/ipscan/gui/feeders/ControlsArea.java | Deleted SWT controls area composite. |
| src/net/azib/ipscan/gui/feeders/AbstractFeederGUI.java | Deleted SWT feeder GUI base. |
| src/net/azib/ipscan/gui/EditFavoritesDialog.java | Deleted SWT favorites editor dialog. |
| src/net/azib/ipscan/gui/DetailsWindow.java | Deleted SWT details window. |
| src/net/azib/ipscan/gui/actions/ToolsActions.java | Deleted SWT tools actions (selection logic/UI hooks). |
| src/net/azib/ipscan/gui/actions/TerminalLauncher.java | Deleted SWT-era terminal launcher. |
| src/net/azib/ipscan/gui/actions/OpenerLauncher.java | Deleted SWT-era opener launcher. |
| src/net/azib/ipscan/gui/actions/HelpMenuActions.java | Deleted SWT help actions. |
| src/net/azib/ipscan/gui/actions/GotoMenuActions.java | Deleted SWT goto actions. |
| src/net/azib/ipscan/gui/actions/FeederActions.java | Deleted SWT feeder helper actions. |
| src/net/azib/ipscan/gui/actions/FavoritesMenuActions.java | Deleted SWT favorites menu actions. |
| src/net/azib/ipscan/gui/actions/ColumnsActions.java | Deleted SWT column header actions. |
| src/net/azib/ipscan/gui/actions/BrowserLauncher.java | Deleted SWT Program.launch-based browser launcher. |
| src/net/azib/ipscan/gui/AbstractModalDialog.java | Deleted SWT modal dialog base. |
| src/net/azib/ipscan/gui/AboutDialog.java | Deleted SWT about dialog. |
| src/net/azib/ipscan/fetchers/PortTextFetcher.java | Removed SWT preferences editor binding (prefs class now null). |
| src/net/azib/ipscan/fetchers/PortsFetcher.java | Removed SWT preferences editor binding (prefs class now null). |
| src/net/azib/ipscan/fetchers/PingFetcher.java | Removed SWT preferences editor binding (prefs class now null). |
| src/net/azib/ipscan/fetchers/OpenerLaunchFetcher.java | Added fetcher providing a clickable “open” indicator value. |
| src/net/azib/ipscan/fetchers/OpenerColumnFetcher.java | Added fetcher that displays per-IP default opener label/placeholder. |
| src/net/azib/ipscan/fetchers/MACFetcher.java | Removed SWT preferences editor binding (prefs class now null). |
| src/net/azib/ipscan/fetchers/FetcherRegistry.java | Simplified prefs editor instantiation; updated default selected fetchers. |
| src/net/azib/ipscan/exporters/TXTExporter.java | Updated TXT import API to consume FeederCreator instead of GUI type. |
| src/net/azib/ipscan/core/ScanningResultList.java | Added helpers for result snapshots, safe removals, and fetcher/result re-alignment. |
| src/net/azib/ipscan/core/ScanningResultComparator.java | Added fallback comparison when typed compare fails (ClassCastException). |
| src/net/azib/ipscan/config/OpenersConfig.java | Ensured default openers are always present and removed legacy opener.* keys. |
| src/net/azib/ipscan/config/GUIRegistry.java | Deleted SWT GUI DI registration. |
| src/net/azib/ipscan/config/GUIConfig.java | Added startup preference + column order persistence + feeder data helpers; removed SWT Point APIs. |
| src/net/azib/ipscan/config/FXComponentRegistry.java | Added minimal JavaFX DI registration (Stage). |
| src/net/azib/ipscan/config/DefaultOpenerConfig.java | Added file-based per-IP default opener persistence. |
| src/net/azib/ipscan/config/ConfigModule.java | Registered DefaultOpenerConfig in DI container. |
| src/net/azib/ipscan/config/Config.java | Added portable config directory resolution and exposed favorites/default openers accessors. |
| src/net/azib/ipscan/config/ComponentRegistry.java | Registered opener fetchers and moved pinger plugin loading outside GUI-only init. |
| src/net/azib/ipscan/config/CommentsConfig.java | Migrated comment persistence from Java Preferences to comments.txt in config dir. |
| run-javafx.bat | Added local developer convenience script (currently machine-specific). |
| run-ipscan.bat | Added local developer convenience script (currently machine-specific/outdated). |
| resources/messages.properties | Updated/added strings for opener columns, comments editing, startup options. |
| resources/messages_zh_TW.properties | Updated translated button.ipUp text. |
| resources/messages_zh_CN.properties | Updated translated button.ipUp text. |
| resources/messages_tr.properties | Updated translated button.ipUp text. |
| resources/messages_pt_BR.properties | Updated translated button.ipUp text. |
| resources/messages_it.properties | Updated translated button.ipUp text. |
| resources/messages_hu.properties | Added/updated opener/startup strings; updated button.ipUp. |
| resources/messages_ga_IE.properties | Updated translated button.ipUp text. |
| resources/messages_fr.properties | Updated translated button.ipUp text. |
| resources/messages_fi.properties | Updated translated button.ipUp text. |
| ext/jna.pro | Updated ProGuard config to suppress warnings for removed SWT + added JavaFX classes. |
| classpath.gradle | Added helper task to print runtimeClasspath. |
| build.gradle | Added JavaFX plugin/modules, removed SWT packaging, updated jar/jlink packaging logic. |
| AGENTS.md | Added repository guidance for agent/dev workflow verification. |
| .gitignore | Added bin/, *.jar, and hs_err_pid logs. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+60
to
+64
| public String get(String ip) { | ||
| var openerName = defaults.getProperty(ip); | ||
| if (openerName != null) return openerName; | ||
| return Labels.getInstance().get("opener.ping"); | ||
| } |
Comment on lines
+151
to
+155
| var oldName = listView.getItems().get(currentSelectionIndex); | ||
| var opener = openersConfig.getOpener(oldName); | ||
| var workingDir = workingDirText.getText().length() > 0 ? new File(workingDirText.getText()) : null; | ||
| openersConfig.add(nameText.getText(), new OpenersConfig.Opener(stringText.getText(), inTerminalCheck.isSelected(), workingDir)); | ||
| listView.getItems().set(currentSelectionIndex, nameText.getText()); |
Comment on lines
+3
to
+7
| set JAVA_HOME=C:\Users\peter\scoop\apps\openjdk21\current | ||
| set PATH=%JAVA_HOME%\bin;%PATH% | ||
| cd /d "I:\Angry IP Scanner\ipscan" | ||
|
|
||
| set GRADLE_CACHE=%USERPROFILE%\.gradle\caches\modules-2\files-2.1 |
Comment on lines
+3
to
+7
| set JAVA_HOME=C:\Users\peter\scoop\apps\openjdk21\current | ||
| set PATH=%JAVA_HOME%\bin;%PATH% | ||
| cd /d "I:\Angry IP Scanner\ipscan" | ||
| set PLUGIN_JAR=..\ipscan-tasmota-plugin\build\libs\ipscan-tasmota-plugin-1.0.1.jar | ||
| set SWT=C:\Users\peter\.gradle\caches\modules-2\files-2.1\org.eclipse.platform\org.eclipse.swt.win32.win32.x86_64\3.134.0\978f1c41438ebab37caf2e8d8446b420bf61c2a\org.eclipse.swt.win32.win32.x86_64-3.134.0.jar |
Comment on lines
10
to
+14
| public class FeederGUIRegistryTest { | ||
| private FeederArea parent; | ||
| private FeederGUIRegistry registry; | ||
| private FeederSelectionCombo feederSelectionCombo; | ||
| private RangeFeederGUI feederGUI; | ||
|
|
||
| @Before | ||
| public void createRegistry() { | ||
| parent = new FeederArea(new Shell()); | ||
|
|
||
| feederSelectionCombo = mock(FeederSelectionCombo.class); | ||
|
|
||
| feederGUI = new RangeFeederGUI(parent); | ||
| feederGUI.initialize(); | ||
| registry = new FeederGUIRegistry(Collections.singletonList(feederGUI), feederSelectionCombo, null); | ||
| } | ||
|
|
||
| @After | ||
| public void dispose() { | ||
| parent.dispose(); | ||
| } | ||
|
|
||
| @Test | ||
| public void addFeederNamesToTheCombo() throws Exception { | ||
| reset(feederSelectionCombo); | ||
| new FeederGUIRegistry(Collections.singletonList(feederGUI), feederSelectionCombo, null); | ||
| verify(feederSelectionCombo).add(Labels.getLabel(feederGUI.getFeederId())); | ||
| } | ||
|
|
||
| @Test | ||
| public void lastFeederIsNeverNull() throws Exception { | ||
| assertNotNull(registry.lastFeeder); | ||
| assertNotNull(registry.lastFeeder.toString()); | ||
| } | ||
|
|
||
| @Test | ||
| public void createFeederRemembersTheLastOne() throws Exception { | ||
| var lastFeeder = registry.createFeeder(); | ||
| assertSame(lastFeeder, registry.lastFeeder); | ||
| assertNotSame(lastFeeder, registry.createFeeder()); | ||
| public void rangeFeederIsNeverNull() throws Exception { | ||
| var feeder = new RangeFeeder("127.0.0.1", "127.0.0.2"); |
Comment on lines
+132
to
+135
| var stream = FXGUI.class.getResourceAsStream(path); | ||
| if (stream != null) { | ||
| javafx.scene.text.Font.loadFont(stream, -1); | ||
| } |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
1. File-based Comments + Inline Editing
Commits:
16033af8,7ade9ea5,57747ca2Textwidget;Enter/FocusOutsaves,Escapecancels.CommentsConfigpersists tocomments.txtinstead of Java Preferences (survives restarts, flushed immediately).Config.getConfigDir()— portable config directory next to the JAR, falls back to~/.ipscan.2. Default Opener per IP
Commits:
219305eb,4e8ac91e,4c0efca0,3e8f2333OpenerColumnFetcher— column showing the configured opener name; double-click opens a radio-menu to pick one.OpenerLaunchFetcher— centered triangle (▶) icon column; click to launch the default opener for that IP.DefaultOpenerConfig— per-IP opener assignment (persisted to file).3. ColumnVisibilityMenu (removes SelectFetchersDialog)
Commits:
ed77fc0cColumnVisibilityMenu— right-click on the table header toggles individual columns on/off inline.SelectFetchersDialog.java— old modal dialog removed.MacApplicationMenu,MainWindow,ToolsActions,ColumnsActions,CommandsMenuActions,OpenerLauncher,AbstractModalDialog.4. Column Order Persistence + Drag-Reorder
Commits: (Contained within
ed77fc0cand95c1f86e)saveColumnOrder()— persists visual column order viaguiConfig.setColumnOrder()after every drag.6. Column Header Tooltip
Commits:
3a2f7eaaHeaderTooltipPoller— polls cursor position every 100ms to show a width-capped (360px), wrapping tooltip over column headers.ResultTable Performance
Commits:
39b5cf1ecolumnFetcherIndexMapforpopulateNewFetcher()— background thread that fills a newly added fetcher column in batches (100 rows per UI update) without freezing the table.ScanningResultList.Table Rebuild on Fetcher Change
Commits: (Contained within
ed77fc0c)handleUpdateOfSelectedFetchers()now preserves scanned results, re-aligns columns in saved order, and populates newly added fetchers with real data off the UI thread.