tags:

views:

66

answers:

3

My app needs to display a graphical representation of a value ranging from -1 to 1. Negative values should be in one color, with positive values in another. Zero is in the center and shows nothing. (If it helps, the particular use here is to display the relative weight of buy and sell orders in a financial application.)

I would ideally like to use a pair of JProgressBars for this, however the Swing control starts (at its minimum) at the left. The standard control only supports two orientations, left-right or bottom-top. Passing in negative values doesn't help. My question is, what is the quickest way to achieve this effect?

Subclassing JProgressBar would involve re-implementing it almost entirely. Using a JFreeChart bar chart seems like a great deal of code (and effort) for a relatively trivial task. I could perhaps make a small, square-celled JTable and fill it in, but again that's a lot of code. What would you suggest?

Many thanks,

Tim

A: 

I had a look at JFreeChart the other day and for what you want to do it looks like complete overkill.

As this seems as if it would be fairly easy to draw procedurally, I'd just make a class extending JComponent, override the paint method to draw a rect in it, and add it as a custom widget.

DrDipshit
Completely agree, I've used JFreeChart before and it is a pretty big library for doing something as simple as your doing.
Albinoswordfish
OK thanks doc. I will go for that approach; quicker than anything else I've thought of.I am pretty comfortable with JFreeChart, which is likely why I reached for it instead of thinking wider. (I'm also very comfortable with a mallet, which is why nobody asks me to do dishes anymore.)
Tim Kemp
lol, yeah I know what its like.
DrDipshit
+1  A: 

Using JFreeChart or subclassing JProgressBar seems like overkill, but overriding paintTrack() in BasicSliderUI may be effective. Here's an example.

trashgod
Thanks! I will look into that as well. It looks promising.
Tim Kemp
+2  A: 

Umm, maybe this won't work at all, but how about making a sub-class of JProgressBar and overriding paintComponent() to something like this:

@Override
protected void paintComponent(Graphics g) {
  Graphics2D g2d = (Graphics2D) g;
  g2d.rotate(Math.PI);
  super.paintComponent(g2d);
}

I'd test it if I was more lucid and awake.

Edit: While rotating it might work too, I found it easier to scale it and then translate, as follows:

@Override
protected void paintComponent(Graphics g) {
  Graphics2D g2d = (Graphics2D) g;
  g2d.scale(-1, 1); //Flips over y-axis
  g2d.translate(-getWidth(), 0); //Moves back to old position.
  super.paintComponent(g2d);
}
Tikhon Jelvis
I think `JProgressBar` has an `orientation` field, too.
Catalina Island
@Catalina Island: that's just for horizontal or vertical, unfortunately.
Tim Kemp
@Tikhon Jelvis, nice idea but didn't draw at all. I will report back if I get it working.
Tim Kemp
Umm, I think you might also need to translate it. I'll play around a bit with it to see what I can do.
Tikhon Jelvis
Flipping and then translating worked for me, so I've updated my answer.
Tikhon Jelvis
Perfect, and easy. Thanks! Will use this next time. I have accepted this answer instead as it's exactly right. I cheated horribly in the code I ended up using (for a quick demo) - by inverting fg/bg colors and setting the displayed value to 100-value for the 'sell' side... Ghastly hack.
Tim Kemp