1

Here is an application which launches a new window (a sub-form). On submitting this sub-form, what should happen is that the returned data gets processed and the parent form is updated. However, the program does not respond when the sub-form is launched. Could someone explain why this occurs and how should I solve it?

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();    
    }
}
Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Sameer Sarmah
  • 1,052
  • 4
  • 15
  • 33
  • Looks like someone needs to read up on the [Swing threading model](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/). You are only allowed to create and manipulate Swing classes from the EDT. This code violates that. – Boris the Spider Feb 01 '14 at 22:57
  • 1
    See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/a/9554657/418556) IT seems you are trying to get the behavior of a `JDialog`, though I'd suggest to make it modal to actually *block* the user access to the main form until the dialog is dismissed. – Andrew Thompson Feb 01 '14 at 23:24

2 Answers2

1

You should not be calling things like cond.await(); on the UI thread (on the event dispatching thread). This is why your UI hangs. Also, even though this is not related, don't use empty catch blocks as you did there when catching the InterruptedException.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
1

As answered by Peter when the waiting part is removed from the UI thread and moved to BlockingMethod() it works.Also the lock should be reacquired in that method and should be released when done processing.

 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();    
    }
    }
Sameer Sarmah
  • 1,052
  • 4
  • 15
  • 33