diff --git a/src/net/azib/ipscan/config/CommandLineProcessor.java b/src/net/azib/ipscan/config/CommandLineProcessor.java index 0f3b0cd6..6152a613 100644 --- a/src/net/azib/ipscan/config/CommandLineProcessor.java +++ b/src/net/azib/ipscan/config/CommandLineProcessor.java @@ -24,7 +24,7 @@ import net.azib.ipscan.feeders.FeederRegistry; * * @author Anton Keks */ -public class CommandLineProcessor implements StateTransitionListener { +public class CommandLineProcessor implements CommandProcessor, StateTransitionListener { private final FeederRegistry feederRegistry; private final ExporterRegistry exporters; @@ -53,6 +53,14 @@ public class CommandLineProcessor implements StateTransitionListener { stateMachine.addTransitionListener(this); } + public boolean shouldAutoQuit() { + return autoQuit; + } + + public boolean shouldAutoStart() { + return autoStart; + } + public void parse(String ...args) { for (int i = 0; i < args.length; i++) { String arg = args[i]; diff --git a/src/net/azib/ipscan/config/CommandProcessor.java b/src/net/azib/ipscan/config/CommandProcessor.java new file mode 100644 index 00000000..b7b3ff24 --- /dev/null +++ b/src/net/azib/ipscan/config/CommandProcessor.java @@ -0,0 +1,17 @@ +/** + * This file is a part of Angry IP Scanner source code, + * see http://www.azib.net/ for more information. + * Licensed under GPLv2. + */ + +package net.azib.ipscan.config; + +/** + * Interface for providing of various commands to the application + * + * @author Anton Keks + */ +public interface CommandProcessor { + boolean shouldAutoStart(); + boolean shouldAutoQuit(); +} diff --git a/src/net/azib/ipscan/config/ComponentRegistry.java b/src/net/azib/ipscan/config/ComponentRegistry.java index 3b2ca207..0cfe23fd 100755 --- a/src/net/azib/ipscan/config/ComponentRegistry.java +++ b/src/net/azib/ipscan/config/ComponentRegistry.java @@ -12,7 +12,6 @@ import net.azib.ipscan.core.ScannerDispatcherThreadFactory; import net.azib.ipscan.core.ScanningResultList; import net.azib.ipscan.core.net.PingerRegistry; import net.azib.ipscan.core.net.PingerRegistryImpl; -import net.azib.ipscan.core.state.StateMachine; import net.azib.ipscan.exporters.CSVExporter; import net.azib.ipscan.exporters.ExporterRegistry; import net.azib.ipscan.exporters.IPListExporter; @@ -37,6 +36,7 @@ import net.azib.ipscan.gui.MainMenu; import net.azib.ipscan.gui.MainWindow; import net.azib.ipscan.gui.PreferencesDialog; import net.azib.ipscan.gui.ResultTable; +import net.azib.ipscan.gui.SWTAwareStateMachine; import net.azib.ipscan.gui.SelectFetchersDialog; import net.azib.ipscan.gui.StatisticsDialog; import net.azib.ipscan.gui.StatusBar; @@ -56,6 +56,7 @@ import net.azib.ipscan.gui.feeders.RangeFeederGUI; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.picocontainer.MutablePicoContainer; @@ -66,22 +67,22 @@ import org.picocontainer.defaults.ConstantParameter; import org.picocontainer.defaults.DefaultPicoContainer; /** - * This class is the dependency injection configuration - * using the Pico Container. - * + * This class is the dependency injection configuration using the Pico Container. + * * @author Anton Keks */ public class ComponentRegistry { - + private PicoContainer container; + private boolean containerStarted; - + public ComponentRegistry() { MutablePicoContainer container = new DefaultPicoContainer(); this.container = container; - + ComponentParameter anyComponentParameter = new ComponentParameter(); - + // non-GUI Config globalConfig = Config.getConfig(); container.registerComponentInstance(globalConfig.getPreferences()); @@ -92,13 +93,13 @@ public class ComponentRegistry { container.registerComponentInstance(Labels.getInstance()); container.registerComponentImplementation(CommentsConfig.class); container.registerComponentImplementation(ConfigDetector.class); - + container.registerComponentImplementation(ExporterRegistry.class); container.registerComponentImplementation(TXTExporter.class); container.registerComponentImplementation(CSVExporter.class); container.registerComponentImplementation(XMLExporter.class); container.registerComponentImplementation(IPListExporter.class); - + container.registerComponentImplementation(FetcherRegistry.class, FetcherRegistryImpl.class); container.registerComponentImplementation(IPFetcher.class); container.registerComponentImplementation(PingFetcher.class); @@ -110,91 +111,67 @@ public class ComponentRegistry { container.registerComponentImplementation(HTTPSenderFetcher.class); container.registerComponentImplementation(CommentFetcher.class); container.registerComponentImplementation(NetBIOSInfoFetcher.class); - + container.registerComponentImplementation(PingerRegistry.class, PingerRegistryImpl.class); container.registerComponentImplementation(ScanningResultList.class); container.registerComponentImplementation(Scanner.class); - container.registerComponentImplementation(StateMachine.class); + container.registerComponentImplementation(SWTAwareStateMachine.class); container.registerComponentImplementation(ScannerDispatcherThreadFactory.class); container.registerComponentImplementation(CommandLineProcessor.class); - + // GUI follows (TODO: move GUI to a separate place) - + // Some "shared" GUI components + container.registerComponentInstance(Display.getDefault()); container.registerComponentImplementation("mainShell", Shell.class); container.registerComponentImplementation("mainMenu", Menu.class, new Parameter[] { - new ComponentParameter("mainShell"), - new ConstantParameter(new Integer(SWT.BAR))}); + new ComponentParameter("mainShell"), new ConstantParameter(new Integer(SWT.BAR)) }); container.registerComponentImplementation("commandsMenu", CommandsMenu.class); - + container.registerComponentImplementation("feederArea", Composite.class, new Parameter[] { - new ComponentParameter("mainShell"), - new ConstantParameter(new Integer(SWT.NONE))}); + new ComponentParameter("mainShell"), new ConstantParameter(new Integer(SWT.NONE)) }); container.registerComponentImplementation("controlsArea", Composite.class, new Parameter[] { - new ComponentParameter("mainShell"), - new ConstantParameter(new Integer(SWT.NONE))}); + new ComponentParameter("mainShell"), new ConstantParameter(new Integer(SWT.NONE)) }); container.registerComponentImplementation("startStopButton", Button.class, new Parameter[] { - new ComponentParameter("controlsArea"), - new ConstantParameter(new Integer(SWT.NONE))}); - container.registerComponentImplementation("feederSelectionCombo", FeederSelectionCombo.class, new Parameter[] { - new ComponentParameter("controlsArea")}); - + new ComponentParameter("controlsArea"), new ConstantParameter(new Integer(SWT.NONE)) }); + container.registerComponentImplementation("feederSelectionCombo", FeederSelectionCombo.class, + new Parameter[] { new ComponentParameter("controlsArea") }); + // GUI Feeders container.registerComponentImplementation(FeederGUIRegistry.class); - Parameter[] feederGUIParameters = new Parameter[] {new ComponentParameter("feederArea")}; + Parameter[] feederGUIParameters = new Parameter[] { new ComponentParameter("feederArea") }; container.registerComponentImplementation(RangeFeederGUI.class, RangeFeederGUI.class, feederGUIParameters); container.registerComponentImplementation(RandomFeederGUI.class, RandomFeederGUI.class, feederGUIParameters); container.registerComponentImplementation(FileFeederGUI.class, FileFeederGUI.class, feederGUIParameters); - + container.registerComponentImplementation(OpenerLauncher.class); container.registerComponentImplementation(MainWindow.class, MainWindow.class, new Parameter[] { - new ComponentParameter("mainShell"), - anyComponentParameter, - new ComponentParameter("feederArea"), - new ComponentParameter("controlsArea"), - new ComponentParameter("feederSelectionCombo"), - new ComponentParameter("startStopButton"), - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter}); + new ComponentParameter("mainShell"), anyComponentParameter, new ComponentParameter("feederArea"), + new ComponentParameter("controlsArea"), new ComponentParameter("feederSelectionCombo"), + new ComponentParameter("startStopButton"), anyComponentParameter, anyComponentParameter, + anyComponentParameter, anyComponentParameter, anyComponentParameter, anyComponentParameter, + anyComponentParameter, anyComponentParameter }); container.registerComponentImplementation(ResultTable.class, ResultTable.class, new Parameter[] { - new ComponentParameter("mainShell"), - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter, - anyComponentParameter}); + new ComponentParameter("mainShell"), anyComponentParameter, anyComponentParameter, + anyComponentParameter, anyComponentParameter, anyComponentParameter, anyComponentParameter, + anyComponentParameter }); container.registerComponentImplementation(StatusBar.class, StatusBar.class, new Parameter[] { - new ComponentParameter("mainShell"), - anyComponentParameter, - anyComponentParameter}); - + new ComponentParameter("mainShell"), anyComponentParameter, anyComponentParameter }); + container.registerComponentImplementation(MainMenu.class, MainMenu.class, new Parameter[] { - new ComponentParameter("mainShell"), - new ComponentParameter("mainMenu"), - new ComponentParameter("commandsMenu"), - anyComponentParameter, - new ConstantParameter(container)}); - container.registerComponentImplementation(MainMenu.ColumnsMenu.class, MainMenu.ColumnsMenu.class, new Parameter[] { - new ComponentParameter("mainShell"), - anyComponentParameter, - anyComponentParameter, - anyComponentParameter}); - + new ComponentParameter("mainShell"), new ComponentParameter("mainMenu"), + new ComponentParameter("commandsMenu"), anyComponentParameter, new ConstantParameter(container) }); + container.registerComponentImplementation(MainMenu.ColumnsMenu.class, MainMenu.ColumnsMenu.class, + new Parameter[] { new ComponentParameter("mainShell"), anyComponentParameter, anyComponentParameter, + anyComponentParameter }); + container.registerComponentImplementation(AboutDialog.class); container.registerComponentImplementation(PreferencesDialog.class); container.registerComponentImplementation(ConfigDetectorDialog.class); container.registerComponentImplementation(SelectFetchersDialog.class); container.registerComponentImplementation(DetailsWindow.class); container.registerComponentImplementation(StatisticsDialog.class); - + // various actions / listeners container.registerComponentImplementation(StartStopScanningAction.class); container.registerComponentImplementation(ColumnsActions.SortBy.class); @@ -211,21 +188,22 @@ public class ComponentRegistry { if (Platform.MAC_OS) { // initialize mac-specific stuff try { - container.registerComponentImplementation(Class.forName("net.azib.ipscan.platform.mac.MacApplicationMenu")); + container.registerComponentImplementation(Class + .forName("net.azib.ipscan.platform.mac.MacApplicationMenu")); } catch (Exception e) { Logger.getLogger(getClass().getName()).warning("Cannot initialize MacApplicationMenu: " + e); } } } - + private void start() { if (!containerStarted) { containerStarted = true; container.start(); } } - + public MainWindow getMainWindow() { // initialize all startable components start(); diff --git a/src/net/azib/ipscan/core/ScannerDispatcherThread.java b/src/net/azib/ipscan/core/ScannerDispatcherThread.java index 103d7427..0c930066 100755 --- a/src/net/azib/ipscan/core/ScannerDispatcherThread.java +++ b/src/net/azib/ipscan/core/ScannerDispatcherThread.java @@ -26,7 +26,7 @@ import net.azib.ipscan.util.InetAddressUtils; */ public class ScannerDispatcherThread extends Thread implements ThreadFactory, StateTransitionListener { - private static final long UI_UPDATE_INTERVAL = 100; + private static final long UI_UPDATE_INTERVAL_MS = 150; private ScannerConfig config; private Scanner scanner; @@ -100,9 +100,10 @@ public class ScannerDispatcherThread extends Thread implements ThreadFactory, St threadPool.execute(scanningTask); } - // notify listeners of the progress we are doing (max 5 times per second) - if (System.currentTimeMillis() - lastNotifyTime >= UI_UPDATE_INTERVAL) { - lastNotifyTime = System.currentTimeMillis(); + // notify listeners of the progress we are doing (limiting the update rate) + long now = System.currentTimeMillis(); + if (now - lastNotifyTime >= UI_UPDATE_INTERVAL_MS) { + lastNotifyTime = now; progressCallback.updateProgress(subject.getAddress(), numActiveThreads.intValue(), feeder.percentageComplete()); } } @@ -120,7 +121,7 @@ public class ScannerDispatcherThread extends Thread implements ThreadFactory, St try { // now wait for all threads, which are still running - while (!threadPool.awaitTermination(UI_UPDATE_INTERVAL, TimeUnit.MILLISECONDS)) { + while (!threadPool.awaitTermination(UI_UPDATE_INTERVAL_MS, TimeUnit.MILLISECONDS)) { progressCallback.updateProgress(null, numActiveThreads.intValue(), 100); } } diff --git a/src/net/azib/ipscan/core/ScanningResultList.java b/src/net/azib/ipscan/core/ScanningResultList.java index f779469e..ecc92c53 100755 --- a/src/net/azib/ipscan/core/ScanningResultList.java +++ b/src/net/azib/ipscan/core/ScanningResultList.java @@ -318,13 +318,15 @@ public class ScanningResultList implements Iterable { class StopScanningListener implements StateTransitionListener { public void transitionTo(ScanningState state, Transition transition) { - if (transition == Transition.COMPLETE && state == ScanningState.IDLE) { - info.endTime = System.currentTimeMillis(); - info.scanFinished = true; - } - else - if (state == ScanningState.KILLING) { - info.scanAborted = true; + synchronized (ScanningResultList.this) { + if (transition == Transition.COMPLETE && state == ScanningState.IDLE) { + info.endTime = System.currentTimeMillis(); + info.scanFinished = true; + } + else + if (state == ScanningState.KILLING) { + info.scanAborted = true; + } } } } diff --git a/src/net/azib/ipscan/core/state/StateMachine.java b/src/net/azib/ipscan/core/state/StateMachine.java index d48b8c58..33fd8948 100644 --- a/src/net/azib/ipscan/core/state/StateMachine.java +++ b/src/net/azib/ipscan/core/state/StateMachine.java @@ -10,12 +10,15 @@ import java.util.List; import java.util.concurrent.locks.ReentrantReadWriteLock; /** - * StateMachine implementation. + * Generic StateMachine implementation. * It holds the current state and performs transitions with corresponding methods. + *

+ * Note: the class is abstract because notification of listeners often should happen in the correct thread, + * so subclasses should provide this functionality. * * @author Anton Keks */ -public class StateMachine { +public abstract class StateMachine { public enum Transition {INIT, START, STOP, NEXT, COMPLETE, RESET, RESCAN} @@ -79,7 +82,7 @@ public class StateMachine { } } - private void notifyAboutTransition(Transition transition) { + protected void notifyAboutTransition(Transition transition) { try { listenersLock.readLock().lock(); for (StateTransitionListener listener : transitionListeners) { diff --git a/src/net/azib/ipscan/gui/MainMenu.java b/src/net/azib/ipscan/gui/MainMenu.java index 8a64747f..bbf2fbd1 100755 --- a/src/net/azib/ipscan/gui/MainMenu.java +++ b/src/net/azib/ipscan/gui/MainMenu.java @@ -280,27 +280,22 @@ public class MainMenu implements Startable { } public void transitionTo(final ScanningState state, Transition transition) { - if (state != ScanningState.SCANNING && state != ScanningState.IDLE) + if (transition != Transition.START && transition != Transition.COMPLETE) return; - - menu.getDisplay().asyncExec(new Runnable() { - public void run() { - processMenu(menu); + processMenu(menu, state == ScanningState.IDLE); + } + + public void processMenu(Menu menu, boolean isEnabled) { + // processes menu items recursively + for (MenuItem item : menu.getItems()) { + if (item.getData("disableDuringScanning") == Boolean.TRUE) { + item.setEnabled(isEnabled); } - - public void processMenu(Menu menu) { - // processes menu items recursively - for (MenuItem item : menu.getItems()) { - if (item.getData("disableDuringScanning") == Boolean.TRUE) { - item.setEnabled(state == ScanningState.IDLE); - } - else - if (item.getMenu() != null) { - processMenu(item.getMenu()); - } - } + else + if (item.getMenu() != null) { + processMenu(item.getMenu(), isEnabled); } - }); + } } } } diff --git a/src/net/azib/ipscan/gui/MainWindow.java b/src/net/azib/ipscan/gui/MainWindow.java index 8e9b98c3..9e903a10 100755 --- a/src/net/azib/ipscan/gui/MainWindow.java +++ b/src/net/azib/ipscan/gui/MainWindow.java @@ -268,19 +268,15 @@ public class MainWindow { class EnablerDisabler implements StateTransitionListener { public void transitionTo(final ScanningState state, Transition transition) { - if (state != ScanningState.SCANNING && state != ScanningState.IDLE) + if (transition != Transition.START && transition != Transition.COMPLETE) return; - shell.getDisplay().asyncExec(new Runnable() { - public void run() { - boolean enabled = state == ScanningState.IDLE; - feederArea.setEnabled(enabled); - feederSelectionCombo.setEnabled(enabled); - prefsButton.setEnabled(enabled); - fetchersButton.setEnabled(enabled); - statusBar.setEnabled(enabled); - } - }); + boolean enabled = state == ScanningState.IDLE; + feederArea.setEnabled(enabled); + feederSelectionCombo.setEnabled(enabled); + prefsButton.setEnabled(enabled); + fetchersButton.setEnabled(enabled); + statusBar.setEnabled(enabled); } } diff --git a/src/net/azib/ipscan/gui/ResultTable.java b/src/net/azib/ipscan/gui/ResultTable.java index 96674f1b..2f361aa3 100755 --- a/src/net/azib/ipscan/gui/ResultTable.java +++ b/src/net/azib/ipscan/gui/ResultTable.java @@ -132,7 +132,7 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener, public void addOrUpdateResultRow(final ScanningResult result) { if (isDisposed()) return; - getDisplay().syncExec(new Runnable() { + getDisplay().asyncExec(new Runnable() { public void run() { if (isDisposed()) return; @@ -242,13 +242,9 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener, } - public void transitionTo(final ScanningState state, Transition transition) { + public void transitionTo(ScanningState state, Transition transition) { // change cursor while scanning - getDisplay().asyncExec(new Runnable() { - public void run() { - setCursor(getDisplay().getSystemCursor(state == ScanningState.IDLE ? SWT.CURSOR_ARROW : SWT.CURSOR_APPSTARTING)); - } - }); + setCursor(getDisplay().getSystemCursor(state == ScanningState.IDLE ? SWT.CURSOR_ARROW : SWT.CURSOR_APPSTARTING)); } } diff --git a/src/net/azib/ipscan/gui/SWTAwareStateMachine.java b/src/net/azib/ipscan/gui/SWTAwareStateMachine.java new file mode 100644 index 00000000..3a472128 --- /dev/null +++ b/src/net/azib/ipscan/gui/SWTAwareStateMachine.java @@ -0,0 +1,42 @@ +/** + * This file is a part of Angry IP Scanner source code, + * see http://www.azib.net/ for more information. + * Licensed under GPLv2. + */ + +package net.azib.ipscan.gui; + +import org.eclipse.swt.widgets.Display; + +import net.azib.ipscan.core.state.StateMachine; +import net.azib.ipscan.core.state.StateTransitionListener; + +/** + * Extends the generic {@link StateMachine} in order to run state transition notifications + * in the SWT user-interface thread. This will allow {@link StateTransitionListener}s to call SWT methods without + * the bloat of using the {@link Display#asyncExec(Runnable)} themselves. + * + * @author Anton Keks + */ +public class SWTAwareStateMachine extends StateMachine { + + private Display display; + + public SWTAwareStateMachine(Display display) { + this.display = display; + } + + @Override + protected void notifyAboutTransition(final Transition transition) { + if (display.isDisposed()) + return; + + // call super asynchronously in the correct thread + display.asyncExec(new Runnable() { + public void run() { + SWTAwareStateMachine.super.notifyAboutTransition(transition); + } + }); + } + +} diff --git a/src/net/azib/ipscan/gui/actions/StartStopScanningAction.java b/src/net/azib/ipscan/gui/actions/StartStopScanningAction.java index 305f84f6..34363988 100755 --- a/src/net/azib/ipscan/gui/actions/StartStopScanningAction.java +++ b/src/net/azib/ipscan/gui/actions/StartStopScanningAction.java @@ -138,63 +138,57 @@ public class StartStopScanningAction implements SelectionListener, ScanningProgr } public void transitionTo(final ScanningState state, final Transition transition) { - if (display.isDisposed()) + if (statusBar.isDisposed() || transition == Transition.INIT) return; - display.syncExec(new Runnable() { - public void run() { - if (statusBar.isDisposed() || transition == Transition.INIT) - return; - - // TODO: separate GUI and non-GUI stuff - switch (state) { - case IDLE: - // reset state text - button.setEnabled(true); - updateProgress(null, 0, 0); - statusBar.setStatusText(null); - break; - case STARTING: - // start the scan from scratch! - resultTable.removeAll(); - try { - scannerThread = scannerThreadFactory.createScannerThread(feederRegistry.createFeeder(), StartStopScanningAction.this, createResultsCallback()); - stateMachine.startScanning(); - mainWindowTitle = statusBar.getShell().getText(); - } - catch (RuntimeException e) { - stateMachine.reset(); - throw e; - } - break; - case RESTARTING: - // restart the scanning - rescan - resultTable.resetSelection(); - try { - scannerThread = scannerThreadFactory.createScannerThread(feederRegistry.createRescanFeeder(resultTable.getSelection()), StartStopScanningAction.this, createResultsCallback()); - stateMachine.startScanning(); - mainWindowTitle = statusBar.getShell().getText(); - } - catch (RuntimeException e) { - stateMachine.reset(); - throw e; - } - break; - case SCANNING: - scannerThread.start(); - break; - case STOPPING: - statusBar.setStatusText(Labels.getLabel("state.waitForThreads")); - break; - case KILLING: - button.setEnabled(false); - statusBar.setStatusText(Labels.getLabel("state.killingThreads")); - break; + + // TODO: separate GUI and non-GUI stuff + switch (state) { + case IDLE: + // reset state text + button.setEnabled(true); + updateProgress(null, 0, 0); + statusBar.setStatusText(null); + break; + case STARTING: + // start the scan from scratch! + resultTable.removeAll(); + try { + scannerThread = scannerThreadFactory.createScannerThread(feederRegistry.createFeeder(), StartStopScanningAction.this, createResultsCallback()); + stateMachine.startScanning(); + mainWindowTitle = statusBar.getShell().getText(); } - // change button image - button.setImage(buttonImages[state.ordinal()]); - button.setText(buttonTexts[state.ordinal()]); - } - }); + catch (RuntimeException e) { + stateMachine.reset(); + throw e; + } + break; + case RESTARTING: + // restart the scanning - rescan + resultTable.resetSelection(); + try { + scannerThread = scannerThreadFactory.createScannerThread(feederRegistry.createRescanFeeder(resultTable.getSelection()), StartStopScanningAction.this, createResultsCallback()); + stateMachine.startScanning(); + mainWindowTitle = statusBar.getShell().getText(); + } + catch (RuntimeException e) { + stateMachine.reset(); + throw e; + } + break; + case SCANNING: + scannerThread.start(); + break; + case STOPPING: + statusBar.setStatusText(Labels.getLabel("state.waitForThreads")); + break; + case KILLING: + button.setEnabled(false); + statusBar.setStatusText(Labels.getLabel("state.killingThreads")); + break; + } + // change button image + button.setImage(buttonImages[state.ordinal()]); + button.setText(buttonTexts[state.ordinal()]); } /** diff --git a/src/net/azib/ipscan/gui/actions/ToolsActions.java b/src/net/azib/ipscan/gui/actions/ToolsActions.java index b5f6d2c9..90a93e42 100755 --- a/src/net/azib/ipscan/gui/actions/ToolsActions.java +++ b/src/net/azib/ipscan/gui/actions/ToolsActions.java @@ -5,6 +5,7 @@ */ package net.azib.ipscan.gui.actions; +import net.azib.ipscan.config.CommandProcessor; import net.azib.ipscan.config.GUIConfig; import net.azib.ipscan.config.Labels; import net.azib.ipscan.core.ScanningResultList; @@ -20,7 +21,6 @@ import net.azib.ipscan.gui.StatisticsDialog; import net.azib.ipscan.gui.StatusBar; import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; @@ -74,11 +74,12 @@ public class ToolsActions { private final StatisticsDialog statisticsDialog; private final GUIConfig guiConfig; - public ScanStatistics(GUIConfig guiConfig, StatisticsDialog statisticsDialog, StateMachine stateMachine) { + public ScanStatistics(GUIConfig guiConfig, StatisticsDialog statisticsDialog, StateMachine stateMachine, CommandProcessor commandProcessor) { this.guiConfig = guiConfig; this.statisticsDialog = statisticsDialog; // register for state changes - stateMachine.addTransitionListener(this); + if (!commandProcessor.shouldAutoQuit()) + stateMachine.addTransitionListener(this); } public void handleEvent(Event event) { @@ -88,11 +89,7 @@ public class ToolsActions { public void transitionTo(ScanningState state, Transition transition) { // switching to IDLE means the end of scanning if (transition == Transition.COMPLETE && guiConfig.showScanStats) { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - handleEvent(null); - } - }); + handleEvent(null); } } } diff --git a/test/net/azib/ipscan/core/ScanningResultListTest.java b/test/net/azib/ipscan/core/ScanningResultListTest.java index feb31a8b..63c131e0 100755 --- a/test/net/azib/ipscan/core/ScanningResultListTest.java +++ b/test/net/azib/ipscan/core/ScanningResultListTest.java @@ -66,7 +66,7 @@ public class ScanningResultListTest { @Test public void testConstructor() throws Exception { - StateMachine stateMachine = new StateMachine(); + StateMachine stateMachine = new StateMachine(){}; scanningResults = new ScanningResultList(fetcherRegistry, stateMachine); scanningResults.initNewScan(createMockFeeder("inff")); assertFalse(scanningResults.getScanInfo().isCompletedNormally()); diff --git a/test/net/azib/ipscan/core/state/StateMachineTest.java b/test/net/azib/ipscan/core/state/StateMachineTest.java index f6cb708d..dfffd9c2 100644 --- a/test/net/azib/ipscan/core/state/StateMachineTest.java +++ b/test/net/azib/ipscan/core/state/StateMachineTest.java @@ -23,7 +23,8 @@ public class StateMachineTest { @Before public void createStateMachine() { - stateMachine = new StateMachine(); + // create empty subclass of StateMachine + stateMachine = new StateMachine(){}; } @Test