2013-03-04 104 views
1

问题是,条形图下的文本与条形图中的条不对齐。我如何使它们正确对齐?需要帮助修复GUI

为了让探测器闭嘴,我还可以补充些什么细节? :)

import java.awt.*; 
import javax.swing.*; 
import java.awt.event.*; 

public class SimpleBarChart extends JPanel { 

    private double[] value; 
    private String[] languages; 
    private String title; 
    private int gapBetweenBars = 40;//MODIFICATION - NOT A PART OF ORIGINAL CODE 

    public SimpleBarChart(double[] val, String[] lang, String t) { 
     languages = lang; 
     value = val; 
     title = t; 
    } 

    public void paintComponent(Graphics graphics) { 
     super.paintComponent(graphics); 
     if (value == null || value.length == 0) { 
      return; 
     } 
     double minValue = 0; 
     double maxValue = 0; 
     for (int i = 0; i < value.length; i++) { 
      if (minValue > value[i]) { 
       minValue = value[i]; 
      } 
      if (maxValue < value[i]) { 
       maxValue = value[i]; 
      } 
     } 
     Dimension dim = getSize(); 
     int clientWidth = dim.width; 
     int clientHeight = dim.height; 
     int barWidth = clientWidth/value.length; 

     barWidth = barWidth/3;//MODIFICATION - NOT A PART OF ORIGINAL CODE 

     Font titleFont = new Font("Book Antiqua", Font.BOLD, 15); 
     FontMetrics titleFontMetrics = graphics.getFontMetrics(titleFont); 
     Font labelFont = new Font("Book Antiqua", Font.PLAIN, 10); 
     FontMetrics labelFontMetrics = graphics.getFontMetrics(labelFont); 
     int titleWidth = titleFontMetrics.stringWidth(title); 
     int q = titleFontMetrics.getAscent(); 
     int p = (clientWidth - titleWidth)/2; 
     graphics.setFont(titleFont); 
     graphics.drawString(title, p, q); 
     int top = titleFontMetrics.getHeight(); 
     int bottom = labelFontMetrics.getHeight(); 

     if (maxValue == minValue) { 
      return; 
     } 

     double scale = (clientHeight - top - bottom)/(maxValue - minValue); 
     q = clientHeight - labelFontMetrics.getDescent(); 
     graphics.setFont(labelFont); 

     for (int j = 0; j < value.length; j++) { 
      int valueP = j * (barWidth + gapBetweenBars) + 1; //MODIFICATION - NOT A PART OF ORIGINAL CODE 
      int valueQ = top; 
      int height = (int) (value[j] * scale); 
      if (value[j] >= 0) { 
       valueQ += (int) ((maxValue - value[j]) * scale); 
      } else { 
       valueQ += (int) (maxValue * scale); 
       height = -height; 
      } 
      graphics.setColor(Color.blue); 
      graphics.fillRect(valueP, valueQ, barWidth - 2, height); 
      graphics.setColor(Color.black); 
      graphics.drawRect(valueP, valueQ, barWidth - 2, height); 
      int labelWidth = labelFontMetrics.stringWidth(languages[j]); 
      p = j * barWidth + (barWidth - labelWidth)/2; 
      graphics.drawString(languages[j], p, q); 
     } 
    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame(); 
     frame.setSize(500, 500); 
     double[] value = new double[5]; 
     String[] languages = new String[5]; 
     value[0] = 1; 
     languages[0] = "Visual Basic"; 

     value[1] = 2; 
     languages[1] = "PHP"; 

     value[2] = 3; 
     languages[2] = "C++"; 

     value[3] = 4; 
     languages[3] = "C"; 

     value[4] = 5; 
     languages[4] = "Java"; 

     frame.getContentPane().add(new SimpleBarChart(value, languages, "Programming Languages")); 

     WindowListener winListener = new WindowAdapter() { 
      public void windowClosing(WindowEvent event) { 
       System.exit(0); 
      } 
     }; 
     frame.addWindowListener(winListener); 
     frame.setVisible(true); 
    } 

    public void setGapBetweenBars(int gapBetweenBars) { 

     this.gapBetweenBars = gapBetweenBars; 
    } 

    public int getGapBetweenBars() { 

     return this.gapBetweenBars; 
    } 
} 
+0

欢迎来到stackoverflow。您最近在您描述问题时发布了一些问题,然后通过了一大段代码。你应该尝试发布可能也会帮助其他人来到这里的问题。像这样的问题太局部化了。在提出问题以使其更有帮助之前,您应该尝试缩小问题的范围。 – Simon 2013-03-04 10:52:06

回答

3

p在for循环的价值是不正确的,而应是:

p = j * (barWidth + gapBetweenBars) + (barWidth - labelWidth)/2; 

你忘了考虑这个差距。

+1

哇!有用。你做了什么,你是怎么弄明白的? – SuperStar 2013-03-04 10:49:08

+1

@SuperStar你的字符串没有水平对齐,这意味着'p'的值不正确。之后,它只是一个基本的数学运算:列索引/条时间(条宽+间隙)+(条宽/ 2)给出列的中间部分。然后,我们减去标签大小的一半,以使其居中在条上。这就是全部;-) – 2013-03-04 10:51:41

+0

我这么哑:(:( – SuperStar 2013-03-04 10:52:39

3

使用这方面的循环

int labelWidth = labelFontMetrics.stringWidth(languages[j]); 
p = j * (barWidth+gapBetweenBars) + (barWidth - labelWidth)/2; 

改变计算语言串之间的空间