题
我工作的一个简单的小秋千组成部分,我撕裂了我的头发试图找出为什么我的绘制方法是行不通的。
此组件背后的想法是,它是一个小的JPanel带有标签。背景(标签后面)被认为是白色的,与指示两个测量值的比率的左手侧的彩色矩形:“实际的”和“预期”
如果你有一堆这些部件垂直对准的,他们会形成一个条形图,水平杆组成。
这样的事情应该是超简单。
总之,这里的代码:
package com.mycompany.view;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class BarGraphPanel extends JPanel {
private static final Color BACKGROUND = Color.WHITE;
private static final Color FOREGROUND = Color.BLACK;
private static final Color BORDER_COLOR = new Color(229, 172, 0);
private static final Color BAR_GRAPH_COLOR = new Color(255, 255, 165);
private int actual = 0;
private int expected = 1;
private JLabel label;
public BarGraphPanel() {
super();
label = new JLabel();
label.setOpaque(false);
label.setForeground(FOREGROUND);
super.add(label);
super.setOpaque(true);
}
public void setActualAndExpected(int actual, int expected) {
this.actual = actual;
this.expected = expected;
}
@Override
public void paint(Graphics g) {
double proportion = (expected == 0) ? 0 : ((double) actual) / expected;
Rectangle bounds = super.getBounds();
g.setColor(BACKGROUND);
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
g.setColor(BAR_GRAPH_COLOR);
g.fillRect(bounds.x, bounds.y, (int) (bounds.width * proportion), bounds.height);
g.setColor(BORDER_COLOR);
g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height);
label.setText(String.format("%s of %s (%.1f%%)", actual, expected, proportion * 100));
super.paint(g);
g.dispose();
}
}
和这里的简单的测试工具:
package com.mycompany.view;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.UIManager;
public class MyFrame extends JFrame {
public MyFrame() {
super();
super.setLayout(new GridLayout(3, 1));
super.setPreferredSize(new Dimension(300, 200));
BarGraphPanel a = new BarGraphPanel();
BarGraphPanel b = new BarGraphPanel();
BarGraphPanel c = new BarGraphPanel();
a.setActualAndExpected(75, 100);
b.setActualAndExpected(85, 200);
c.setActualAndExpected(20, 300);
super.add(a);
super.add(b);
super.add(c);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Throwable t) { }
MyFrame frame = new MyFrame();
frame.pack();
frame.setVisible(true);
}
}
测试工具创建一个简单的框架,然后添加三个这些控件。
在标签的所有正确地呈现,这表明,我认为涂料()方法被实际调用,但矩形不被绘制图形对象。
我在做什么错了?
和为什么Swing编程吸这么多?
这是我的最终代码。谢谢大家,你们的帮助!
public void paintComponent(Graphics g) {
double proportion = (expected == 0) ? 0 : ((double) actual) / expected;
Rectangle bounds = super.getBounds();
g.setColor(BACKGROUND);
g.fillRect(0, 0, bounds.width, bounds.height);
g.setColor(BAR_GRAPH_COLOR);
g.fillRect(0, 0, (int) (bounds.width * proportion), bounds.height);
g.setColor(BORDER_COLOR);
g.drawRect(0, 0, bounds.width - 1, bounds.height - 1);
FontMetrics metrics = g.getFontMetrics();
String label = String.format("%s of %s (%.1f%%)", actual, expected, proportion * 100);
Rectangle2D textBounds = metrics.getStringBounds(label, g);
g.setColor(FOREGROUND);
g.drawString(label, 5, (int) ((bounds.height + textBounds.getHeight()) / 2));
}
解决方案
我想你已经几乎回答了你自己的问题的意见,与大卫的回答一起。改变paint(Graphics g)
到paintComponent(Graphics g)
和除去方法的最后两行,你应该罚款。
修改强>奇怪的是,这仅适用于三个的第一杆。正在进行更多的测试...
顺便说一句,你在边境绘图代码的差一错误。它应该是:
g.setColor(BORDER_COLOR);
g.drawRect(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1);
<强> EDIT2:确定,也可以得到。完整paintComponent
方法应该是如下:
@Override
public void paintComponent(Graphics g) {
double proportion = (expected == 0) ? 0 : ((double) actual) / expected;
Rectangle bounds = super.getBounds();
g.setColor(BACKGROUND);
g.fillRect(0, 0, bounds.width, bounds.height);
g.setColor(BAR_GRAPH_COLOR);
g.fillRect(0, 0, (int) (bounds.width * proportion), bounds.height);
g.setColor(BORDER_COLOR);
g.drawRect(0, 0, bounds.width-1, bounds.height-1);
label.setText(String.format("%s of %s (%.1f%%)", actual, expected, proportion * 100));
}
请注意给予g.fillRect()
和g.drawRect()
的坐标是相对于该组件,因此它们必须在(0,0)开始。
不,我不能帮你与你的最后一个问题,但我觉得你的痛苦。 :)
其他提示
在您的JPanel,你叫super.setOpaque(真)。 JPanel的是要在当你调用super.paint(背景完全填充),并覆盖您的外接矩形框。
不知道这是你的问题的根源,但在Swing你应该重写paintComponent(Graphics2D)
,而不是...
如果有的话,我想你应该打电话super.paint(G);在你的方法的顶部,而不是在最底层。这是可能超是在你的东西上绘制。