【问题标题】:Attempting to label bars in chart, but produces text multiple times尝试在图表中标记条形图,但多次生成文本
【发布时间】:2014-11-21 02:52:16
【问题描述】:

我正在创建一个程序,请求用户一个月的销售额,并执行销售到条形图。程序运行并正确生成条形图;但是文本没有正确执行。我试图将标题“每月销售”作为图表的标题,用销售助理名称标记条形,并在图表左侧标记条形的值。任何建议都会有所帮助。它在整个图表中反复产生“每月销售额”。

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


  }

【问题讨论】:

  • 您不会在paintComponent 方法中创建想要的组件。这有点疯狂,因为您无法控制何时或是否调用该方法,并且您正在减慢必须非常快的方法。只在里面画画,其他什么都没有。

标签: java swing bar-chart


【解决方案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 和控制台的方法,它们不能很好地混合在一起......

【讨论】:

  • 他还在该方法中创建和放置 JLabels。
  • 我是否只为标签创建新方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 2019-02-06
  • 1970-01-01
  • 2021-11-13
相关资源
最近更新 更多