从右到左(反向)JProgressBar

3
我的应用程序需要显示一个值的图形表示,范围从-1到1。负值应该是一种颜色,正值应该是另一种颜色。零位于中心,不显示任何内容。(如果有帮助的话,在金融应用程序中,特定的使用是显示买入和卖出订单的相对权重。)
我想使用一对JProgressBars来实现这个功能,但是Swing控件从左侧开始(最小)。标准控件仅支持两个方向,从左到右或从底部到顶部。传入负值也没有帮助。我的问题是,最快实现此效果的方法是什么?
子类化JProgressBar将涉及重新实现它的大部分内容。使用JFreeChart条形图似乎需要大量的代码(和工作),对于相对较小的任务而言,这太多了。我可以创建一个小的、方形的JTable并填充它,但这又是很多代码。你有什么建议?

子类化为什么需要重新实现所有内容?为什么不能子类化JProgressBar并覆盖适当的方法? - Nate W.
6个回答

4

嗯,也许这根本行不通,但是如何创建一个JProgressBar的子类并重写paintComponent()方法,使其像这样:

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

如果我更加清醒和有精神,我会测试它。

编辑: 虽然旋转也可能有效,但我发现缩放后再平移更容易实现,具体操作如下:

@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);
}

我认为 JProgressBar 也有一个 orientation 字段。 - Catalina Island
@卡特琳娜岛:很抱歉,这只适用于水平或垂直。 - Tim
@Tikhon Jelvis,好主意,但是没有画出来。如果我成功了,我会回报的。 - Tim
嗯,我觉得你可能也需要翻译一下。我会试着玩一下看看我能做什么。 - Tikhon Jelvis
翻转后再翻译对我起了作用,因此我更新了我的答案。 - Tikhon Jelvis
完美而且简单。谢谢!下次会用这个。我已经接受了这个答案,因为它完全正确。在我最终使用的代码中(为了快速演示),我作弊得很厉害——通过反转前景/背景颜色并将显示值设置为100-值来实现“卖出”方面...可怕的hack。 - Tim

2

使用JFreeChart或子类化JProgressBar似乎有些过度,但在BasicSliderUI中覆盖paintTrack()可能会更有效。这里有一个例子


谢谢!我也会研究一下。看起来很有前途。 - Tim

1
以下代码可以完成任务:
setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

1

前几天我看了一下JFreeChart,对于你想做的事情来说,它看起来完全是杀鸡焉用牛刀。

既然这似乎可以很容易地通过程序绘制,我会创建一个扩展JComponent的类,覆盖paint方法以在其中绘制一个矩形,并将其添加为自定义小部件。


完全同意,我以前使用过JFreeChart,它对于做像你这样简单的事情来说是一个相当大的库。 - Albinoswordfish
好的,谢谢医生。我会采用这种方法;比我想到的任何其他方法都要快。我对JFreeChart非常熟悉,这可能是为什么我选择它而不是考虑更广泛的原因。(我也非常熟练地使用木槌,这就是为什么再也没有人让我洗碗了。) - Tim

0

我尝试了上面接受的解决方案,但它没有解决我的用例。我需要进度条是垂直的,从顶部到底部显示进度,并在条形图中以适当的可读方向显示值作为字符串。如果不需要显示字符串值,旋转条形图将起作用。 :-(

因此,在进行了大量研究后,我选择了以下方法。

扩展

javax.swing.plaf.basic.BasicProgressBarUI

在我的自定义实现中并覆盖

protected void paintDeterminate(Graphics g, JComponent c)

方法。

除了在垂直方向改变这个小片段之外,保持和父元素一样的所有内容。

原始的。

g2.drawLine(barRectWidth/2 + b.left,
            b.top + barRectHeight,
            barRectWidth/2 + b.left,
            b.top + barRectHeight - amountFull);

已修改

    g2.drawLine(barRectWidth / 2 + b.left,
                b.top,
                barRectWidth / 2 + b.left,
                b.top + amountFull);

这完美解决了我的使用情况;从上到下显示可读的字符串值的进展。也许这篇帖子会对其他人有帮助,或者至少指引他们朝一个方向前进。

祝好, Daniel


0

交换背景和前景颜色,回归将看起来像向左的进度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接