JFrame中如何实现希尔伯特曲线

How to implement Hilbert Curve in JFrame

我想做一个基于希尔伯特曲线的项目。我能够在 Applet 中使用代码,但我需要它在 JFrame 中工作,因为我需要一次打开多个框架来展示我的项目。下面小程序里有代码,不知道怎么改成JFrame

在小程序形式下,就像下面的代码:

import java.awt.*;
import java.applet.*;   

public class HilbertCurve extends Applet{
private SimpleGraphics sg = null;
private int dist0=256;
private int dist=dist0;

public void init(){
    resize(dist0, dist0);
    sg = new SimpleGraphics(getGraphics());}

public void paint(Graphics g){
    int level = 4;
    dist = dist0;
    for(int i=level; i>0; i--) dist/=2;
    sg.goToXY (dist/2, dist/2);
    HilbertU(level);
}

private void HilbertU(int level){
    if(level>0){
        HilbertD(level-1); sg.lineRel(0,dist);
        HilbertU(level-1); sg.lineRel(dist,0);
        HilbertU(level-1); sg.lineRel(0,-dist);
        HilbertC(level-1);
    }
}

private void HilbertD(int level){
    if(level>0){
        HilbertU(level-1); sg.lineRel(dist,0);
        HilbertD(level-1); sg.lineRel(0,dist);
        HilbertD(level-1); sg.lineRel(-dist,0);
        HilbertA(level-1);
    }
}
private void HilbertC(int level){
    if(level>0){
        HilbertA(level-1); sg.lineRel(-dist,0);
        HilbertC(level-1); sg.lineRel(0,-dist);
        HilbertC(level-1); sg.lineRel(dist,0);
        HilbertU(level-1);
    }
}
private void HilbertA(int level){
    if(level>0){
        HilbertC(level-1); sg.lineRel(0,-dist);
        HilbertA(level-1); sg.lineRel(-dist,0);
        HilbertA(level-1); sg.lineRel(0,dist);
        HilbertD(level-1);
    }
}

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

class SimpleGraphics{
private Graphics g = null;
private int x =0, y = 0;

public SimpleGraphics(Graphics g) {
    this.g = g;}

public void goToXY(int x, int y){
    this.x =x;
    this.y= y;
}

public void lineRel(int deltaX, int deltaY){
    g.drawLine(x, y, x+deltaX, y+deltaY);
    x+=deltaX;
    y+=deltaY;}
} 

我试着自己把它放到 JFrame 上,但是我做不到。 JFrame 打开,但 HilbertCurve 没有启动。下面是我的代码,我没有更改 class SimpleGraphics

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

public class HilbertCurve extends JPanel {
JFrame frame;

private SimpleGraphics sg = null;
private int dist0=256;
private int dist=dist0;


public static void main(String[] args){
    HilbertCurve exemplo1 = new HilbertCurve();
    exemplo1.fireUpScreen();
}

public void fireUpScreen(){
    frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(512,512);
    frame.setVisible(true);
    frame.add(this);
}

public void paint(Graphics g){

    int level = 4;
    dist = dist0;
    for(int i=level; i>0; i--) dist/=2;
    sg.goToXY (dist/2, dist/2);
    HilbertU(level);

}

private void HilbertU(int level){
    if(level>0){
        HilbertD(level-1); sg.lineRel(0,dist);
        HilbertU(level-1); sg.lineRel(dist,0);
        HilbertU(level-1); sg.lineRel(0,-dist);
        HilbertC(level-1);
    }
}

private void HilbertD(int level){
    if(level>0){
        HilbertU(level-1); sg.lineRel(dist,0);
        HilbertD(level-1); sg.lineRel(0,dist);
        HilbertD(level-1); sg.lineRel(-dist,0);
        HilbertA(level-1);
    }
}
private void HilbertC(int level){
    if(level>0){
        HilbertA(level-1); sg.lineRel(-dist,0);
        HilbertC(level-1); sg.lineRel(0,-dist);
        HilbertC(level-1); sg.lineRel(dist,0);
        HilbertU(level-1);
    }
}

 private void HilbertA(int level){
    if(level>0){
        HilbertC(level-1); sg.lineRel(0,-dist);
        HilbertA(level-1); sg.lineRel(-dist,0);
        HilbertA(level-1); sg.lineRel(0,dist);
        HilbertD(level-1);
    }
}

}

首先,我建议您先通读 Performing Custom Painting and Painting in AWT and Swing 以更好地理解 Swing 中的绘画工作原理。

示例 Applet 实际上是如何执行绘制的一个糟糕示例,因为您永远不应该维护对 Graphics 的引用,并且应该在绘制组件时将其传递给需要它的方法。

您还应该以 NullPointerException 作为结尾,因为 sg 从未被初始化。

一般来说,先建立UI,最后再调用setVisible,可以解决一些简单的问题。

没有理由 HilbertCurve 需要引用 JFrame,框架可以在 main 方法中实例化。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class HilbertCurve extends JPanel {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                HilbertCurve exemplo1 = new HilbertCurve();
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(exemplo1);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    private SimpleGraphics sg = null;
    private int dist0 = 256;
    private int dist = dist0;

    public HilbertCurve() {
        sg = new SimpleGraphics();
    }

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

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        int level = 4;
        dist = dist0;
        for (int i = level; i > 0; i--) {
            dist /= 2;
        }
        sg.goToXY(dist / 2, dist / 2);
        Graphics2D g2d = (Graphics2D) g.create();
        hilbertU(g2d, level);
        g2d.dispose();

    }

    private void hilbertU(Graphics2D g, int level) {
        if (level > 0) {
            hilbertD(g, level - 1);
            sg.lineRel(g, 0, dist);
            hilbertU(g, level - 1);
            sg.lineRel(g, dist, 0);
            hilbertU(g, level - 1);
            sg.lineRel(g, 0, -dist);
            hilbertC(g, level - 1);
        }
    }

    private void hilbertD(Graphics2D g, int level) {
        if (level > 0) {
            hilbertU(g, level - 1);
            sg.lineRel(g, dist, 0);
            hilbertD(g, level - 1);
            sg.lineRel(g, 0, dist);
            hilbertD(g, level - 1);
            sg.lineRel(g, -dist, 0);
            hilbertA(g, level - 1);
        }
    }

    private void hilbertC(Graphics2D g, int level) {
        if (level > 0) {
            hilbertA(g, level - 1);
            sg.lineRel(g, -dist, 0);
            hilbertC(g, level - 1);
            sg.lineRel(g, 0, -dist);
            hilbertC(g, level - 1);
            sg.lineRel(g, dist, 0);
            hilbertU(g, level - 1);
        }
    }

    private void hilbertA(Graphics2D g, int level) {
        if (level > 0) {
            hilbertC(g, level - 1);
            sg.lineRel(g, 0, -dist);
            hilbertA(g, level - 1);
            sg.lineRel(g, -dist, 0);
            hilbertA(g, level - 1);
            sg.lineRel(g, 0, dist);
            hilbertD(g, level - 1);
        }
    }

    class SimpleGraphics {

//        private Graphics g = null;
        private int x = 0, y = 0;

        public SimpleGraphics() {
        }

        public void goToXY(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public void lineRel(Graphics2D g, int deltaX, int deltaY) {
            g.drawLine(x, y, x + deltaX, y + deltaY);
            x += deltaX;
            y += deltaY;
        }
    }
}