程序在启动子表单时没有响应

时间:2014-02-01 22:53:57

标签: java swing concurrency

这是一个启动新窗口(子窗体)的应用程序。在提交此子表单时,应该发生的是返回的数据得到处理并更新父表单。但是,启动子表单时程序不响应。有人可以解释为什么会发生这种情况,我该如何解决?

public class FormCondition 
{
    private JLabel nameLabel;
    private JTextField name;
    private JButton create;
    private Lock lock;
    private Condition cond;
    private String str;
    public FormCondition()
    {   
        lock = new ReentrantLock();
        cond = lock.newCondition();
        create = new JButton("Create");
        nameLabel = new JLabel("Name");
        name = new JTextField();
        name.setEditable(false);
        create.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                if (e.getSource() == create)
                {   
                    try
                    {
                        lock.lock();
                        try
                        {
                            Runnable r = new Runnable()
                            {
                                @Override
                                public void run() 
                                {
                                    System.out.println("Starting a new Thread");
                                    new newForm();
                                }
                            };

                            new Thread(r).start();
                            System.out.println("about to wait");
                            cond.await();
                            name.setText(str);
                        }
                        finally
                        {
                            lock.unlock();
                        }
                    }
                    catch (InterruptedException e1)
                    {
                        // empty
                    }
                }
            }
        });
        JFrame frame = new JFrame("Main form");
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(0, 2));
        panel.add(nameLabel);
        panel.add(name);
        panel.add(create);
        frame.add(panel);
        frame.setLocationRelativeTo(null);
        frame.setSize(200, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    }

    public void setName(String name)
    {
        str = name;
        System.out.println("Name received is: " + str);
    }

    class newForm implements ActionListener
    {
        private JLabel nameLabel;
        private JTextField name;
        private JButton go;
        public newForm()
        {
            nameLabel = new JLabel("Name");
            name = new JTextField();
            go = new JButton("Go");
            JFrame frame=new JFrame("Second form");
            JPanel panel=new JPanel();
            panel.setLayout(new GridLayout(0,2));
            panel.add(nameLabel);
            panel.add(name);
            panel.add(go);
            frame.add(panel);
            frame.setLocationRelativeTo(null);
            frame.setSize(200,200);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        public void actionPerformed(ActionEvent e) 
        {
            if (e.getSource() == go)
            {
                lock.lock();
                try
                {
                    String string = name.getText();
                    System.out.println("Name entered is: " + str);
                    setName(str);
                    cond.signal();
                    System.out.println("Signalled");
                }
                finally
                {
                    lock.unlock();
                }

            }
        }
    }

    public static void main(String[] str)
    {
        new FormCondition();    
    }
}

2 个答案:

答案 0 :(得分:1)

你不应该在UI线程上调用cond.await();之类的东西(在事件调度线程上)。这就是你的UI挂起的原因。此外,即使这不相关,也不要像捕捉InterruptedException时那样使用空的catch块。

答案 1 :(得分:1)

正如Peter所说,当等待部分从UI线程中移除并移动到BlockingMethod()时,它会起作用。此外,应该在该方法中重新获取锁,并且应该在完成处理时释放。

 public class FormCondition 
    {
        private JLabel nameLabel;
        private JTextField name;
        private JButton create;
        private ReentrantLock lock;
        private Condition cond;
        private String str;
        public FormCondition()
    {   
        lock=new ReentrantLock();
        cond=lock.newCondition();
        create=new JButton("Create");
        nameLabel=new JLabel("Name");
        name=new JTextField();
        name.setEditable(false);
        create.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e) {
                if(e.getSource()==create)
                {   
                    try
                    {
                        lock.lock();
                        System.out.println("Lock acquired");
                        System.out.println("Starting a new Thread");
                        System.out.println("Sleep for two minutes");
                        Thread.sleep(2000);
                        System.out.println("Awake now");
                        new newForm();
                        lock.unlock();
                        blockingMethod();




                    }
                    catch(InterruptedException e1)
                    {
                    e1.getMessage() ;

                    }


                }

            }});
        JFrame frame=new JFrame("Main form");
        JPanel panel=new JPanel();
        panel.setLayout(new GridLayout(0,2));
        panel.add(nameLabel);
        panel.add(name);
        panel.add(create);
        frame.add(panel);
        frame.setLocationRelativeTo(null);
        frame.setSize(400,200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    }



    public void blockingMethod()
    {
        Runnable r2=new Runnable(){

            @Override
            public void run() 
            {

                try 
                {   lock.lock(); 
                    System.out.println("about to wait");
                    cond.await();//lock released temporarily
                    System.out.println("waiting done...");
                    //invoke setName after reaquiring lock
                    lock.unlock();
                }
                catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }


            }};
            try
            {
                    lock.lock();
                    System.out.println("Still has the Lock ");
                    new Thread(r2).start();
                    lock.unlock();


            }
            catch(Exception e1)
            {
            e1.getMessage() ;

            }

    }

    public void setName(String name)
    {

    str=name;
    this.name.setText(str);
    System.out.println("Name received is: "+str);
    }

    class newForm  implements ActionListener
    {
    private JLabel nameLabel;
    private JTextField name;
    private JButton go;
    public newForm()
    {
    nameLabel=new JLabel("Name");
    name=new JTextField();
    go=new JButton("Go");
    go.addActionListener(this);
    JFrame frame=new JFrame("Second form");
    JPanel panel=new JPanel();
    panel.setLayout(new GridLayout(0,2));
    panel.add(nameLabel);
    panel.add(name);
    panel.add(go);
    frame.add(panel);
    frame.setLocationRelativeTo(null);
    frame.setSize(300,200);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


    }
    public void actionPerformed(ActionEvent e) 
    {

        if(e.getSource()==go)
        {
            System.out.println("waiting for the lock");
             lock.lock();
             System.out.println("Lock acquired");

                 try
                 {

                  String string= name.getText();
                  System.out.println("Name entered is: "+string);
                  setName(string);
                  cond.signalAll();
                  System.out.println("Signalled");
                 }

                 finally
                 {
                     lock.unlock();
                     System.out.println("Lock released");

                 }




        }

    }
    }

    public static void main(String[] str)
    {
    new FormCondition();    
    }
    }