views:

76

answers:

2

I'm currently making a java swing GUI with the Netbeans GUI builder. I have a bunch of panels that are being replaced on my main JFrame as the user navigates the GUI and a controller class is taking care of this. At one step, however, there is a panel (FilterDefinitionPanel) that contains a combo box as well as a blank inner panel (QueryHelperPanel).

What I'd like to do is to swap out this inner panel with another I've created (StringQueryDefinitionPanel) depending on what the user selects in the combo box. So right now under my combo box's ComboBoxItemStateChanged event handler I have my controller class run this method:

 public void selectFilterAttribute(Object item) {
    /**
     * Determine panel to create based on item selection. Currently always returns the same
     * StringQueryDefinitionPanel.
     */
    JPanel panel = this.getRequiredQueryHelperPanel(item);
    /**
     * Swap the placeholder QueryHelperPanel with the required one.
     */
    ((FilterDefinitionPanel) this.mainFrame.getMainPanel()).setQueryHelperPanel(panel);
    /**
     * Not sure if all of these are needed :\
     */
    mainFrame.validate();
    mainFrame.repaint();
    mainFrame.pack();
}

This is what's happening in the FilterDefinitionPanel's setQueryHelper method:

public void setQueryHelperPanel(JPanel panel){
    this.remove(queryHelperPanel);
    this.queryHelperPanel=panel;
    this.queryHelperPanel.repaint();
    /**
    * Again, not sure which refresh methods are needed...
    */
    this.validate();
    this.repaint(); 
}

Currently I think this is replacing my inner placeholder panel with ...something... , but the replacement seems to contain nothing. I don't know if it matters but both the placeholder and the replacement panel are the same size. I'm kind of a swing nub so any tips would be really appreciated.

+6  A: 

The setQueryHelperPanel() method does not work because it removes the existing panel from the collection of children of this via the remove() method, but then does not use add() to add the new panel - assigning it to the instance variable does not cause it to become a child.

However, a much cleaner solution for your problem would be to use a CardLayout.

Michael Borgwardt
A: 

Thanks for the reply.

I looked into CardLayout previously but I'm trying to avoid it as from what I understand it loads all the panels in memory and then allows you to swap them out. I'd like to keep full control over when I dynamically display the panels.

Forgetting the remove was a dumb mistake on my part. I actually had that earlier but it still wasn't working. This is the current swap method:

public void setQueryHelperPanel(JPanel panel){
    this.remove(queryHelperPanel);
    this.queryHelperPanel=panel;
    this.add(queryHelperPanel);
    this.queryHelperPanel.repaint();
    this.validate();
    this.repaint();
}

I understand that setting the instance variable doesn't actually add it as a child, but my idea was that the variable would be used to remember what panel to remove or add.

Don
Do you call this method in Event Dispatch Thread? If not, it may be the reason of your problem.
Taisin
@Taisin: Seriously, CardLayout is the correct way to do this. Your reasons for avoiding this do not make sense.
Michael Borgwardt
@Michael Borgwardt: I'm sorry, but MY reasons for avoiding??? I'm not the author of the question. Personally, I agree with you, I would use Card Layout in this situation, however the author's reasons are his own, and I'm just pointing out the possible reason why the code above doesn't work (and it should, even if the solution is far from optimal).
Taisin
@Taisin: sorry for the mix-up - and you're right, the code should theoretically work.
Michael Borgwardt