Skip to content

New features - #527

Open
zaum wants to merge 18 commits into
angryip:masterfrom
zaum:new-features
Open

New features#527
zaum wants to merge 18 commits into
angryip:masterfrom
zaum:new-features

Conversation

@zaum

@zaum zaum commented Jul 22, 2026

Copy link
Copy Markdown

1. File-based Comments + Inline Editing

Commits: 16033af8, 7ade9ea5, 57747ca2

  • New: Inline comment editor — double-click a comment cell opens a Text widget; Enter/FocusOut saves, Escape cancels.
  • New: CommentsConfig persists to comments.txt instead of Java Preferences (survives restarts, flushed immediately).
  • New: Config.getConfigDir() — portable config directory next to the JAR, falls back to ~/.ipscan.
image
  • New: Add auto-start scan preference
image

2. Default Opener per IP

Commits: 219305eb, 4e8ac91e, 4c0efca0, 3e8f2333

  • New: OpenerColumnFetcher — column showing the configured opener name; double-click opens a radio-menu to pick one.
  • New: OpenerLaunchFetcher — centered triangle () icon column; click to launch the default opener for that IP.
  • New: DefaultOpenerConfig — per-IP opener assignment (persisted to file).
image

3. ColumnVisibilityMenu (removes SelectFetchersDialog)

Commits: ed77fc0c

  • New: ColumnVisibilityMenu — right-click on the table header toggles individual columns on/off inline.
  • Deleted: SelectFetchersDialog.java — old modal dialog removed.
  • Modified: MacApplicationMenu, MainWindow, ToolsActions, ColumnsActions, CommandsMenuActions, OpenerLauncher, AbstractModalDialog.
image

4. Column Order Persistence + Drag-Reorder

Commits: (Contained within ed77fc0c and 95c1f86e)

  • New: saveColumnOrder() — persists visual column order via guiConfig.setColumnOrder() after every drag.
  • New: IP column is pinned to visual position 0 and never movable.
  • New: Drag-to-reorder is disabled during scan, re-enabled when idle.
drag

6. Column Header Tooltip

Commits: 3a2f7eaa

  • New: HeaderTooltipPoller — polls cursor position every 100ms to show a width-capped (360px), wrapping tooltip over column headers.
  • New: 2-second delay before showing, instant hide on focus loss, auto-positions below the hovered header.
image

ResultTable Performance
Commits: 39b5cf1e

  • New: Precomputed columnFetcherIndexMap for $O(1)$ fetcher lookup during virtual-table rendering.
  • New: populateNewFetcher() — background thread that fills a newly added fetcher column in batches (100 rows per UI update) without freezing the table.
  • Modified: ScanningResultList.

Table Rebuild on Fetcher Change
Commits: (Contained within ed77fc0c)

  • New: handleUpdateOfSelectedFetchers() now preserves scanned results, re-aligns columns in saved order, and populates newly added fetchers with real data off the UI thread.

zaum added 18 commits July 19, 2026 13:46
…for setting and opening with default openers
…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.
@angryziber

Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts in this pull request

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 in comments.txt, per-IP default openers stored in openers-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 thread run-javafx.bat
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 thread run-ipscan.bat
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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants