JAVA:正确的for循环迭代混淆了吗?

时间:2014-11-11 08:34:14

标签: java loops for-loop methods iteration

背景资料:

我正在编写一个程序,我应该使用类DrawingPanel绘制一个数据集,该数据集存储在以下文件(input file)中,名为“names.txt”。 / p>

此java文件允许您创建给定大小的面板,并在此面板中绘制形状和线条。我遇到的程序遇到的问题与类方法的规范和理解无关。

我应该使用此java文件绘制的数据集按以下方式配置:

[姓名] [性别] [排名] [排名] [排名] [排名] ....等共14个排名。

示例:

Jane F 98 108 128 116 48 55 47 39 67 202 312 345 436 384

计划的总体目标: 用户应该输入他们想要看到的图表和性别。然后绘制数据,表示y轴的排名和表示x轴的时间。

我的主要问题正在绘制构成图表的线条。这些图的线条用以下方法绘制:

g.drawLine(x1, y1, x2, y2)

用g表示Graphics对象。需要两点,因为创建一条线需要两个端点。

这个for循环负责打印线条。

    for (int j = 0; j < SECTION_WIDTH * DECADES; j += SECTION_WIDTH){
            g.setColor(Color.BLACK);
            g.drawLine(j, yCoordinate, i + intervalIncrease, yCoordinate2);
            g.setColor(Color.RED);
            intervalIncrease += SECTION_WIDTH;
            g.drawString(intervalLabel, intervalIncrease , yCoordinate);
            }            
    }

问题摘要:上面的for循环是我程序中错误的原因。问题是构成图形的线条打印不正确。这是由不正确的循环迭代和条件引起的,这些迭代和条件由于for循环的尴尬位置而变得复杂,并且事实上两个调用一切都是正确运行程序所必需的。尽管猜测和检查几个小时,我无法弄清楚如何操纵循环使其工作。

这很复杂,因为drawString方法依赖于drawLine方法变量。

我已经尝试在我的代码中实现它,但它没有用。

有关DrawingPanel.java的具体要求和其他信息:

请参阅此(Specification)了解有关图表外观的规格和其他要求。

下面还提供了图表应该是什么样子的图片。

    public static void drawRanks(String line, Graphics g){
    int yearIncrease = 0;
    int intervalIncrease = 0;
    System.out.println(line);
    Scanner lineScan = new Scanner(line);
    String name = lineScan.next();
    String gender = lineScan.next();
    for(int i = 0; i < DECADES/2; i++) {
        g.setColor(Color.RED);
        int rank = lineScan.nextInt();
        int rank2 = lineScan.nextInt();
        int yCoordinate = rank/2 + 25;
        int yCoordinate2 = rank2/2 + 25;
        String intervalLabel = name + " " + gender + " " + String.valueOf(rank);
        String intervalLabel2 = name + " " + gender + " " + String.valueOf(rank2);
        if (rank == 0){
            yCoordinate = 525;
        }
        if (rank2 == 0){
            yCoordinate2 = 525;
        }
        for (int j = 0; j < SECTION_WIDTH * DECADES; j += SECTION_WIDTH){
            g.setColor(Color.BLACK);
            g.drawLine(j, yCoordinate, i + intervalIncrease, yCoordinate2);
            g.setColor(Color.RED);
            intervalIncrease += SECTION_WIDTH;
            g.drawString(intervalLabel, intervalIncrease , yCoordinate);
            }            
    }

    for(int j = 0; j < DECADES; j++) {
        g.setColor(Color.BLACK);
        g.drawString(String.valueOf(STARTING_YEAR + yearIncrease), SECTION_WIDTH * j, 550);
        yearIncrease += 10;
    }  

    for (int k = DECADES * SECTION_WIDTH; k >= 0; k -= SECTION_WIDTH){
        g.drawLine(k, 0, k, 550);
    }

}

生成的图表图片:DrawingPanel Graph http://i59.tinypic.com/2rmqgdf.png

预期图表:Expected DrawingPanel Graph http://i62.tinypic.com/1ooyuc.jpg

如果我的解释不清楚,请随时发表评论。 这是DrawingPanel类所在的位置,如有必要,可用于编译目的。 DrawingPanel.java

以下是方法的API:

DrawingPanel name = new DrawingPanel(width, height);

Graphics g - name.getGraphics();

panel.setBackground(color); -  sets panel's background color

g.setColor(color); - sets Graphics pen color (like dipping a brush in paint)

g.drawLine(x1, y2, x2, y2); - a line from points (x1, y1) to (x2, y2)

g.drawString(text, x, y); - the given text with its lower-left corner at (x, y)

1 个答案:

答案 0 :(得分:2)

你的一般想法,你必须成对阅读排名,是错误的。你要做的是从最后一个等级的坐标画一条线到当前等级的坐标。这是我的方法版本(请注意,我没有整个环境,所以我无法对此进行测试):

public static void drawRanks(String line, Graphics g){
    int yearIncrease = 0;
    System.out.println(line);
    Scanner lineScan = new Scanner(line);
    String name = lineScan.next();
    String gender = lineScan.next();
    int lastRank = lineScan.nextInt();
    int lastY = lastRank/2 + 25;
    if ( lastRank == 0 ) {
        lastY = 525;
    }
    int lastX = 0;

    while ( lineScan.hasNextInt() ) {
        int rank = lineScan.nextInt();

        int y = rank/2 + 25;
        if (rank == 0){
            y = 525;
        }
        int x = lastX + SECTION_WIDTH;

        String intervalLabel = name + " " + gender + " " + String.valueOf(lastRank);

        g.setColor(Color.RED);
        g.drawLine(lastX, lastY, x, y);
        g.drawString(intervalLabel,lastX,lastY);
        lastX = x;
        lastY = y;
        lastRank = rank;

    }

    g.drawString(intervalLabel,lastX,lastY);

    for(int j = 0; j < DECADES; j++) {
        g.setColor(Color.BLACK);
        g.drawString(String.valueOf(STARTING_YEAR + yearIncrease), SECTION_WIDTH * j, 550);
        yearIncrease += 10;
    }  

    for (int k = DECADES * SECTION_WIDTH; k >= 0; k -= SECTION_WIDTH){
        g.drawLine(k, 0, k, 550);
    }

}

首先你读了名字和性别,然后你读了第一个等级,给你初始坐标。

然后,在循环的每次迭代中,您只读取一个等级。您将之前排名的线条绘制到新排名。您在先前的等级坐标处绘制属于先前等级的标签。然后将当前的xyrank分别保存到lastXlastYlastRank,以便您可以依赖他们在下一次迭代中。

完成循环后,你仍然有一个标签你还没画出来,所以你绘制它,然后你继续绘制黑线(我没有看到你的代码的纠正在那里,只是保持原样。)