1

Im using a JPanel with propertyChangeListener and want it to rerender itself based on whenever a particular variable model changes. My code for the same is as follows --

public class LabelMacroEditor extends JPanel implements PropertyChangeListener {

    private static final long serialVersionUID = 1L;
    private LabelMacroModel model;

    public LabelMacroEditor(LabelMacroModel bean) {

        this.model = bean;
        model.addPropertyChangeListener(this);
        setupComponents();
        validate();
        setVisible(true);
    }

    public void setupComponents()
    {

        Box allButtons =  Box.createVerticalBox();
        JScrollPane macroModelScroller =  new JScrollPane(allButtons);
        macroModelScroller.setPreferredSize(new Dimension(300, 200));
        for(MacroModel macroModel : model.getMacroModelList())
        {
            LabelMacroEditorEditableEntity macroEditorEntity =  new LabelMacroEditorEditableEntity(macroModel);
            Box entityBox =  Box.createHorizontalBox();
            entityBox.add(macroEditorEntity.getUpButton());
            entityBox.add(Box.createHorizontalStrut(15));
            entityBox.add(macroEditorEntity.getMacroDetailsButton());
            entityBox.add(Box.createHorizontalStrut(15));
            entityBox.add(macroEditorEntity.getDownButton());

            allButtons.add(entityBox);
        }
        add(macroModelScroller);
    }

    @Override
    public void propertyChange(PropertyChangeEvent arg0) {
        revalidate();
        repaint();
    }
}

When i use the debug mode in eclipse i can see that whenever there is a change to model it triggers off the call propertyChange and it also runs over revalidate and repaint but only the JPanel display remains the same. It does not seem to be rerendering itself. Anything fundamental that I'm missing here ?

EDIT :

An example snippet of a property im changing is as follows --

labelMacroModel.addMacroModel(addedMacroModel);

where labelMacroModel is of the type LabelMacroModel and addedMacroModel is of the type Macro

Now the relevant part of LabelMacroModel class that fires off the property change is as follows --

private List<MacroModel> macroModelList;// this is the list of all MacroModels
public void addMacroModel(MacroModel macroModel) {
        macroModelList.add(macroModel);

        pcs.fireIndexedPropertyChange("LabelMacroModel", macroModelList.size(), null, macroModel);
    }
ping
  • 1,229
  • 3
  • 21
  • 41
  • *"Anything fundamental that I'm missing here ?"* An SSCCE to get me interested? – Andrew Thompson Mar 18 '12 at 18:42
  • Can you give an example property that you change? – Perry Monschau Mar 18 '12 at 18:44
  • @PerryMonschau -- Ive edited to provide a code snippet of the property im changing. – ping Mar 18 '12 at 18:53
  • 1
    Rather than show snippets of code, what is your program supposed to be doing? What is the overall job of the program, and what is the specific job of this JPanel? You might be better off with a different approach, but we can only decide this if you give us more information. – Hovercraft Full Of Eels Mar 18 '12 at 20:22
  • @HovercraftFullOfEels I have posted my use case in another question now --http://stackoverflow.com/questions/9762747/java-swing-writing-a-ui-that-will-repaint-itself-based-on-changes-to-a-custom – ping Mar 18 '12 at 22:06
  • 1
    unrelated to the problem at hand: don't call setXXSize ever – kleopatra Mar 19 '12 at 10:28

2 Answers2

4

Its not clear how you are changing the components in the panel. If panel is not updated then repaint/revalidate will have no effect. I think you should not need revalidate/repaint to be called explicitly if you are not modifying the way components are laid out. JButton.setText should for example change the label of the button without need of calling repaint.

Ashwinee K Jha
  • 9,187
  • 2
  • 25
  • 19
2

To expand on the answer by AKJ above, I think you should be reconstructing your components on property change. So doing a remove all then readding is one way to do this. Once you get this working you could be more selective about pushing the model update into the GUI eg if a new entry has been added then just add a new component to reflect this. The remove all / readd is fine for a lot of cases though. HTH.

davidfrancis
  • 3,734
  • 2
  • 24
  • 21