我正在创建一个程序,用于请求用户一个月的销售,并执行销售到条形图。程序运行并正确生成条形;但是文本没有正确执行。我正在尝试将标题“月销售额”作为图表标题,使用销售伙伴名称标记条形图,并在图表左侧标记条形图的值。任何建议都会有所帮助。它在整个图表中反复产生“月度销售”。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class BarGraph extends JPanel
{
//set variables for graph
JLabel jLabel1, jLabel2, jLabel3, jLabel4, jLabel5;
private Map<Color, Integer> bars =
new LinkedHashMap <>();
//execute bars and color
public void addBar(Color color, int value)
{
bars.put(color, value);
repaint();
}
//create paint components of chaart
public void paintComponent(Graphics g)
{
Dimension d = getSize();
int clientWidth = d.width;
int clientHeight = d.height;
int max = Integer.MIN_VALUE;
for (Integer value : bars.values())
{
max = Math.max(max, value);
}
jLabel1 = new JLabel("Sales For Month", JLabel.CENTER);
// We can position of the text, relative to the icon:
jLabel1.setVerticalTextPosition(JLabel.BOTTOM);
jLabel2 = new JLabel("PAM");
jLabel3 = new JLabel("Leo");
jLabel4 = new JLabel("Kim");
jLabel5 = new JLabel("BOB"); // Label of Icon Only
// Add labels to the Panel
add(jLabel1);
//paint bar
int width = (getWidth() / bars.size()) - 2;
int x = 1;
for (Color color : bars.keySet())
{
int value = bars.get(color);
int height = (int)
((getHeight() -5) * ((double)value /max));
g.setColor(color);
g.fillRect(x, getHeight() - height, width, height);
g.setColor(Color.black);
g.drawRect(x, getHeight() - height, width, height);
x += (width + 2);
}
}
//set bar size
public Dimension getPreferredSize()
{
return new Dimension(bars.size() * 10 + 2, 50);
}
//create main to generate charte
public static void main(String[] args)
{
JFrame frame = new JFrame("Friendly Hal's Auto");
BarGraph graph = new BarGraph();
//set frame size
frame.setSize(350, 300);
//create variable for user input
int carsSold1;
int carsSold2;
int carsSold3;
int carsSold4;
//request user input
Scanner input = new Scanner(System.in);
System.out.println("How many cars did Pam sell for the month?");
carsSold1 = input.nextInt();
System.out.println("How many cars did Leo sell for the month?");
carsSold2 = input.nextInt();
System.out.println("How many cars did Kim sell for the month?");
carsSold3 = input.nextInt();
System.out.println("How many cars did Bob sell for the month?");
carsSold4 = input.nextInt();
//color bar to user choice
graph.addBar (Color.red, carsSold1);
graph.addBar (Color.green, carsSold2);
graph.addBar(Color.blue, carsSold3);
graph.addBar(Color.yellow, carsSold4);
frame.getContentPane().add(graph);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
答案 0 :(得分:1)
你的问题是,你已经打破了油漆链......
public void paintComponent(Graphics g)
{
// Your problem is right here...
Dimension d = getSize();
paintComponent
的其中一项工作是清除Graphics
上下文(组件背景颜色)准备好绘画......
首次调用super.paintComponent(g);
方法时添加paintComponent
Graphics
上下文是共享资源,在给定绘制周期内绘制的所有组件将共享相同的Graphics
上下文,在某些系统上,它对于所有绘制周期都是相同的,所以你在使用之前需要确保它已被清除......
有关详细信息,请参阅Painting in AWT and Swing和Performing Custom Painting。
<强>更新强>
正如@HovercraftFullOfEels指出的那样,您正在paintComponent
内创建UI元素,绘画应该绘制UI的当前状态,并且不应对其进行任何修改。当重绘经理认为应该完成时,绘画就完成了,所以你的paintComponent
可能被调用很多次,这取决于你在做什么。
从paintComponent
中修改UI的状态可能会设置无限循环的重绘请求,最终会占用您的CPU周期并使您的PC无法使用...
也可能想要读取Initial Threads并确保仅在事件调度线程的上下文中创建和修改UI。
你也不应该混合使用基于UI和控制台的方法,它们不能很好地混合在一起......