Java绘制奇怪的视觉工件/ bug

时间:2014-12-26 15:47:23

标签: java swing

我是java编程的初学者。我们得到了一个任务,做一些算法。我有Sierpinski Triangle。我有一个创建2D数组并存储值的想法,0 =白色矩形,1 =蓝色矩形。绘制它我遇到了很大的麻烦(从未有过使用swing / awt的经验)。我终于做到了,但在绘图结束时出现了奇怪的视觉错误。它没有结束,但线路仍在继续。

我不知道为什么会这样。

这是我的代码:

扩展Okno

JPanel类:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package newpackage;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Arrays;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/**
 *
 * @author Juraj
 */
class Okno extends JPanel {

    // value = 1 is blue rectangle, value 0 = white rectangle
    public static int n = 500;
    public static int[][] tabulka = new int[n][n]; //creating 2D array

    public static void inicializaciaTabulky(){
        for (int i = 0; i < n; i++) { // initialization of 2D array (first column and first row = 1)
            tabulka[0][i] = 1;
            tabulka[i][0] = 1;
        }
    }

    // filling the rest of the array; if the cell above and cell to the left are the same value, e.g.
    // value of 1 or 0, then it is 0, everything else is 1
    public static void doplnenieTabulky() {
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                if (tabulka[i-1][j] == 1 && tabulka[i][j-1] == 1 || 
                    tabulka[i-1][j] == 0 && tabulka[i][j-1] == 0) {
                    tabulka[i][j] = 0;
                } else {
                    tabulka[i][j] = 1;
                }
            }
        }
    }

    // drawing rectangles; if the value is 1 = blue rectangle, value 0 = white rectangle
    private void vykreslenie(Graphics g){
        Graphics2D g2d = (Graphics2D) g;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                switch(tabulka[i][j]) {
                    case 0: 
                        g.setColor(Color.white);
                        g.drawRect(i, j, 50, 50);
                        break;
                    case 1: 
                        g.setColor(Color.blue);
                        g.drawRect(i, j, 50, 50);
                        break;
                }
            }
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        vykreslenie(g);
    }
}
扩展Trojuholnik

JFrame类:

public class Trojuholnik extends JFrame {  
    public Trojuholnik() {
        initUI();
    }

    private void initUI() {
        setSize(800, 600);
        setTitle("Sierpinski Triangle");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(new Okno());
        setLocationRelativeTo(rootPane);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Trojuholnik trojuholnik = new Trojuholnik();
                trojuholnik.setVisible(true);
                Okno.inicializaciaTabulky();
                Okno.doplnenieTabulky();
                System.out.println(Arrays.deepToString(Okno.tabulka));
            }
        });
    }
}

目前的结果如下:

result of code

1 个答案:

答案 0 :(得分:3)

首先提出一些基本建议:

不要创建一个扩展JFrame的类。您没有向框架添加新功能,因此您应该将面板添加到框架中。因此run()方法中的基本代码应该是:

JFrame frame = new JFrame();
frame.setTitle("Sierpinski Triangle");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new Okno());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

不要在你的Okno类中使用静态变量和方法。只需为您的类创建一个构造函数,并在构造函数中初始化该数组。

在进行自定义绘制时,您应该覆盖类的getPreferredSize()方法以返回组件的大小,因为每个组件都应该知道它自己的大小。请注意我是如何更改上述代码以使用pack()方法的。现在框架将正确调整大小。所以你要在你的Okno课程中添加如下内容:

@Override
public Dimension getPreferredSize()
{
    return new Dimension(500, 500);
}

关于绘画问题。我真的不知道算法在做什么,但我怀疑问题是你的数组有500个值,但是Rectangle的绘画使用的是50的大小,所以你的面板的大小实际上是550x550不是500x500导致工件。

我认为解决方案是简单地用矩形大小(1,1)绘制。至少这幅画看起来和我一样。