Итак, есть ряд вещей, которые "выключены"
Начиная с ...
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();
}
Помимо того, что уже существует класс с именем Window
вjava.awt
, что сбивает с толку, вы используете имя переменной Window
, что более запутанно.
Window
простирается от Canvas
, но вы на самом деле никогда не используете его.Вызов setPreferredSize
и setMinimumSize
, потому что Window
фактически никогда ни к чему не добавляется, и обычно рекомендуется не делать этого, вместо этого предпочитая переопределять эти методы, чтобы предотвратить случайное изменение их значений.
С Game
, вы звоните Window
... это своего рода странный способ делать вещи, так как на самом деле не Game
ответственность за создание окна, скорее, это наоборот.
Лично я бы начал с выделенной точки входа, в обязанности которой входит загрузка и подготовка среды, и показывал первый экран, например ...
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
указывает на этот класс.
Я бы также обновил Game
, поэтому он переопределяет getPreferredSize
.Я бы также взглянул на ваши start
и stop
методы.
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 вы можете обнаружить, что даже установка running
в false
перед вызовом join
не работает.Вместо этого вы должны использовать атомарную переменную (и использование Boolean
, вероятно, вызовет кучу других проблем, так как вы ссылаетесь на местоположение в памяти, а не на фактическое значение)
Я бы порекомендовал прочитать Параллелизм
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() {
}
}
Используемая мной среда IDE (NetBeans) не позволит мне запустить файл Java
На вкладке «Проекты» выберите класс Main
/ файл Java, щелкните правой кнопкой мыши и выберите «Выполнить файл»
В качестве альтернативы,при Main
, открытом в редакторе (и выбранном), нажмите Shift + F6
Далее, убедитесь, что com.hypopixel.Main
установлен в качестве основного класса проектов"
- Щелкните правой кнопкой мыши узел проекта на вкладке" Проекты "и выберите" Свойства "
- Выберите «Выполнить» из опций внизу справа, убедитесь, что «Основной класс» установлен как
com.hypopixel.Main
, если нет, нажмите Обзор ... и выберите его из доступныхопции