java - 图形对象未显示在屏幕上

标签 java swing enums jpanel

所以这个问题的答案可能是完全显而易见的,但我就是看不到。为什么我的 Graphics 对象没有显示我告诉它的内容?我相当确定我尊重 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) {

    }
}

以上就是我的全部类(class),希望对您有所帮助

最佳答案

所以,我删除了你的代码以使其运行并能够显示...

Display

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class GraphicsTest {

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

    public GraphicsTest() {
        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 Screen());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.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;

        private boolean running = false;

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

            running = true;
            scene = Scene.MENU;

            while (running) {
                repaint();

                frames++;

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

                    lastFrame = System.currentTimeMillis();
                }
            }

            System.exit(0);
        }

        public Screen() {
            thread.start();
        }

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

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

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

            if (scene == Scene.MENU) {
                g.setColor(Color.BLACK);

                g.fillRoundRect((getWidth() / 2) - 100, (getHeight() / 2) - 50, 200, 100, 25, 25);
            }
        }

    }
}

这表明您所描述的问题是在其他地方。

对我来说这个;

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

看起来很可疑,因为当您应该依赖组件自己的宽度/高度属性时,您却依赖于 TowerDefense 属性(除了 clearRect 实际上不需要在此背景下)。

这进一步让我怀疑您实际上并未将 Screen 组件添加到任何可显示的内容

另一个可能的问题是您正在使用适当的布局管理器,但由于您的 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) {

        }

    }
}

关于java - 图形对象未显示在屏幕上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33965663/

相关文章:

java - 我应该将枚举作为参数传递还是传递其文字值

java - Jackson 中的自定义 JSON 数组反序列化

java - 我需要在java中制作一个有两个选择的下拉框

java - 如何在另一个 JPanel 之上创建 JPanel 或任何 JComponent 作为覆盖层或上层

Java JFormattedTextfield 时间格式化

asp.net - 如何在 Javascript 中创建常量文件?

java - Apache POI Excel 工作表 : resize a picture while keeping its ratio

java - iText - 在所有元素之上插入覆盖文本

java - 模型更新时更新 JTree 中的选择路径

c++ - 我应该使用基类还是子类来访问基类中定义的枚举值/常量?