Я пишу приложение IP-сканер и процесс занимает много времени, так что я использовал на задней сцене графического интерфейса является услуга исполнителя, как:Как запустить сервис-исполнителя от Swing worker?
public static List<Future<String>> checkThisIP(String ipStart, String ipEnd) throws UnknownHostException {
final ExecutorService es = Executors.newFixedThreadPool(10);
final List<Future<String>> futures = new ArrayList<>();
String ipStringStart;
String ipStringEnd;
String targetIpString;
//my update
ipStringStart = ipStart.substring(ipStart.lastIndexOf(".") + 1, ipStart.length());
ipStringEnd = ipEnd.substring(ipEnd.lastIndexOf(".") + 1, ipEnd.length());
targetIpString = ipStart.substring(0, ipStart.lastIndexOf(".") + 1);
if (!ipStart.equals(ipEnd)) {
for (int i = Integer.parseInt(ipStringStart); i <= Integer.parseInt(ipStringEnd); i++) {
String currentIp = targetIpString + i;
futures.add(runPingScan(es, currentIp));
}
} else {
futures.add(runPingScan(es, ipStart));
}
es.shutdown();
return futures;
}
public static Future<String> runPingScan(final ExecutorService es, final String ip) {
return es.submit(new Callable<String>() {
@Override
public String call() {
String returnMe = "";
//custom ping class
Ping p = new Ping();
//send message
p.SendReply(ip);
//IsReachable returns ture or false
if(p.IsReachable()){
returnMe=ip;
}
return returnMe;
}
});
}
Это оригинальный лага кода действие предварительно с помощью JButton :
// scan result is Future list returned from service executor
List<Future<String>> scanResult = p.checkThisIP(jFormattedTextField1.getText(), jFormattedTextField2.getText());
for (final Future<String> f : scanResult) {
try {
ip = f.get();
if (!ip.equals("")) {
arp ARP = new arp();
PortScan openPort = new PortScan();
IP ipClass = new IP();
mac = ARP.getMac(ip);
manufacturer = ARP.getOUI(mac);
ports = openPort.checkIpForPorts(ip);
hostname = ipClass.hostname(ip);
title = ipClass.htmlTitle(ip);
Object[] data = {ip, mac, manufacturer, ports, hostname, title};
tableModel.addRow(data);
}
if (jFormattedTextField1.getText().equals(jFormattedTextField2.getText()) && ip.equals("")) {
JOptionPane.showMessageDialog(null, "<html>Can not ping the address ! <br> Server might be protected by <b>WAF</b>.</html>", "Alert", HEIGHT);
}
} catch (Exception ex) {
Logger.getLogger(gui.class.getName()).log(Level.SEVERE, null, ex);
}
}
Выполнение этого кода это хорошо, но когда я прикрепить его к кнопку Начать проверку ГПИ-лаги, я гугл и понял, использовать Swing Worker. Когда я реализовал только качели, он убил параллелизм, и когда я реализовал оба gui все еще лага. Мой вопрос заключается в том, чтобы заставить кнопку (рабочий Swing) вызвать исполнителя службы для выполнения других процессов?
Спасибо за разъяснение +1. Обратите внимание, что первым параметром Swingworker должен быть List>, и я пробовал ваш ответ, но я столкнулся с таким же отставанием. Посмотрите на мой ответ, я использовал функцию swingworker ** doInBackground() ** для вызова функций, которые используют ** сервис-исполнитель ** (причина задержки) без какой-либо другой функции swingfunction. –
Параметр первого типа определяет данные, созданные 'doInBackground', которые позже вызывается вызовом' get'. Он предназначен для того, чтобы просто быть списком строк, не нужно фьючерсов, так как все проверки ping будут завершены в этот момент. Если вы все делаете внутри 'doInBackground', убедитесь, что ваша модель правильно управляет обновлениями gui (т. Е.' InvokeLater'), поскольку Swing не является потокобезопасным, и все, что касается его компонентов, должно делать это из EDT. – duckstep
Насколько я знаю, список строк не может принимать List>. 'Список <Будущее > scanResult = p.checkThisIP (ip1, ip2); // функция возвращает список Future ', поэтому, если мы хотим вернуть этот список из' doInbackground() ', первый параметр должен быть' > '. P.S: Я пробовал попробовать сам. Благодаря ! –