开发者

Why loop disabled other button or swing components?

When I pressed a jbutton with a f开发者_StackOverflowor loop event inside it, other components became disabled.

Here is the code I have from my 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();
    }

Then after the loop has finished, the other components became enabled? How am I going to deal with it? Thanks in advance...

Edited codes: Suggested by no good at coding

    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();
    }


Presumably, by 'disabled' you mean they become unresponsive.

That's happening because you're performing very expensive/long-lived operations in the Event Dispatch Thread which handles all GUI related actions such as repainting components. When your code blocks this thread, Swing is unable to perform the usual operations quickly and the UI will become unresponsive to user actions and painting or drawing actions may also appear to lag/freeze.

You should spawn a new thread to do your heavy lifting and report the results. Swing provides the SwingWorker class that can help you do what you want.

Quick-and-dirty code:

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();
}

Suggested reading:

  • http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html
  • http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html
  • http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html


You can't do any substantial computing inside an event handler, because while your handler is running, all other components are inaccessible and the screen can't be repainted. You have to create a new thread and do the processing in that.


Add you loop to Thread and start the thread once button clicked. Currently button event method is blocked with loop to complete.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜