Как мне исправить, что мой JFrame не открывается, компилятор не выдает ошибок, как мне это исправить?

[Технически не [дубликат]] Я знаю, что это случалось раньше (есть ошибка, из-за которой мой JFrame не открывается при компиляции моей игры, как мне исправить это [дубликат]), и MadProgrammer ответил: «Game.main не ничего не делать. Поскольку это основная точка входа для программы, ей нужно что-то сделать, прежде чем что-то произойдет», но теперь, когда Game.main что-то делает, я не вижу ответа.

Я пробовал перекомпилировать и проверять на ошибки, ни одной, кто-то даже заставил это работать. Как я могу это исправить

Игра.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();
    }
}

Окно.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 откроется (потому что кто-то другой смог его получить), но он не открылся.

У меня открывается, правда в минимальном размере (только заголовок с некоторыми иконками). А минимальный размер связан с тем, что вы устанавливаете минимальный и предпочтительный размер в экземпляре Window, но никогда не добавляете его в JFrame. В JFrame вы добавляете экземпляр Game, но не устанавливаете для него минимальный и предпочтительный размер.

Thomas Kläger 31.01.2019 19:58
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
38
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, есть ряд вещей, которые «выключены»

Начиная с...

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... это какой-то странный способ делать что-то, так как создание окна на самом деле не входит в обязанности Games, скорее , это наоборот.

Лично я бы начал с выделенной точки входа, в обязанности которой входит, например, загрузка и подготовка среды и показ первого экрана...

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() {
    }
}

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

На вкладке «Проекты» выберите класс Main/Java-файл, щелкните правой кнопкой мыши и выберите «Запустить файл».

Run file in netbeans

Как вариант, при открытом в редакторе (и выбранном) Main нажмите Shift+F6

Далее убедитесь, что com.hypopixel.Main установлен в качестве проектов "основной класс"

  • Щелкните правой кнопкой мыши узел проекта на вкладке «Проекты» и выберите «Свойства».

Properties

  • Выберите «Выполнить» из вариантов справа, убедитесь, что «Основной класс» установлен как com.hypopixel.Main, если нет, нажмите Browse... и выберите его из доступных вариантов.

Options

спасибо, я не понимал, сколько действительно не работает! Может быть, код, который я использовал, устарел, вот откуда я его взял: «youtube.com/watch?v=1gir2R7G9ws&t=40s», устарел?

Katty the NB cat. 31.01.2019 21:13

@CyleLinin Одна из повторяющихся проблем, с которыми я сталкиваюсь, заключается в том, что учебные пособия на YouTube, как правило, ужасны, по моему опыту, они не предназначены для обучения «хорошей» практике, а показывают, «как» достичь определенной цели. Например, в приведенном выше коде я бы сказал, что Game не должен отвечать за управление потоком, это часть ответственности основного движка, Game действительно должен быть сосредоточен только на поверхности рендеринга, но это я. И, да, мы получаем много вопросов «Я слежу за видео на YouTube...», на которые, как правило, отвечают «не следи за ним» ;)

MadProgrammer 31.01.2019 21:40

Подскажите, пожалуйста, как найти туториал по созданию 3D-игры? также код, который вы дали, не создает JFrame.

Katty the NB cat. 31.01.2019 21:48

@CyleLinin «Кроме того, указанный вами код не создает JFrame» - Да, я запустил его перед публикацией, вы ДОЛЖНЫ запустить класс Main (он должен быть основной точкой входа). "Подскажите, пожалуйста, как найти туториал по созданию 3D-игры" — сомневаюсь, что он есть. Вам нужно будет использовать ряд источников для создания решения. Это также будет зависеть от того, какой 3D-движок вы пытаетесь использовать. Я мог бы порекомендовать потратить время на просмотр JavaFX, так как он имеет лучшую встроенную поддержку для этого.

MadProgrammer 31.01.2019 21:59

Файл манифеста настроен с учетом «Main-Class: Main» в Main.java, и когда я скомпилирую его для получения T.jar, он не откроет JFrame с пометкой «Тестирование», как указано в коде.

Katty the NB cat. 31.01.2019 22:08

@CyleLinin Мое личное предложение — сосредоточиться на решении «а» проблемы, а затем выяснить, как эта часть вписывается в общую головоломку. «Основные циклы» хорошо задокументированы и обсуждены, обновление состояния, визуализация состояния, подсчет кадров в секунду, повтор; широко обсуждается управление сущностями. Я бы попробовал просмотреть доступные движки с открытым исходным кодом, они дадут вам много полезной информации и идей, возможно, сосредоточусь на использовании одного или двух и посмотрим, в чем различия и как вы можете их использовать.

MadProgrammer 31.01.2019 22:12
«он не откроет JFrame» - Значит, что-то еще не так - поместите оператор System.out.println в метод main, посмотрите, был ли вообще запущен Main. Main находится в упаковке? В Java есть проблемы с классами, помещенными в пакет по умолчанию.
MadProgrammer 31.01.2019 22:21

Нет, ничего не делает. Нет ошибок, нет ошибок IDE, ничего, и да, это в пакете, имя пакета: "com.hypopixel"

Katty the NB cat. 31.01.2019 22:57

Хорошо, вы можете запустить его из IDE? Запустить класс напрямую (из IDE)? Main-Class: Main должен больше походить на Main-Class: com.hypopixel.Main, исходя из имеющейся информации. На данный момент все, что у вас есть, это неправильная конфигурация - поэтому я связал руководство работа с файлом манифеста выше.

MadProgrammer 31.01.2019 23:05

IDE, которую я использую (NetBeans), не позволяет мне запускать java-файл. также я не знаю, поможет ли это, но когда я компилирую, он генерирует 3 файла .class: Main.class, Main$1.class и Game.class.

Katty the NB cat. 01.02.2019 00:16

В навигаторе проекта выберите класс Main (java-файл), щелкните правой кнопкой мыши и выберите «Запустить файл» или, пока файл открыт в редакторе, нажмите [Shift]+[F6]

MadProgrammer 01.02.2019 00:18

всякий раз, когда я запускаю Main (в NetBeans), он говорит мне следующее: Исключение в потоке "AWT-EventQueue-0" java.lang.RuntimeException: Некомпилируемый исходный код - не удается найти символ: class Game at com.hypopixel.Main$1.run (Main.java:20) в java.awt.event.InvocationEvent.dispatch(InvocationEvent.java‌​:311) в java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758) в java.awt.EventQueue.access$500( EventQueue.java:97) в java.awt.EventQueue$3.run(EventQueue.java:709) в java.awt.EventQueue$3.run(EventQueue.java:703) в java.security.AccessController.doPrivileged(собственный метод) а

Katty the NB cat. 01.02.2019 01:06

Сначала выполните «Очистить и построить», затем запустите класс Main.

MadProgrammer 01.02.2019 01:21

как мне ЭТО исправить?

Katty the NB cat. 03.02.2019 22:18

Оба Main и Game в одном проекте? У вас есть они в правильных упаковках и правильный ли импорт. Когда вы компилируете код, вы получаете сообщения об ошибках?

MadProgrammer 03.02.2019 22:21

@CyleLinin Кажется, вам нужен хороший учебник по Netbeans.

MadProgrammer 03.02.2019 22:29

Другие вопросы по теме