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

Java 重复drawLine()以绘制垂直条,java,swing,draw,paintcomponent,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 wid

我被分配了一项任务,并且能够完成它,但我觉得必须有一个更简单的方法来完成它

我的任务是画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个条重复这一点,只需更改height-h+/-*末端的偏移量,并在条之间留出1的空间

这似乎是一个很长的路要走。关于如何在不重复60次的情况下实现此功能的任何建议

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


[1]:

您可以将
用于
循环和
%

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;
}
for(inti=0,intj=0;i<360;i++){
如果(i%5!=0){
g、 抽绳(x+i,高度,x+i,高度-h-j);
}
如果(i%6=0)
j=j-12;
}
我想这正是你想要的。我做了一些假设:

  • 你每跳过第六行就留下一个空格
  • 你每第二行增加j负12

这是一个关于何时使用循环的好例子。要画出前五条线,你需要这样的东西

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);
    }
}
public void绘图线(int x、int height、int h、int j){
对于(int i=0;i<5;i++){
g、 抽绳(x+i,高度,x+i,高度-h-j);
}
}
但是,这并不完整,因为您必须多次执行此操作。只需使用另一个for循环

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

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

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

}
if( i > 5 && i < 10) {
}
// etc..
}
for(int i=0;i<60;i++){
如果(i<5){
}
如果(i>5&&i<10){
}
//等等。。
}

这是第二次尝试:p

公共组件(图形g){ 超级组件(g)

int-width=getWidth();
int height=getHeight();
System.out.println(“getWidth=“+getWidth());
System.out.println(“getHeight=“+getHeight());
随机rd=新随机();
int x=50;

对于(int i=0;i您看到但不知道的内容

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

我在重复我自己

  • 我为什么要重复这个
  • 这是一种基本模式吗
  • 如果我没有看到一个基本模式…这个代码可以进一步分解吗
  • 每一行代码的增减变化是什么
  • 我知道什么样的编码习惯用法(循环、边做边收集等)最能处理这个问题
这也是为什么保持代码方法简短和切中要害可以让您更清楚地看到上述内容

但在编码之前更重要的是:事先设计你的对象。这将允许你在编码之前解决99个问题

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

(有些人可能会主张将下面代码中的第二个循环保留到其单独的方法中,以保持其干净、可读性,并允许您再次重用它。)

您的解决方案

创建一个方法来获取你的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 );
        }
    }
}
公共组件(图形g){
//实行超级优先
超级组件(g);
//在开始时设置所有字段类型
int totalWidth、totalHeight、barHeight、barWidth、totalBarsRequired;
//设置所有常量字段
barWidth=5;//此处设置条宽(创建方法)
//设置所有方法字段
totalWidth=getWidth();
totalHeight=getHeight();
//无需设置钢筋,因为我们可以根据钢筋宽度计算钢筋
totalBarsRequired=(int)totalWidth/barWidth;
//检查所有需要的栏杆
对于(int-barNumber=0;barNumber
看看其他答案,没有人指出显而易见的问题: 要绘制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();
        }
    }
    ...
}
公共类栏扩展了JPanel{
私人双重价值观;
专用最终静态整型条_宽度=5;
专用最终静态内螺纹间隙=3;
公共酒吧(){
barValues=新的双精度[60];
对于(int i=0;i
使用矩形绘制:

@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);
    }
}
@覆盖
受保护组件(图形g){
维度大小=getSize();
g、 setColor(Color.white);
g、 fillRect(0,0,size.width,size.height);
g、 设置颜色(新颜色(0x445566));
对于(int i=0;i
使用线条绘制
@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);
    }
}
@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);
    }
}