当我在其中按下带有for循环事件的jbutton时,其他组件被禁用。
以下是我的jbutton代码:
try{
InetAddress localhost = InetAddress.getLocalHost();
byte[] ip = localhost.getAddress();
for(int i=1;i<254;i++){
ip[3]=(byte)i;
final InetAddress address = InetAddress.getByAddress(ip);
if(address.isReachable(1000)){
listModel1.addElement(address);
System.out.println(address + "-Machine is turned on and can be ping.");
Rectangle progressRec = jProgressBar1.getBounds();
progressRec.x = 0;
progressRec.y = 0;
jProgressBar1.setValue(i);
jProgressBar1.paintImmediately(progressRec);
}
}
jList1.setModel(listModel1);
}catch(Exception e){
e.printStackTrace();
}
循环结束后,其他组件是否已启用?我怎么去处理它?提前谢谢......
编辑的代码:建议不擅长编码
try{
InetAddress localhost = InetAddress.getLocalHost();
final byte[] ip = localhost.getAddress();
SwingWorker<ListModel, InetAddress> worker = new SwingWorker<ListModel, InetAddress>(){
public ListModel doInBackground() throws UnknownHostException, IOException{
for(int i=1;i<254;i++){
ip[3]=(byte)i;
final InetAddress address = InetAddress.getByAddress(ip);
if(address.isReachable(1000)){
publish(address);
listModel1.addElement(address);
Rectangle progressRec = jProgressBar1.getBounds();
progressRec.x = 0;
progressRec.y = 0;
jProgressBar1.setValue(i);
jProgressBar1.paintImmediately(progressRec);
}
}
return listModel1;
}
@Override
public void process(List<InetAddress> addresses){//there was a problem here.
for(InetAddress address : addresses){
System.out.println(address + "-Machine is turned on and can be ping.");
}
}
@Override
public void done(){
try {
jList1.setModel(get());
} catch (InterruptedException ex) {
Logger.getLogger(NetCafeTime.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(NetCafeTime.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
worker.execute();
}catch(Exception e){
e.printStackTrace();
}
答案 0 :(得分:5)
据推测,“残疾人”是指他们没有反应。
这种情况正在发生,因为您在Event Dispatch Thread中执行非常昂贵/长期的操作,这些操作处理所有与GUI相关的操作,例如重新绘制组件。当您的代码阻止此线程时,Swing无法快速执行常规操作,UI将无法响应用户操作,并且绘制或绘制操作也可能看起来滞后/冻结。
您应该生成一个新线程来完成繁重的工作并报告结果。 Swing提供了SwingWorker类,可以帮助你做你想做的事。
快速而肮脏的代码:
try{
InetAddress localhost = InetAddress.getLocalHost();
final byte[] ip = localhost.getAddress();
SwingWorker<ListModel, InetAddress> worker = new SwingWorker<ListModel, InetAddress>()
{
public ListModel doInBackground()
{
for(int i=1;i<254;i++){
ip[3]=(byte)i;
final InetAddress address = InetAddress.getByAddress(ip);
if(address.isReachable(1000)){
publish(address);
listModel1.addElement(address);
}
}
return listModel1;
}
public void process(List<InetAddress> addresses)
{
for(InetAddress address : addresses)
{
System.out.println(address + "-Machine is turned on and can be ping.");
Rectangle progressRec = jProgressBar1.getBounds();
progressRec.x = 0;
progressRec.y = 0;
jProgressBar1.setValue(i);
jProgressBar1.paintImmediately(progressRec);
}
}
public void done()
{
jList1.setModel(get());
}
};
worker.execute();
}catch(Exception e){
e.printStackTrace();
}
建议阅读:
答案 1 :(得分:2)
您无法在事件处理程序中进行任何实质性计算,因为在处理程序运行时,所有其他组件都无法访问,并且无法重新绘制屏幕。您必须创建一个新线程并在其中进行处理。
答案 2 :(得分:2)
将循环添加到Thread并在单击按钮后启动线程。目前按钮事件方法被阻止,循环完成。