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 bu开发者_运维百科y 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?
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);
}
Using JFreeChart
or subclassing JProgressBar
seems like overkill, but overriding paintTrack()
in BasicSliderUI
may be effective. Here's an example.
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.
Following code does the job:
setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
Swap the background and foreground colors and the regress will look like a progress to the left.
I tried the accepted resolution above but it didn't solve my use case. I needed the progress bar to be VERTICAL with the progress from TOP to BOTTOM and show the value as a String in the bar, in the proper readable orientation. Rotating the bar would have worked if the string value didn't need to be shown. :-(
So, after much research I settled on the following.
Extend
javax.swing.plaf.basic.BasicProgressBarUI
in my own implementation and override the
protected void paintDeterminate(Graphics g, JComponent c)
method.
Keep everything the same as the parent except in the case of VERTICAL change this little snippet.
Original
g2.drawLine(barRectWidth/2 + b.left,
b.top + barRectHeight,
barRectWidth/2 + b.left,
b.top + barRectHeight - amountFull);
Modified
g2.drawLine(barRectWidth / 2 + b.left,
b.top,
barRectWidth / 2 + b.left,
b.top + amountFull);
This solved my use case precisely; progress from top to bottom and show the string value in a readable orientation. Maybe this post will help someone else or at least point them in a direction.
Regards, Daniel
精彩评论