如何从其他类绘制到JPanel(类扩展)

时间:2013-01-29 04:34:43

标签: java swing jpanel java-2d

public class Main extends JPanel implements Runnable {

    private static final int WIDTH = 1000;
    private static final int HEIGHT = 800;
    TerranGenartor gen = new TerranGenartor();

    public Main() {
        setSize(WIDTH, HEIGHT);
        gen.run();
    }

    public void paintComponents(Graphics g) {
        repaint();

    }

    public void run() {
    }
}

我在

收到错误
 TerranGenartor gen = new TerranGenartor(); 

我的TerranGenartor班级

public class TerranGenartor implements Runnable {

    Main main = new Main();
    Graphics g;
    Random r = new Random();
    int SMIN = 1;
    int SMAX = 3;
    int i = 0;
    int num;
    int x = 0;
    int y = 0;
    public Color grass = new Color(124, 252, 0);
    public Color stone = new Color(190, 190, 190);
    public Color dirt = new Color(139, 69, 19);
    boolean Runn = false;

    public void start() {
        Runn = true;
        System.out.println("Working...");
    }

    public TerranGenartor() {
        Runn = true;
    }

    protected void paintComponent(Graphics g) {
        g = main.getGraphics();
        while (Runn) {
            if (i <= 1000) {
                num = r.nextInt(SMAX - SMIN + 1) + SMIN;
                switch (num) {
                    case 1:
                        g.setColor(grass);
                        break;
                    case 2:
                        g.setColor(stone);
                        break;
                    case 3:
                        g.setColor(dirt);
                        break;
                    default:
                        g.setColor(grass);
                        break;
                }
                g.fillRect(x, y, 50, 50);
                x += 50;
                System.out.println(i);
                System.out.println("X: " + x);
                try {
                    Thread.sleep(15);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void run() {
        while (Runn) {
            paintComponent(g);
        }
    }
}

此类是不会在主类中绘制的类(JPanel extend)。我尝试了一些东西,但似乎没有任何工作。

我的The_Runner班级

public class The_Runner {

    Main main = new Main();
    JFrame frame = new JFrame();
    private static final int WIDTH = 1000;
    private static final int HEIGHT = 800;
    String TITLE = "Map gen.";

    public The_Runner() {
        frame.setSize(WIDTH, HEIGHT);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setTitle(TITLE);
        frame.add(main);
    }

    public static void main(String[] args) {
        The_Runner runner = new The_Runner();
    }
}    

这个课程符合并运行它,我认为这一切都很好。

这个问题是,当我想从TerranGenerator类进行绘制时,它不起作用。 JPanel上没有显示任何内容。

1 个答案:

答案 0 :(得分:2)

让我们从...开始......

来自setSize(WIDTH, HEIGHT);

Main。这是一个坏主意。布局管理器可以覆盖这些值(假设您正在使用它)。您应该覆盖getPreferredSize并将其返回...

public Dimension getPreferredSize() {
    return new Dimension(WIDTH, HEIGHT);
}

然后这个(也来自Main

public void paintComponents(Graphics g) {
    repaint();
}

你永远不应该从repaint方法中调用paint或调用任何可能导致repaint被调用的方法,你将最终陷入无限循环的厄运之中你的CPU高达100%

MainTerranGenartor之间有循环引用。基本上你已经在每个中声明了每个引用,编译器无法处理它,因为它不能构建一个类而不构建另一个类。

永远不要这样做......

g = main.getGraphics();

getGraphics可以返回null值。通过此方法返回的结果值只不过是应用程序使用的当前图形上下文的快照。这可以在下一个油漆循环中取消引用或更改。

永远不要从事件调度线程(EDT)外部绘制/更新/修改/创建任何Swing组件,如果你这样做,你最终会得到奇怪的绘画工件,当你尝试更新图形时,EDT也会更新它从不漂亮。

您可能想看看

<强>更新

我怀疑你的“主要”问题(除了无法编译代码)将是repaint请求通过使用main.getGraphics消除您所绘制的任何更改

您还应该在super.paintComponent方法中调用Main#paintComponent

更新了示例