如何修复我的 JFrame 未打开,编译器没有给我任何错误,我该如何修复?

How do I fix my JFrame not opening, the compiler gives me no errors, how do I fix it?

[技术上不是 [重复]] 我知道这以前发生过(有一个错误,我的 JFrame 在编译我的游戏时无法打开,我该如何解决这个 [重复])并且 MadProgrammer 回答:"Game.main isn't doing anything. Since its the main entry point for the program, it will need to do something before something can happen" 但现在 Game.main 做了一些我看不到答案的事情。

我尝试重新编译并检查错误,none,其他人甚至让它工作。我该如何解决这个问题

Game.java:

package com.hypopixel;

import java.awt.*;

import javax.swing.*;

import java.applet.*;

public class Game extends Canvas implements Runnable {

    public static final long serialVersionUID = 1L;

    private Thread thread;
    private Boolean running = false;

    public Game() {
        new Window(800, 600, this);
    }

    public synchronized void start() {
        thread = new Thread(this);
        thread.start();
        running = true;
    }
    public synchronized void stop() {
        try {
            thread.join();
            running = false;
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {
    }

    public static void main(String[] args) {
        new Game();
    }
}

Window.java:

package com.hypopixel;

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

public class Window extends Canvas {

    public static int BlockSizing = 4;

    public static final long serialVersionUID = 1L;

    public Window(int Wwidth, int Wheight, Game game) {
        JFrame Window = new JFrame();
        setPreferredSize(new Dimension(Wwidth, Wheight));
        setMinimumSize(new Dimension(800, 600));
        Window.add(game);
        Window.pack();
        Window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Window.setTitle("HypoPixel");
        Window.setLocationRelativeTo(null);
        Window.setVisible(true);
        game.start();
    }
}
/*

Credits:

Just another Java Programmer

MadProgrammer

*/

manifest.txt同

我希望 JFrame 能够打开(因为其他人能够得到它)但它打不开。

所以,有很多东西是 "off"

开始于...

public Window(int Wwidth, int Wheight, Game game) {
    JFrame Window = new JFrame();
    setPreferredSize(new Dimension(Wwidth, Wheight));
    setMinimumSize(new Dimension(800, 600));
    Window.add(game);
    Window.pack();
    Window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Window.setTitle("HypoPixel");
    Window.setLocationRelativeTo(null);
    Window.setVisible(true);
    game.start();
}

除了在java.awt中已经有一个叫Window的class让人迷惑外,你用变量名Window,更令人困惑。

WindowCanvas 扩展而来,但您从未真正使用过它。调用 setPreferredSizesetMinimumSize 是因为 Window 从未真正添加到任何东西中,通常建议不要这样做,而是倾向于重写这些方法,以防止意外更改它们的值。

Game,你打电话给 Window ...这是一种奇怪的做事方式,因为 Game 并不是 [=117] 的真正责任=],恰恰相反。

就个人而言,我会从一个专门的入口点开始,其职责是加载和准备环境并显示第一个屏幕,例如...

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Game());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

确保 manufest.mf 使其 Main-Class 属性 指向此 class.

我也会更新 Game,因此它会覆盖 getPreferredSize。我还会看一下您的 startstop 方法。

public synchronized void start() {
    thread = new Thread(this);
    thread.start();
    running = true;
}

如果调用两次会怎样?在创建新

之前,您应该检查 Thread 的状态
public synchronized void stop() {
    try {
        thread.join();
        running = false;
    } catch(Exception e) {
        e.printStackTrace();
    }
}

这不会做任何事情,因为 join 正在阻塞,所以 running 的状态永远不会改变。

此外,由于 Java 的内存模型,您可能会发现即使在调用 join 之前将 running 设置为 false 也不起作用。相反,您应该使用 atomic variable(并且使用 Boolean 可能会导致一系列其他问题,因为您引用的是内存位置而不是实际值)

我建议通读 Concurrency

import java.awt.Canvas;
import java.awt.Dimension;
import java.util.concurrent.atomic.AtomicBoolean;

public class Game extends Canvas implements Runnable {

    public static final long serialVersionUID = 1L;

    private Thread thread;
    private AtomicBoolean running = new AtomicBoolean(false);

    public Game() {
    }

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

    public synchronized void start() {
        running.set(true);
        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }
    }

    public synchronized void stop() {
        running.set(false);
        if (thread == null) {
            return;
        }
        try {
            thread.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void run() {
    }
}

the IDE I use (NetBeans) will not let me run the java file

从 "Projects" 选项卡,select Main class/Java 文件,右键单击 select "Run File"

或者,在编辑器中打开 Main(和 selected),按 Shift+F6

接下来,确保 com.hypopixel.Main 设置为项目 "main class"

  • 右键单击 "Projects" 选项卡中的项目节点,然后 select "Properties"

  • Select "Run" 从右侧的选项中,确认 "Main Class" 设置为 com.hypopixel.Main,如果没有,请单击 浏览。 .. 和 select 它来自可用的选项