Starting off, let's list out the tasks ahead of us:
1. We need to do a small amount of re-factoring on
the carousel layout to allow us to sub-class it and
over-ride a couple of pieces of functionality.
2. We need a new component that will contain a
carousel, and a menu (I'm going to use a JList, it
does the job!)
3. The menu needs a custom cell renderer to make the
selected cell look pretty
The re-factoring was pretty minimal, but I did add a
couple of methods, just before I start that, I need
to mention one of the existing methods which needed
to be over-ridden:
public void setFrontMostComponent(Component
component)
Previously this would spin the
specified component to the FRONT of the carousel.
This time, I wanted it to be on the right of the
carousel, so the new method (in the rather
imaginatively named OffsetCarouselLayout class). This
function just determines the target angle
differently.
protected boolean shouldHide(Component comp,
double angle)
One of the problems with the
over-riding of the above function is that you can
have component in front of the currently focused one.
This new function is used to determine if a component
should be hidden (based on where it is on the
carousel). It lets me stop things appearing in front
of the current component.
The next two are pretty obvious, they let me
manipulate the center of the carousel (in the
component) and the radius of the carousel (I didn't
want it quite as squashed).
That's it, not bad, gotta-love OO programming!
So, let's summarize what we have; a single component
with a JCarousel component (with a new layout
manager), and a JList in it, pretty straight
forward....
As you can imagine, Java makes most of this pretty
easy. But there are a couple more steps that you'll
find in the source code.
It turns out, JLists don't like wrapping the selected
object when the user is using the keys to cycle
through (it gets stuck at the top or the bottom). So
you'll see in the code of the Carousel Menu that it
has a keyboard listener to move the cursor to the top
or the bottom when it hits one of the ends. Also we
need to update which component is at the "front" of
the carousel based on which item is selected, and a
simple implementation of the list selection listener
achieves that.
And of course, we need a nice border around the
selected item. I've cheated a little and created a
simple border called "ImageBorder" which takes a
bounded image (like the one shown below) and a set of
insets, and slices and dices it to make it
resize-able.
I've added the code for this below, and of course,
once I'm back from my trip I'll update my project
file so that you can all download the source. And
rather wonderfully, that's it. Once again, Java can
really deliver on a modern UI and I think you'll
agree it makes my blog examples a little more usable!
![]()