为什么循环禁用其他按钮或摆动组件?

时间:2011-04-15 02:11:41

标签: java netbeans

当我在其中按下带有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();
    }

3 个答案:

答案 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并在单击按钮后启动线程。目前按钮事件方法被阻止,循环完成。