Как исправить то, что мой JFrame не открывается, компилятор не выдает ошибок, как мне это исправить? - PullRequest
0 голосов
/ 31 января 2019

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

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

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 является тем же

Iожидал, что JFrame откроется (потому что кто-то другой смог его получить), и он не откроется.

1 Ответ

0 голосов
/ 31 января 2019

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

Начиная с ...

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, щелкните правой кнопкой мыши и выберите «Выполнить файл»

Run file in netbeans

В качестве альтернативы,при Main, открытом в редакторе (и выбранном), нажмите Shift + F6

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

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

Properties

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

Options

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...