Java GUI对按钮单击没有响应
我正在尝试用Java编写一个简单的端口扫描程序。它可以工作,但是一旦扫描开始,整个窗口就会停止对点击的响应。这不允许我使用停止按钮暂停操作或退出窗口。这是我的密码:Java GUI对按钮单击没有响应,java,swing,port-scanning,Java,Swing,Port Scanning,我正在尝试用Java编写一个简单的端口扫描程序。它可以工作,但是一旦扫描开始,整个窗口就会停止对点击的响应。这不允许我使用停止按钮暂停操作或退出窗口。这是我的密码: import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import javax.swing.*; import java.awt.event.*; public class GUIScanner { JF
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import javax.swing.*;
import java.awt.event.*;
public class GUIScanner {
JFrame frame = new JFrame("Port Scanner");
JTextField textField = new JTextField("",20);
JPanel panel = new JPanel();
JButton button = new JButton("Scan");
JButton button2 = new JButton("Stop");
JLabel label = new JLabel("");
boolean stopped = false;
public GUIScanner() {
initialize();
}
public static void main(String[] args) {
GUIScanner scanner = new GUIScanner();
}
public void initialize() {
panel.add(textField);
panel.add(button);
panel.add(button2);
frame.add(panel);
frame.setSize(500, 500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String address = textField.getText().toString();
scanHost(address, 200);
}
});
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stopped) {
stopped = true;
button2.setText("Resume");
} else {
stopped = false;
button2.setText("Stop");
}
}
});
}
public void scanHost(String ip, int timeout) {
while(!stopped) {
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stopped) {
stopped = true;
button2.setText("Resume");
} else {
stopped = false;
button2.setText("Stop");
}
}
});
for(int port = 0; port <= 65535; port++) {
frame.setTitle("Scanning port " + port + " of 65535");
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(ip, port), timeout);
socket.close();
System.out.println(port);
} catch (IOException e) {
}
}
}
}
}
import java.io.IOException;
导入java.net.InetSocketAddress;
导入java.net.Socket;
导入javax.swing.*;
导入java.awt.event.*;
公共类GUI扫描器{
JFrame=新的JFrame(“端口扫描仪”);
JTextField textField=新的JTextField(“,20”);
JPanel面板=新的JPanel();
JButton按钮=新JButton(“扫描”);
JButton button2=新JButton(“停止”);
JLabel标签=新的JLabel(“”);
布尔停止=假;
公共GUIScanner(){
初始化();
}
公共静态void main(字符串[]args){
GUIScanner=新的GUIScanner();
}
公共无效初始化(){
panel.add(textField);
面板。添加(按钮);
面板。添加(按钮2);
框架。添加(面板);
框架。设置尺寸(500500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addActionListener(新建ActionListener()){
已执行的公共无效操作(操作事件e){
字符串地址=textField.getText().toString();
扫描主机(地址:200);
}
});
button2.addActionListener(新建ActionListener(){
已执行的公共无效操作(操作事件e){
如果(!停止){
停止=真;
按钮2.setText(“恢复”);
}否则{
停止=错误;
按钮2.设置文本(“停止”);
}
}
});
}
公共无效扫描主机(字符串ip,int超时){
当(!停止){
button2.addActionListener(新建ActionListener(){
已执行的公共无效操作(操作事件e){
如果(!停止){
停止=真;
按钮2.setText(“恢复”);
}否则{
停止=错误;
按钮2.设置文本(“停止”);
}
}
});
对于(int-port=0;port欢迎来到“亲爱的,我阻止了事件调度线程”的精彩世界
首先看一看更多的概述
从本质上讲,Swing是单线程的,并且不是线程安全的。这意味着您永远不应该在EDT上下文中执行长时间运行或阻塞操作,但也不应该从EDT上下文之外更新UI
而应考虑使用诸如 SWIWORKWORKS 之类的东西,允许您在后台运行阻塞/长运行操作,但提供功能:<代码>发布< /代码>和<代码>进程>代码>更新:在EDT
< P>欢迎来到“亲爱的,我阻塞了事件调度线程”的奇妙世界。
首先看一看更多的概述
从本质上讲,Swing是单线程的,并且不是线程安全的。这意味着您永远不应该在EDT上下文中执行长时间运行或阻塞操作,但也不应该从EDT上下文之外更新UI
而应考虑使用“代码> Swing Works/CODE >之类的东西,它允许你在后台运行阻塞/长时间运行,但是提供了功能:<代码>发布< /COD>和进程/<代码>更新,在EDT
< P>使用SWIFEWORKER在后台运行另一个线程。当您暂停后台线程时,端口扫描程序代码被取消。以下是端口扫描程序代码的更正版本:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import javax.swing.*;
import java.awt.event.*;
public class GUIScanner {
JFrame frame = new JFrame("Port Scanner");
JTextField textField = new JTextField("", 20);
JPanel panel = new JPanel();
JButton button = new JButton("Scan");
JButton button2 = new JButton("Stop");
JLabel label = new JLabel("");
boolean stopped = false;
PausableSwingWorker<Void, String> scanningWorker;
abstract class PausableSwingWorker<K, V> extends SwingWorker<K, V> {
private volatile boolean isPaused;
final Object lock = new Object();
public final void pause() {
if (!isPaused() && !isDone()) {
isPaused = true;
}
}
public final void resume() {
if (isPaused() && !isDone()) {
isPaused = false;
synchronized(lock) {
lock.notify();
}
}
}
public final boolean isPaused() {
return isPaused;
}
}
public GUIScanner() {
initialize();
}
public static void main(String[] args) {
GUIScanner scanner = new GUIScanner();
}
public void initialize() {
panel.add(textField);
panel.add(button);
panel.add(button2);
frame.add(panel);
frame.setSize(500, 500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String address = textField.getText().toString();
scanHost(address, 200);
}
});
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!stopped) {
stopped = true;
button2.setText("Resume");
scanningWorker.pause();
} else {
stopped = false;
button2.setText("Stop");
scanningWorker.resume();
}
}
});
}
public void scanHost(String ip, int timeout) {
scanningWorker = new PausableSwingWorker<Void, String>() {
@Override
public Void doInBackground() {
for (int port = 0; port <= 65535; port++) {
if (!isPaused()) {
frame.setTitle("Scanning port " + port + " of 65535");
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(ip, port), timeout);
socket.close();
System.out.println("Port " + port + " is open");
} catch (IOException e) {
}
}
else {
synchronized(lock) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return null;
}
@Override
public void done() {
}
};
scanningWorker.execute();
}
}
import java.io.IOException;
导入java.net.InetSocketAddress;
导入java.net.Socket;
导入javax.swing.*;
导入java.awt.event.*;
公共类GUI扫描器{
JFrame=新的JFrame(“端口扫描仪”);
JTextField textField=新的JTextField(“,20”);
JPanel面板=新的JPanel();
JButton按钮=新JButton(“扫描”);
JButton button2=新JButton(“停止”);
JLabel标签=新的JLabel(“”);
布尔停止=假;
PausableSwingWorker扫描工人;
抽象类PausableSwingWorker扩展了SwingWorker{
私营部门的支持;
最终对象锁=新对象();
公共最终无效暂停(){
如果(!isPaused()&&!isDone()){
isPaused=真;
}
}
公开最终作废简历(){
如果(isPaused()&&!isDone()){
isPaused=false;
已同步(锁定){
lock.notify();
}
}
}
公共最终布尔值isPaused(){
返回是有理由的;
}
}
公共GUIScanner(){
初始化();
}
公共静态void main(字符串[]args){
GUIScanner=新的GUIScanner();
}
公共无效初始化(){
panel.add(textField);
面板。添加(按钮);
面板。添加(按钮2);
框架。添加(面板);
框架。设置尺寸(500500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addActionListener(新建ActionListener()){
已执行的公共无效操作(操作事件e){
字符串地址=textField.getText().toString();
扫描主机(地址:200);
}
});
button2.addActionListener(新建ActionListener(){
已执行的公共无效操作(操作事件e){
如果(!停止){
停止=真;
按钮2.setText(“恢复”);
scanningWorker.pause();
}否则{
停止=错误;
按钮2.设置文本(“停止”);
scanningWorker.resume();
}
}
});
}
公共无效扫描主机(字符串ip,int超时){
scanningWorker=新的PausableSwingWorker(){
@凌驾
酒吧