Java 图形对象未显示到屏幕

Java 图形对象未显示到屏幕,java,swing,enums,jpanel,Java,Swing,Enums,Jpanel,所以这个问题的答案可能是显而易见的,但我就是看不到。为什么我的图形对象没有显示我告诉它的内容?我相当肯定我很尊重Swing并发性之类的东西,但也许不是。以下是我的JPanel代码: package com.kraken.towerdefense.graphics; import com.kraken.towerdefense.TowerDefense; import com.kraken.towerdefense.listener.KeyHandler; import com.kraken.t

所以这个问题的答案可能是显而易见的,但我就是看不到。为什么我的图形对象没有显示我告诉它的内容?我相当肯定我很尊重Swing并发性之类的东西,但也许不是。以下是我的JPanel代码:

package com.kraken.towerdefense.graphics;

import com.kraken.towerdefense.TowerDefense;
import com.kraken.towerdefense.listener.KeyHandler;
import com.kraken.towerdefense.listener.MouseMotionHandler;
import com.kraken.towerdefense.scene.Scene;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;

public class Screen extends JPanel implements Runnable {

    Thread thread = new Thread(this);

    private int FPS = 0;

    public Scene scene;

    TowerDefense tD;

    private boolean running = false;

    public RoundRectangle2D.Float playGame, quitGame;
    public boolean playGameHighlighted, quitGameHighlighted;

    @Override
    public void run() {
        long lastFrame = System.currentTimeMillis();
        int frames = 0;

        running = true;

        while (running) {
            repaint();

            frames++;

            if (System.currentTimeMillis() - 1000 >= lastFrame) {
                FPS = frames;
                frames = 0;

                lastFrame = System.currentTimeMillis();
            }
        }

        System.exit(0);
    }

    public Screen(TowerDefense tD) {
        thread.start();

        addKeyListener(new KeyHandler(this));
        addMouseMotionListener(new MouseMotionHandler(this));

        this.tD = tD;
        scene = Scene.MENU;
    }

    @Override
    public void paintComponent(Graphics g2) {
        super.paintComponent(g2);

        playGame = new RoundRectangle2D.Float((getWidth() / 2) - 200, (getHeight() / 2) - 100, 400, 100, 10, 10);
        quitGame = new RoundRectangle2D.Float((getWidth() / 2) - 200, (getHeight() / 2) + 20, 400, 100, 10, 10);

        Graphics2D g = (Graphics2D) g2.create();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        g.clearRect(0, 0, getWidth(), getHeight());

        g.drawString("FPS: " + FPS, 10, 10);

        if (scene == Scene.MENU) {
            if (playGameHighlighted) {
                g.setColor(new Color(255, 152, 56));
            } else {
                g.setColor(new Color(4, 47, 61));
            }
            g.fill(playGame);

            if (quitGameHighlighted) {
                g.setColor(new Color(255, 152, 56));
            } else {
                g.setColor(new Color(4, 47, 61));
            }
            g.fill(quitGame);

            g.setColor(Color.WHITE);
            g.setFont(new Font("Gisha", Font.PLAIN, 20));
            g.drawString("Play", (getWidth() / 2) - (g.getFontMetrics().stringWidth("Play") / 2), (getHeight() / 2) - 45);
            g.drawString("Quit", (getWidth() / 2) - (g.getFontMetrics().stringWidth("Quit") / 2), (getHeight() / 2) + 75);
        }
    }

    public class KeyTyped {
        public void keyESC() {
            running = false;
        }
    }
}
这是我的场景枚举:

package com.kraken.towerdefense.scene;

public enum Scene {
    MENU,
    GAME
}
我很确定我不需要提供JFrame代码,但是如果必要的话我会提供。如果您能为我的代码中的问题提供任何其他解决方案,我们将不胜感激。谢谢

编辑1

这是我的MouseMotionListener类:

package com.kraken.towerdefense.listener;

import com.kraken.towerdefense.graphics.Screen;

import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

public class MouseMotionHandler implements MouseMotionListener {

    Screen screen;

    public MouseMotionHandler(Screen screen) {
        this.screen = screen;
    }

    @Override
    public void mouseDragged(MouseEvent e) {

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        if (screen.playGame.contains(e.getPoint())) {
            screen.playGameHighlighted = true;
        } else {
            screen.playGameHighlighted = false;
        }

        if (screen.quitGame.contains(e.getPoint())) {
            screen.quitGameHighlighted = true;
        } else {
            screen.playGameHighlighted = false;
        }
    }
}
以下是我的JFrame代码:

package com.kraken.towerdefense;

import com.kraken.towerdefense.graphics.Screen;

import javax.swing.*;

public class TowerDefense extends JFrame {

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

    public TowerDefense() {
        setExtendedState(MAXIMIZED_BOTH);
        setUndecorated(true);
        setTitle("Tower Defense");

        setDefaultCloseOperation(EXIT_ON_CLOSE);

        setResizable(false);

        Screen screen = new Screen(this);
        this.add(screen);

        setVisible(true);
    }

}
这是我的KeyListener代码:

package com.kraken.towerdefense.listener;

import com.kraken.towerdefense.graphics.Screen;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyHandler implements KeyListener {

    private Screen screen;
    private Screen.KeyTyped keyTyped;

    public KeyHandler(Screen screen) {
        this.screen = screen;

        keyTyped = screen.new KeyTyped();
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == 27) {
            keyTyped.keyESC();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }
}

所以这些都是我的类,我希望这对我有所帮助。所以,我删掉了你的代码,使其运行,并且能够显示

这表明你所描述的问题是其他地方的问题

对我来说

g.clearRect(0, 0, tD.getWidth(), tD.getHeight());
看起来很可疑,因为您依赖的是
TowerDefense
属性,而您应该依赖组件自身的宽度/高度属性(除了
clearRect
在这种情况下实际上不需要)

这进一步让我怀疑,您实际上没有将
屏幕
组件添加到任何可显示的内容中

另一个可能的问题是您正在使用适当的布局管理器,但是由于您的
Screen
类没有提供任何
preferredSize
提示,因此这将是一个您没有演示的附加问题

根据对原始问题的更改进行更新

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import static java.awt.Frame.MAXIMIZED_BOTH;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import javafx.scene.Scene;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;

public class TowerDefense extends JFrame {

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

    public TowerDefense() {
//        setExtendedState(MAXIMIZED_BOTH);
//        setUndecorated(true);
        setTitle("Tower Defense");

        setDefaultCloseOperation(EXIT_ON_CLOSE);

//        setResizable(false);

        Screen screen = new Screen(this);
        this.add(screen);
        pack();

        setVisible(true);
    }

    public enum Scene {
        MENU,
        GAME
    }

    public class Screen extends JPanel implements Runnable {

        Thread thread = new Thread(this);

        private int FPS = 0;

        public Scene scene;

        TowerDefense tD;

        private boolean running = false;

        public RoundRectangle2D.Float playGame, quitGame;
        public boolean playGameHighlighted, quitGameHighlighted;

        @Override
        public void run() {
//            long lastFrame = System.currentTimeMillis();
//            int frames = 0;
//
//            running = true;
//
//            while (running) {
//                repaint();
//
//                frames++;
//
//                if (System.currentTimeMillis() - 1000 >= lastFrame) {
//                    FPS = frames;
//                    frames = 0;
//
//                    lastFrame = System.currentTimeMillis();
//                }
//            }
//
//            System.exit(0);
        }

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

        public Screen(TowerDefense tD) {
            thread.start();

            addKeyListener(new KeyHandler(this));
            addMouseMotionListener(
                    new MouseAdapter() {

                @Override
                public void mouseMoved(MouseEvent e) {
                    playGameHighlighted = playGame.contains(e.getPoint());
                    quitGameHighlighted = quitGame.contains(e.getPoint());
                    repaint();
                }
            });

            this.tD = tD;
            scene = Scene.MENU;

        }

        @Override
        public void paintComponent(Graphics g2) {
            super.paintComponent(g2);

            playGame = new RoundRectangle2D.Float((getWidth() / 2) - 200, (getHeight() / 2) - 100, 400, 100, 10, 10);
            quitGame = new RoundRectangle2D.Float((getWidth() / 2) - 200, (getHeight() / 2) + 20, 400, 100, 10, 10);

            Graphics2D g = (Graphics2D) g2.create();
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            g.clearRect(0, 0, getWidth(), getHeight());

            g.drawString("FPS: " + FPS, 10, 10);

            if (scene == Scene.MENU) {
                if (playGameHighlighted) {
                    g.setColor(new Color(255, 152, 56));
                } else {
                    g.setColor(new Color(4, 47, 61));
                }
                g.draw(playGame);

                if (quitGameHighlighted) {
                    g.setColor(new Color(255, 152, 56));
                } else {
                    g.setColor(new Color(4, 47, 61));
                }
                g.draw(quitGame);

                g.setColor(Color.WHITE);
                g.setFont(new Font("Gisha", Font.PLAIN, 20));
                g.drawString("Play", (getWidth() / 2) - (g.getFontMetrics().stringWidth("Play") / 2), (getHeight() / 2) - 45);
                g.drawString("Quit", (getWidth() / 2) - (g.getFontMetrics().stringWidth("Quit") / 2), (getHeight() / 2) + 75);
            }
        }

        public class KeyTyped {

            public void keyESC() {
                running = false;
            }
        }

    }

    public class KeyHandler implements KeyListener {

        private Screen screen;
        private Screen.KeyTyped keyTyped;

        public KeyHandler(Screen screen) {
            this.screen = screen;

            keyTyped = screen.new KeyTyped();
        }

        @Override
        public void keyTyped(KeyEvent e) {

        }

        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == 27) {
                keyTyped.keyESC();
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {

        }

    }
}

所以,我删掉了你的代码,让它运行,并能够显示

这表明你所描述的问题是其他地方的问题

对我来说

g.clearRect(0, 0, tD.getWidth(), tD.getHeight());
看起来很可疑,因为您依赖的是
TowerDefense
属性,而您应该依赖组件自身的宽度/高度属性(除了
clearRect
在这种情况下实际上不需要)

这进一步让我怀疑,您实际上没有将
屏幕
组件添加到任何可显示的内容中

另一个可能的问题是您正在使用适当的布局管理器,但是由于您的
Screen
类没有提供任何
preferredSize
提示,因此这将是一个您没有演示的附加问题

根据对原始问题的更改进行更新

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import static java.awt.Frame.MAXIMIZED_BOTH;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import javafx.scene.Scene;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JPanel;

public class TowerDefense extends JFrame {

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

    public TowerDefense() {
//        setExtendedState(MAXIMIZED_BOTH);
//        setUndecorated(true);
        setTitle("Tower Defense");

        setDefaultCloseOperation(EXIT_ON_CLOSE);

//        setResizable(false);

        Screen screen = new Screen(this);
        this.add(screen);
        pack();

        setVisible(true);
    }

    public enum Scene {
        MENU,
        GAME
    }

    public class Screen extends JPanel implements Runnable {

        Thread thread = new Thread(this);

        private int FPS = 0;

        public Scene scene;

        TowerDefense tD;

        private boolean running = false;

        public RoundRectangle2D.Float playGame, quitGame;
        public boolean playGameHighlighted, quitGameHighlighted;

        @Override
        public void run() {
//            long lastFrame = System.currentTimeMillis();
//            int frames = 0;
//
//            running = true;
//
//            while (running) {
//                repaint();
//
//                frames++;
//
//                if (System.currentTimeMillis() - 1000 >= lastFrame) {
//                    FPS = frames;
//                    frames = 0;
//
//                    lastFrame = System.currentTimeMillis();
//                }
//            }
//
//            System.exit(0);
        }

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

        public Screen(TowerDefense tD) {
            thread.start();

            addKeyListener(new KeyHandler(this));
            addMouseMotionListener(
                    new MouseAdapter() {

                @Override
                public void mouseMoved(MouseEvent e) {
                    playGameHighlighted = playGame.contains(e.getPoint());
                    quitGameHighlighted = quitGame.contains(e.getPoint());
                    repaint();
                }
            });

            this.tD = tD;
            scene = Scene.MENU;

        }

        @Override
        public void paintComponent(Graphics g2) {
            super.paintComponent(g2);

            playGame = new RoundRectangle2D.Float((getWidth() / 2) - 200, (getHeight() / 2) - 100, 400, 100, 10, 10);
            quitGame = new RoundRectangle2D.Float((getWidth() / 2) - 200, (getHeight() / 2) + 20, 400, 100, 10, 10);

            Graphics2D g = (Graphics2D) g2.create();
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

            g.clearRect(0, 0, getWidth(), getHeight());

            g.drawString("FPS: " + FPS, 10, 10);

            if (scene == Scene.MENU) {
                if (playGameHighlighted) {
                    g.setColor(new Color(255, 152, 56));
                } else {
                    g.setColor(new Color(4, 47, 61));
                }
                g.draw(playGame);

                if (quitGameHighlighted) {
                    g.setColor(new Color(255, 152, 56));
                } else {
                    g.setColor(new Color(4, 47, 61));
                }
                g.draw(quitGame);

                g.setColor(Color.WHITE);
                g.setFont(new Font("Gisha", Font.PLAIN, 20));
                g.drawString("Play", (getWidth() / 2) - (g.getFontMetrics().stringWidth("Play") / 2), (getHeight() / 2) - 45);
                g.drawString("Quit", (getWidth() / 2) - (g.getFontMetrics().stringWidth("Quit") / 2), (getHeight() / 2) + 75);
            }
        }

        public class KeyTyped {

            public void keyESC() {
                running = false;
            }
        }

    }

    public class KeyHandler implements KeyListener {

        private Screen screen;
        private Screen.KeyTyped keyTyped;

        public KeyHandler(Screen screen) {
            this.screen = screen;

            keyTyped = screen.new KeyTyped();
        }

        @Override
        public void keyTyped(KeyEvent e) {

        }

        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == 27) {
                keyTyped.keyESC();
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {

        }

    }
}