Dekel Viner
Dekel Viner

Reputation: 33

contentpane.removeAll does not remove JPanel

I have a JPanel with a start button when that button is pressed it calls through the mainFrame the start() function in the controller

public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    if (e.getSource().equals(start)) {
        System.out.println("hi");
        try {
            f.c.start();
        } catch (KludgeException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

    }
}

the start() function calls the askQuesions() function which loops over questions creates a question panel for them and stores the answers.

public void start() throws KludgeException{
    System.out.println("start");
    askQuestions();
    ConductInference();
}

 public void askQuestions() throws KludgeException {
    QuestionsPanel qp = new QuestionsPanel(main);
    for(data.containers.Question q : kludge.getQuestions()){
        qp.addQuestion(q.getQuestion(), q.getType());
        main.setPanel(qp);
        synchronized(this){
            while(!next){
                try {
                    wait();
                    kludge.setSystemValue(q.getValueName(), v);
                    //System.out.println("waitOver");
                }   catch (InterruptedException e) {}
            }
        }
        next = false;
        //System.out.println("next question");
    }
    System.out.println("questions over;");
}

this is a function in the mainFrame which is a JFrame it set the necessary panel.

public void setPanel(JPanel p){
    main.getContentPane().removeAll();
    main.getContentPane().add(p);
    main.validate();
    System.out.println("all removed, added and validated");
}

My problem is this... the program gets stuck on the startPanel when the stat button is pressed it freezes. If i skip the whole startPanel and tell it to go straight to the questions it works fine. but still i dont want it to go straight to the questions. For some reason it switches between the question panels fine but not between the startPanel and questionPanels..

Upvotes: 1

Views: 321

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285460

You've got a concurrency issue and are calling long-running code on the Swing event thread, an issue that will prevent this thread from doing its important jobs such as painting the GUI and interacting with the user. The solution is to do the long-running code in a background thread such as provided by a SwingWorker. That and read up on Swing concurrency: Lesson: Concurrency in Swing


OK, I'm now sure that my original recommendation -- to use a background thread -- is wrong, that instead you've over-complicated your code with the while loop, the synchronized block and the wait. Yes these are blocking the event thread, and yes, this is hamstringing your application, making it freeze and become totally unresponsive, but the solution is not to use a background thread but instead you will want to get rid of the while (true) loop, the synchronized block and the wait() call and in their place use event listeners and call back methods. The exact wiring of this will depend on code that we're not yet privy to, but that is the solution to this problem. For instance, the question panel could notify a control class that a question has been answered, to change the state of the model so that it moves on to the next question. The model then changes, and this can notify the view that it must update itself and now display this next question.

Side notes:

  • you're better off using a CardLayout to swap views then to directly swap them. The tutorial can be found here: CardLayout tutorial.

  • And regarding: main.setPanel(qp);
    You appear to be re-adding the QuestionPanel to the main within the for loop. If so, you only need to and only should add it once.

Upvotes: 1

Related Questions