我在JavaFX中使用一个简单的GUI端口扫描程序。它使用多个线程来发现本地网络中的在线主机。在主机发现过程开始之前,我想要禁用hostDiscovery
按钮。当我执行我的代码时,主机发现过程将完成,只有在完成后我的按钮才会被禁用。
我的FXML文件的一部分
<Button fx:id="hostDiscovery" layoutX="470.0" layoutY="370.0" mnemonicParsing="false" prefHeight="60.0" prefWidth="200.0" text="Start Host Discovery" AnchorPane.bottomAnchor="30.0" AnchorPane.rightAnchor="30.0" />
在Controller类中调试代码
public class FXMLController implements Initializable
{
@FXML
private Button hostDiscovery;
@Override // This method is called by the FXMLLoader when initialization is complete
public void initialize(URL fxmlFileLocation, ResourceBundle resources)
{
assert hostDiscovery != null : "fx:id=\"hostDiscovery\" was not injected: check your FXML file 'PortScanner.fxml'.";
// initialize your logic here: all @FXML variables will have been injected
hostDiscovery.setOnAction(event -> {
System.out.println("HD Test Start");
hostDiscovery.setDisable(true); //Here I want to disable the button
final int hostDiscoveryTimeout = 1000;
final int threads = 25;
final ExecutorService exService = Executors.newFixedThreadPool(threads);
final List<Future<HostDiscoveryResult>> futures = new ArrayList<>();
String ipAddress = "192.168.0.";
for (int i = 1; i < 255; i++)
{
StringBuilder currentIPAddress = new StringBuilder().append(ipAddress).append(i);
HostDiscovery dHost = new HostDiscovery(currentIPAddress.toString(), hostDiscoveryTimeout);
futures.add(dHost.multithreadedHostDicovery(exService));
}
try
{
exService.shutdown();
exService.awaitTermination(hostDiscoveryTimeout, TimeUnit.MILLISECONDS);
} catch (Exception e)
{
System.out.println(e);
}
for (final Future<HostDiscoveryResult> i : futures)
{
try
{
if (i.get().isOnline())
{
System.out.print(i.get().getIpAddress() + " ");
System.out.println(i.get().getHostName());
}
} catch (Exception e)
{
System.out.println(e);
}
}
System.out.println("HD Test Stop");
});
}
}
好的,在阅读了James_D发布的Using threads to make database requests这个帖子之后,我设法修改我的代码以按预期运行。这是修改后的版本
hostDiscovery.setOnAction(event -> {
Task<Void> hostDiscoveryTask = new Task<Void>()
{
@Override
protected Void call() throws Exception
{
System.out.println("HD Test Start");
final int hostDiscoveryTimeout = 1000;
final int threads = 25;
final ExecutorService exService = Executors.newFixedThreadPool(threads);
final List<Future<HostDiscoveryResult>> futures = new ArrayList<>();
String ipAddress = "192.168.0.";
for (int i = 1; i < 255; i++)
{
StringBuilder currentIPAddress = new StringBuilder().append(ipAddress).append(i);
HostDiscovery dHost = new HostDiscovery(currentIPAddress.toString(), hostDiscoveryTimeout);
futures.add(dHost.multithreadedHostDicovery(exService));
}
try
{
exService.shutdown();
exService.awaitTermination(hostDiscoveryTimeout, TimeUnit.MILLISECONDS);
} catch (Exception e)
{
System.out.println(e);
}
for (final Future<HostDiscoveryResult> i : futures)
{
try
{
if (i.get().isOnline())
{
System.out.print(i.get().getIpAddress() + " ");
System.out.println(i.get().getHostName());
}
} catch (Exception e)
{
System.out.println(e);
}
}
System.out.println("HD Test Stop");
Platform.runLater(() -> hostDiscovery.setDisable(false));
Platform.runLater(() -> hostDiscovery.setText("Restart Host Discovery"));
return null;
}
};
Thread thr = new Thread(hostDiscoveryTask);
hostDiscovery.setDisable(true);
hostDiscovery.setText("WORKING");
thr.setDaemon(true);
thr.start();
});
}
}