如何在java中创建两个完全独立的窗口而不使用SwingUtilities?

如何在java中创建两个完全独立的窗口而不使用SwingUtilities?,java,window,java-9,Java,Window,Java 9,免责声明:我知道有一个与我的问题类似的问题,但我的问题不同 我正在尝试为我正在创建的游戏创建自己的调试器。我想创建两个窗口:一个窗口用于我的游戏,另一个窗口用于我的调试器,当调试器打开时,我可以在其中管理、查看和更改游戏变量。我希望能够同时使用和查看这两个窗口。问题是我的调试器窗口已连接到我的游戏窗口。当我关闭调试器窗口时也是关闭游戏窗口,这是一个问题 我不想改变我创建游戏窗口的方式,我只想改变调试器窗口 这是我用来创建游戏窗口的代码: // main method starts pub

免责声明:我知道有一个与我的问题类似的问题,但我的问题不同

我正在尝试为我正在创建的游戏创建自己的调试器。我想创建两个窗口:一个窗口用于我的游戏,另一个窗口用于我的调试器,当调试器打开时,我可以在其中管理、查看和更改游戏变量。我希望能够同时使用和查看这两个窗口。问题是我的调试器窗口已连接到我的游戏窗口。当我关闭调试器窗口时也是关闭游戏窗口,这是一个问题

我不想改变我创建游戏窗口的方式,我只想改变调试器窗口

这是我用来创建游戏窗口的代码:

// main method starts
    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame("Ultra Ball"); // create application window
        Game game = new Game(); // represents game class
        frame.add(game); // add the frame
        // set size of application window
        frame.setMaximumSize(new Dimension(game.getScreenWidth(), game.getScreenHeight()));
        frame.setMinimumSize(new Dimension(600, 500)); // set minimum size
        frame.setSize(600, 500); // for testing the game size
        frame.setVisible(true); // show the application window
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // basic window operations
        Image icon = game.createImage("images/logo.png"); // icon
        frame.setIconImage(icon); //set the icon
        while (true) { // runs throughout the game
            game.setBackground(background); // set background color
            game.resize(); // resize game component
            game.move(); // move game components
            game.collisionDetection(); // detect objects collision
            game.debug(true); // debug the game
            game.repaint(); // redraw the game
            Thread.sleep(10); // pauses execution of game
        } // while loop ends

    } // main method ends
// Debug class begins
public class Debug {

    // link classes
    @SuppressWarnings("unused")
    private Game game; // Game class

    // JFrame
    JFrame window = new JFrame("Debugger");

    // Debug constructor begins 
    public Debug(Game game) {
        this.game = game;
    } // Debug constructor ends

    // create a debugger
    public void debug() {
        window.setSize(500, 500);
        window.setVisible(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    } // debug method ends

} // Debug class ends
这是我用来创建调试器窗口的代码:

// main method starts
    public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame("Ultra Ball"); // create application window
        Game game = new Game(); // represents game class
        frame.add(game); // add the frame
        // set size of application window
        frame.setMaximumSize(new Dimension(game.getScreenWidth(), game.getScreenHeight()));
        frame.setMinimumSize(new Dimension(600, 500)); // set minimum size
        frame.setSize(600, 500); // for testing the game size
        frame.setVisible(true); // show the application window
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // basic window operations
        Image icon = game.createImage("images/logo.png"); // icon
        frame.setIconImage(icon); //set the icon
        while (true) { // runs throughout the game
            game.setBackground(background); // set background color
            game.resize(); // resize game component
            game.move(); // move game components
            game.collisionDetection(); // detect objects collision
            game.debug(true); // debug the game
            game.repaint(); // redraw the game
            Thread.sleep(10); // pauses execution of game
        } // while loop ends

    } // main method ends
// Debug class begins
public class Debug {

    // link classes
    @SuppressWarnings("unused")
    private Game game; // Game class

    // JFrame
    JFrame window = new JFrame("Debugger");

    // Debug constructor begins 
    public Debug(Game game) {
        this.game = game;
    } // Debug constructor ends

    // create a debugger
    public void debug() {
        window.setSize(500, 500);
        window.setVisible(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    } // debug method ends

} // Debug class ends
触发调试器:

// debug method begins
public void debug(boolean status) {
    if (status == true) {
        debug.debug();
    }
}

提前感谢您的帮助。

通过这一行,您可以显式地设置调试器窗口以关闭应用程序:
窗口。setDefaultCloseOperation(JFrame.EXIT\u ON\u close)

在关闭时退出(在JFrame中定义):使用 系统退出方法

尝试指定不同的操作,甚至完全删除此行,因此默认操作将是
HIDE\u ON\u CLOSE

文档和所有可用选项:

因此,快速浏览一下代码

game.debug
是每个周期的调用

while (true) { // runs throughout the game
    game.setBackground(background); // set background color
    game.resize(); // resize game component
    game.move(); // move game components
    game.collisionDetection(); // detect objects collision
    game.debug(true); // debug the game
    game.repaint(); // redraw the game
    Thread.sleep(10); // pauses execution of game
} // while loop ends
这似乎叫

// debug method begins
public void debug(boolean status) {
    if (status == true) {
        debug.debug();
    }
}
// create a debugger
public void debug() {
    window.setSize(500, 500);
    window.setVisible(true);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} // debug method ends
这似乎叫

// debug method begins
public void debug(boolean status) {
    if (status == true) {
        debug.debug();
    }
}
// create a debugger
public void debug() {
    window.setSize(500, 500);
    window.setVisible(true);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} // debug method ends
这就解释了为什么调试框架不断弹出

两个即时解决方案浮现在脑海中,@krystainG演示的第一个方法是将
window.setDefaultCloseOperation(JFrame.EXIT\u ON\u CLOSE)
更改为类似
window.setDefaultCloseOperation(JFrame.DISPOSE\u ON\u CLOSE)

下一个解决方案是更改调用“何时”和“如何”
Debug#Debug(布尔)

我要采取的第一步是将
game.debug
调用移出游戏循环

game.debug(true); // debug the game
while (true) { // runs throughout the game
    game.setBackground(background); // set background color
    game.resize(); // resize game component
    game.move(); // move game components
    game.collisionDetection(); // detect objects collision
    game.repaint(); // redraw the game
    Thread.sleep(10); // pauses execution of game
} // while loop ends
我可能做的第二个更改是仅在实际更改状态时更新状态

private boolean isDebugging = false;

// debug method begins
public void debug(boolean status) {
    if (status != isDebugging) {
        isDebugging = status
        if (status == true) {
            debug.debug();
        } else {
            // Close the debug window
        }
    }
}

当类已经处于指定状态时,这将阻止该方法对状态更改作出反应

我在代码中使用while循环,因此当我使用“JFrame.DISPOSE\u ON\u CLOSE”时,调试器窗口将不断弹出。因此,可能行:
game.debug(true);//调试游戏
应该在循环之前只执行一次?@Ryan您不应该从事件调度线程的上下文之外(直接或间接)修改UI的状态。代替尝试使用循环来更新调试器帧,考虑使用观察者模式或生产者消费者模式或探针模式来独立于主游戏循环来更新调试器的状态。kystain提供的答案将解决您提出的问题。如果这个解决方案给你带来了问题,那么考虑一下提供,这就说明了你正在优化代码的问题。我把“game.debug(true);”放在while循环的正上方,这样“JFrame.DISPOSE\u ON\u CLOSE”就可以工作了。谢谢你的帮助。“免责声明:我知道我的问题有一个类似的问题,但我的问题是不同的。”根据我所读的,我认为这不是真的;“我不想改变我创建游戏窗口的方式”-如果这是唯一想解决你问题的方法呢?哪个对你更重要?避免对一个你们似乎不理解的问题口授术语——这将有助于减少你们对问题的失望solutions@MadProgrammer限制解决方案空间在软件开发(或任何工程任务中,真的)中很常见,而“它无法完成(有这些需求)”将是一个有效的答案。根据这些信息,Ryan可以做出你所问的权衡。除此之外,假设你的双重否定不是有意的,他当然不完全理解这个问题——这就是他问问题的原因@Nicolai,我对这些都没有异议,但如果“你有问题”,你应该避免“口述”你希望如何解决问题,并寻找更多的“解决方案”这项工作——因为当前的方法对于所寻求的东西来说可能是完全错误的——知道何时放弃一种方法也是软件的一个重要方面development@MadProgrammer你知道他已经知道其他的解决方案了,对吧?他特别问了这个问题,以了解是否有一个符合他的具体要求。这对于有足够的信息来选择解决方案和潜在地放弃需求是必要的。换句话说,说明限制是做出明智决定的必要条件,你不应该因此批评他。@Nicolai在你看来(我个人对此没有异议)-我问的是,哪个更重要?解决方案还是保持当前状态?我只是建议他们应该避免这样做,因为这样可以提供他们可能没有考虑过的更广泛的可能性