重复drawLine()绘制垂直条形Java

时间:2013-11-17 21:22:18

标签: java swing draw paintcomponent

我获得了一项任务,并且能够完成任务,但我觉得必须有一种更简单的方法来完成它。

我的任务是绘制60个垂直条,宽度为5,随机高度。

public void paintComponent( Graphics g )
{
    super.paintComponent( g );
    g.setColor( color );
    int width = getWidth();
    int height = getHeight();
    int x, h;

// bar with a width of 5 and random heights

    h = rd.nextInt(height); //random height
    x = 50;


g.drawLine( x, height, x, height-h ); //Bar 1
g.drawLine( x+1, height, x+1, height-h );
g.drawLine( x+2, height, x+2, height-h );
g.drawLine( x+3, height, x+3, height-h );
g.drawLine( x+4, height, x+4, height-h );

g.drawLine( x+6, height, x+6, height-h -12 ); // Bar 2
g.drawLine( x+7, height, x+7, height-h -12 );
g.drawLine( x+8, height, x+8, height-h -12 );
g.drawLine( x+9, height, x+9, height-h -12 );
g.drawLine( x+10, height, x+10, height-h -12);

我所做的只是对所有60个小节重复此操作,只需更改高度末尾的偏移量-h +/- * 并在小节之间留下1的空格

这似乎是一个很长的路要走。关于如何实现这一点的任何建议,不重复60次。

编辑:添加了最终项目的图像。 这是完成的外观![1]

[1]: http://i.stack.imgur.com/3ivpM.png

6 个答案:

答案 0 :(得分:2)

看看其他答案,没有人说出明显的答案: 要绘制60个条形图,您不需要绘制超过60个项目(当然不是60x5 = 300行)。

您的选择:

  • 将条形绘制为填充矩形
  • 将条形绘制为宽度为5
  • 线条

在绘画时不应计算条形值,它们应该是数据模型。

public class Bars extends JPanel {

    private double[] barValues;
    private final static int BAR_WIDTH = 5;
    private final static int BAR_GAP = 3;

    public Bars () {
        barValues = new double[60];
        for (int i = 0; i < barValues.length; i++) {
            barValues[i] = Math.random();
        }
    }
    ...
}

使用矩形绘画:

@Override
protected void paintComponent (Graphics g) {
    Dimension size = getSize();
    g.setColor(Color.white);
    g.fillRect(0, 0, size.width, size.height);
    g.setColor(new Color(0x445566));

    for (int i = 0; i < barValues.length; i++) {
        int h = (int) Math.round(barValues[i] * size.height);
        int x = (i * (BAR_WIDTH + BAR_GAP));
        int y = size.height - 1 - h;
        int w = BAR_WIDTH;
        g.fillRect(x, y, w, h);
    }
}

使用宽度为5的线条进行绘画

@Override
protected void paintComponent (Graphics g) {

    Dimension size = getSize();
    g.setColor(Color.white);
    g.fillRect(0, 0, size.width, size.height);
    g.setColor(new Color(0x445566));

    Graphics2D g2 = (Graphics2D) g;
    g2.setStroke(new BasicStroke(5, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));

    for (int i = 0; i < barValues.length; i++) {
        int h = (int) Math.round(barValues[i] * size.height);
        int x = (i * (BAR_WIDTH + BAR_GAP)) + BAR_WIDTH / 2;
        int y = size.height - 1 - h;
        g.drawLine(x, y, x, y + h);
    }
}

答案 1 :(得分:0)

您可以使用for循环%

for(int i = 0, int j = 0 ; i < 360 ; i++ ) {
    if(i % 5 != 0 ) {
        g.drawLine( x+i, height, x+i, height-h - j);
    }

    if(i % 6 = 0)
        j = j - 12;
}

我认为这适合你想要的东西。我做了一些假设:

  • 您跳过每隔6行留一个空格
  • 每隔一行将j增加负12

答案 2 :(得分:0)

这是何时使用循环的一个很好的例子。要绘制前五行,你需要这样的东西。

public void drawLines(int x, int height, int h, int j){
    for(int i = 0; i < 5; i++){
        g.drawLine(x + i, height, x + i, height - h - j);
    }
}

但是,这不完整,因为您必须多次执行此操作。只需使用另一个for循环。

for(int i = 0; i < 12, i++){
    drawLines(x + i * 5, height, h, i * 12);
}

答案 3 :(得分:0)

为什么你不使用for循环和一堆if语句!

for(int i = 0; i < 60; i++) {
if( i < 5) {

}
if( i > 5 && i < 10) {
}
// etc..
}

答案 4 :(得分:0)

这是第二次尝试:P

public void paintComponent(Graphics g){             super.paintComponent方法(克);

        int width = getWidth();
        int height = getHeight();
        System.out.println("getWidth = " + getWidth());
        System.out.println("getHeight = " + getHeight());
        Random rd = new Random();
        int x = 50;

        for (int i = 0; i <= 60; i++) {

            int fisrt = (i / 12) * 12;

            for (int j = 0; j < 12; j++) {

                int h = rd.nextInt(height); // random height

                g.drawLine(x + j, height, x + j, height - h - fisrt);

            }
        }

    }

答案 5 :(得分:0)

你看到但却不知道

您看到了重复代码的模式。在时间上,可能在算法类之后你应该能够预先预测模式,有些是明显的,有些则不是。这就是推理,演绎和数学技能的用武之地。其顺序如下:

我在重复自己......

  • 为什么我要重复这个
  • 这是基本模式吗?
  • 如果我没有看到基本模式......可以进一步细分此代码吗?
  • 在同一行代码上改变增加/减少的内容
  • 我知道哪种编码习惯用法(循环,做什么,收集等)最适合这个

这也是保持代码方法简短的原因,并且可以让您更清楚地看到上述内容。

但在编码之前更重要:事先设计对象。这样您就可以在处理编码方面之前解决99个问题。

一个好的设计可以在任何类型的代码中工作(在这种情况下是OO /面向对象)。

(有些人可能会争辩将下面的代码中的第二个循环保持为单独的方法,以保持其清洁,可读并允许您再次重复使用它。)

您的解决方案

创建一个获取barWidth的方法,这应该是整个paintComponent方法。所有内容都经过评论,所有变量都明确定义了它们的作用,但如果您需要任何帮助,请理解任何部分。

我不确定你为什么把它作为全球领域。

public void paintComponent( Graphics g ) {

    // Carry out super first
    super.paintComponent( g );

    // Set all field types at start
    int totalWidth, totalHeight, barHeight, barWidth, totalBarsRequired;

    // Set all constant fields
    barWidth = 5; // THE BAR WIDTH IS SET HERE (Create a method)

    // Set all method fields
    totalWidth = getWidth();
    totalHeight = getHeight();
    // No need to set the bars as we can calculate them from the bar width
    totalBarsRequired = (int) totalWidth / barWidth;

    // Look over all the bars required
    for( int barNumber = 0 ; barNumber < totalBarsRequired ; barNumber++ ) {
        // Set a new random height each bar
        barHeight = rd.nextInt( totalHeight );

        // Create the lines and loop until the barWidth has been met
        for (int barLineNumber = 0 ; barLineNumber < barWidth ; barLineNumber++ ) {
            g.drawLine( (barNumber * barWidth) + barLineNumber, barHeight, (barNumber * barWidth) + barLineNumber, barHeight );
        }
    }
}