【问题标题】:Calling a method from JFrame from another class从另一个类调用 JFrame 中的方法
【发布时间】:2013-04-09 22:48:50
【问题描述】:

我目前正在制作地形生成器,在一个类中一切正常,但我将扩展我的应用程序。

目前我有一个 JFrame 类,它包含所有内容、生成地形、绘制地形、查找位置等。

我想添加另一个将生成地形的类,但是当我创建这个类时,我需要访问主 JFrame 类中的字段,当我这样做时,我得到一个堆栈溢出错误 - 这是我的代码。

public class Simulator extends Applet
{
//fields

public Simulator()
{
    grid = new int[100][100];
    inhabGrid = new boolean[grid.length][grid.length];
    gridSize = grid.length - 1;
    dist = grid.length;
            TerrainGenerator gen = new TerrainGenerator();
    setSize(dist,dist);
    seedGrid();
    findInhabLocation();
    printGridToConsole();
}

public void paint(Graphics g)   
{
    //panting the grid
}

public void seedGrid()
{
    //seeding

}

public boolean generateTerrain(int x1,int y1, int x2, int y2) 
{

    //terrain generator
}

public boolean mouseUp(Event evt, int x, int y)
{
    seedGrid(); //Create a new map
    findInhabLocation();
    repaint();
    printGridToConsole();
    return true;
}

public boolean keyEvents(Event evt, int x, int y)
{
    seedGrid(); //Create a new map
    findInhabLocation();
    repaint();
    printGridToConsole();
    return true;
}

public void findInhabLocation()
{
    //find best inhabitant location
}

public int locateWater(int x, int y)
{

    //finding closest water
}

public int locateJungle(int x, int y)
{
    //finding closest jungle
}


}
}

这在它自己的类中运行良好,但是当我创建一个类时:

public class TerrainGenerator 
{
Simulator sim = new Simulator();
}

我知道这与构造函数有关,而我正在做的事情很愚蠢,将这个应用程序分成类的最佳方法是什么,例如地形生成器、居民等

例如,我希望能够从“TerrainGenerator”类中调用一个方法并调用,即terrainGenerator.generateTerrain

【问题讨论】:

    标签: java jframe


    【解决方案1】:

    您的 TerrainGenerator 创建了一个 Simulator 对象,反之亦然,因此您最终会得到无限多的对象(但在某些时候堆栈已满并引发堆栈溢出异常......)

    与其在TerrainGenerator 中创建新的Simulator,不如传递对当前Simulator 的引用(嗯,实际上,这也不是一个很好的设计,但我不会让你混淆循环引用的问题)。

    【讨论】:

    • 谢谢,是的,我可以看到正在发生无限循环,你会在字段中声明 TerrainGenerator 吗?
    • 您可以只创建一个构造函数TerrainGenerator(Simulator sim) 并调用new TerrainGenerator(this)。这不是一个好的做法,并且会导致警告“在构造函数中泄漏”,但由于您的代码不是多线程的,这不太可能是一个真正的问题。
    • 好的,感谢您的帮助,还有其他方法可以解决这个问题吗?我觉得我以错误的方式解决这个问题,我可以不创建一个新的 TerrainGenerator 并让方法参数需要生成所需的内容吗?
    • @Dowskiii 是的,肯定会更干净。理想情况下,您根本不希望 TerrainGenerator 依赖于 Simulator。将您需要的所有内容作为方法参数传递将是一个更好的设计。
    • 或者更好的是,使用 MVC 之类的东西,就像 Jorge Iten 指出的那样,但这需要更多的努力。
    【解决方案2】:

    Heuster 的回答是正确的,另外,我认为你可以看看MVC 来帮助你组织你的课程。

    【讨论】:

    • 谢谢,这很有帮助。所以在这里我应该有一个处理数据的“中间人”,然后我可以创建该对象的一个​​实例来为我检索数据?
    • 是的,控制器是“中间人”。每当视图发生变化时,您都可以调用控制器。
    【解决方案3】:

    根据哪个应该是父类,你可以将实例化的类传递给另一个,即;

    private final TerrainGenerator gen;  //if you need to save this.
    public Simulator(TerrainGenerator terrainGenerator)
    {
    
      this.gen = terrainGenerator;
     ....etc
    }
    
    
    public class TerrainGenerator 
    {
    Simulator sim = new Simulator(this);
    }
    

    private final TerrainGenerator gen;  //if you need to save this.
    public Simulator()
    {
    
      this.gen = new TerrainGenerator(this);
     ....etc
    }
    
    private final Simulator sim; //If you need to save it.
    public class TerrainGenerator 
    {
      public TerrainGenerator(Simulator simulator) {
        this.sim = simulator;
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-20
      • 1970-01-01
      相关资源
      最近更新 更多