Saturday, January 16, 2010

Animated cell renderer

This article will take as example list cell renderer but the same way can be applied to animate tree/table renderer.

Let’s start from where the last article end: the renderer is bigger when the cell is selected, why not animate the fact that the renderer size increase over time, to let the user know it’s actually the one that he selected that get bigger.

First we need a way to store the animation value for each cell:


Map<Integer, Float> mapAnimation = new HashMap<Integer, Float>();


The renderer will look up for the animation value:

public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, final boolean cellHasFocus) {

JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index,isSelected, cellHasFocus);

Float progress = mapAnimation.get(index);
if (progress == null) {
progress = 0f;
}
label.setFont(label.getFont().deriveFont(10 + 20 * progress));
label.setPreferredSize(new Dimension(50, (int) (15 + 35 * progress)));
return label;
}




A selection listener to start the animation:
list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(final ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
return;
}
final Timeline timeline = new Timeline();
timeline.setDuration(200);
timeline.addCallback(new TimelineCallback() {
/*…see below…*/
});
timeline.play();
}
});



The TimelineCallBack allow us to define what to do on each timeline pulse, it’s where the animation map will get populated.

new TimelineCallback() {
@Override
public void onTimelinePulse(float durationFraction,float TimelinePosition) {
// set the progress for the selected index
mapAnimation.put(list.getSelectedIndex(), durationFraction);
//set the progress for the last selected index
if (oldSelected[0] != -1) {
mapAnimation.put(oldSelected[0], 1 - durationFraction);
}
//compute the size for each cell with the new animation values
SwingUtilities.invokeLater(new Runnable(){
Override
public void run(){
JlistUtils.computeListSize(list);
}
});
}




And that’s it! You now have an animated renderer.




A bit more complex examples:













as always you can find the source code in the source code repository here

No comments:

Post a Comment