【问题标题】:Why are graphics not appearing in JFrame?为什么图形没有出现在 JFrame 中?
【发布时间】:2013-05-22 05:06:31
【问题描述】:

下面我在我的 Java 程序中包含了两个类(Launcher 和 Controls)。在这两个类中,他们创建了一个 JFrame,绘制了一个背景图像,并添加了文本行。我一遍又一遍地查看代码,但由于某种原因,背景图像和文本行没有出现在第二类(控件)中。谁能给我解释一下为什么会这样?

启动器类:

import hungerGames.Display;
import hungerGames.RunGame;
import hungerGames.input.InputHandler;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferStrategy;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class Launcher extends JFrame implements Runnable {
public static final long serialVersionUID = 1L;

protected JPanel window = new JPanel();

private int width = 800;
private int height = 450;
boolean running = false;
Thread thread;

public Launcher(int id) {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
        e.printStackTrace();
    }
    setUndecorated(true);
    setSize(new Dimension(width, height));
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setResizable(false);
    setVisible(true);
    window.setLayout(null);
    InputHandler input = new InputHandler();
    addKeyListener(input);
    addFocusListener(input);
    addMouseListener(input);
    addMouseMotionListener(input);
    startMenu();
}

public void updateFrame() {
    if (InputHandler.dragged) {
        Point p = getLocation();
        if (InputHandler.MouseDX != InputHandler.MousePX || InputHandler.MouseDX != InputHandler.MousePX) {
            setLocation(p.x + InputHandler.MouseDX - InputHandler.MousePX, p.y + InputHandler.MouseDY - InputHandler.MousePY);
        }
    }
}

public void startMenu() {
    running = true;
    thread = new Thread(this, "menu");
    thread.start();
}

public void stopMenu() {
    try {
        thread.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void run() {
    while (running) {
        try {
            renderMenu();
        } catch (IllegalStateException e) {
            System.out.println("Handled");
        }
        updateFrame();
    }
}

private void renderMenu() throws IllegalStateException {
    BufferStrategy bs = this.getBufferStrategy();
    if (bs == null) {
        createBufferStrategy(3);
        return;
    }
    Graphics g = bs.getDrawGraphics();
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, 800, 450);
    try {
        g.drawImage(ImageIO.read(Display.class.getResource("/main_menu.jpg")), 0, 0, 800, 450, null);
        if (InputHandler.mouseX >= 50 && InputHandler.mouseX <= 100 && InputHandler.mouseY >= 290 && InputHandler.mouseY <= 325) {
            g.drawImage(ImageIO.read(Launcher.class.getResource("/pin.png")), 10, 295, 30, 33, null);
            if (InputHandler.MouseButton == 1) {
                dispose();
                new RunGame();
            }
        }
        if (InputHandler.mouseX >= 50 && InputHandler.mouseX <= 320 && InputHandler.mouseY >= 390 && InputHandler.mouseY <= 425) {
            g.drawImage(ImageIO.read(Launcher.class.getResource("/pin.png")), 10, 395, 30, 33, null);
            if (InputHandler.MouseButton == 1) {
                dispose();
                new Controls();
            }
        }
        if (InputHandler.mouseX >= 400 && InputHandler.mouseX <= 490 && InputHandler.mouseY >= 290 && InputHandler.mouseY <= 325) {
            g.drawImage(ImageIO.read(Launcher.class.getResource("/pin.png")), 360, 295, 30, 33, null);
            if (InputHandler.MouseButton == 1) {
                dispose();
                new Credits();
            }
        }
        if (InputHandler.mouseX >= 400 && InputHandler.mouseX <= 440 && InputHandler.mouseY >= 390 && InputHandler.mouseY <= 425) {
            g.drawImage(ImageIO.read(Launcher.class.getResource("/pin.png")), 360, 395, 30, 33, null);
            if (InputHandler.MouseButton == 1) {
                System.exit(0);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    g.setColor(Color.WHITE);
    g.setFont(new Font("Agency FB", 0, 30));
    g.drawString("By Lawrence Zhao", 210, 275);
    g.setFont(new Font("Agency FB", 0, 40));
    g.drawString("Play", 50, 325);
    g.drawString("Controls and Options", 50, 425);
    g.drawString("Credits", 400, 325);
    g.drawString("Exit", 400, 425);
    g.dispose();
    bs.show();
}
}

控件类:

import hungerGames.Display;
import hungerGames.input.InputHandler;

import java.awt.Choice;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferStrategy;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class Controls extends JFrame{
public static final long serialVersionUID = 1L;

protected JPanel window = new JPanel();

private int width = 720;
private int height = 450;
private Rectangle rResolution;
private Choice resolution = new Choice();

public Controls() {
    try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
        e.printStackTrace();
    }
    setUndecorated(true);
    setSize(new Dimension(width, height));
    setLocationRelativeTo(null);
    setResizable(false);
    setVisible(true);
    window.setLayout(null);
    InputHandler input = new InputHandler();
    addKeyListener(input);
    addFocusListener(input);
    addMouseListener(input);
    addMouseMotionListener(input);

    renderControls();
    drawButtons();
    stopMenuThread();
}

private void stopMenuThread() {
    Display.getLauncherInstance().stopMenu();
}

private void drawButtons() {

    rResolution = new Rectangle(50,100, 100, 25);
    resolution.setBounds(rResolution);
    resolution.add("640, 400");
    resolution.add("800, 600");
    resolution.add("1024, 768");
    resolution.select(1);
    add(resolution);
}

private void renderControls() throws IllegalStateException {
    BufferStrategy bs = this.getBufferStrategy();
    if (bs == null) {
        createBufferStrategy(3);
        return;
    }
    Graphics g = bs.getDrawGraphics();
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, 720, 450);
    try {
        g.drawImage(ImageIO.read(Display.class.getResource("/controls.jpg")),0, 0, 720, 450, null);
        if (InputHandler.mouseX >= 360 && InputHandler.mouseX <= 400 && InputHandler.mouseY >=270 && InputHandler.mouseY <=305) {
            g.drawImage(ImageIO.read(Controls.class.getResource("/pin.png")),360,270, 30, 33, null);
            if (InputHandler.MouseButton == 1) {
                Display.selection = resolution.getSelectedIndex();
                dispose();
                new Launcher(0);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    g.setColor(Color.WHITE);
    g.setFont(new Font("Agency FB", 0, 40));
    g.drawString("Exit", 400, 300);
    g.dispose();
    bs.show();
}

}

【问题讨论】:

    标签: java graphics jframe


    【解决方案1】:

    很明显,您不了解缓冲策略的工作原理。

    我建议您阅读Double Buffering 以获取一些线索。

    (ps,我对这方面的 API 也没有太多经验,但我只需阅读上面链接的 tut 就可以让你的代码工作)

    更新

    对我来说似乎工作得很好......

    一些笔记。

    • 预加载您的图像,否则您将浪费时间进行双重缓冲,因为 IO 会减慢您的速度。
    • 确保您的图片存在并开始正确加载

    .

    public class BadPaint03 {
    
        public static void main(String[] args) {
            new BadPaint03();
        }
    
        public BadPaint03() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    Controls frame = new Controls();
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setVisible(true);
                }
            });
        }
    
        public class Controls extends JFrame {
    
            private int width = 720;
            private int height = 450;
            private Rectangle rResolution;
            protected JPanel window = new JPanel();
            private BufferedImage background;
    
            public Controls() {
    
                try {
                    background = ImageIO.read(new File("/path/to/your/image"));
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                setUndecorated(true);
                setSize(new Dimension(width, height));
                setLocationRelativeTo(null);
                setResizable(false);
                setVisible(true);
                window.setLayout(null);
    
                new Thread(new Runnable() {
                    @Override
                    public void run() {
    
                        while (true) {
    
                            renderControls();
                            try {
                                Thread.sleep(1000 / 24);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(BadPaint03.class.getName()).log(Level.SEVERE, null, ex);
                            }
    
                        }
    
                    }
                }).start();
    
            }
    
            private void renderControls() throws IllegalStateException {
                BufferStrategy bs = this.getBufferStrategy();
                if (bs == null) {
                    createBufferStrategy(3);
                    return;
                }
                Graphics g = bs.getDrawGraphics();
                g.setColor(Color.BLACK);
                g.fillRect(0, 0, 720, 450);
    
                if (background != null) {
    
                    int x = (720 - background.getWidth()) / 2;
                    int y = (450 - background.getHeight()) / 2;
                    g.drawImage(background, x, y, null);
    
                }
    
                g.setColor(Color.WHITE);
                g.setFont(new Font("Agency FB", 0, 40));
                g.drawString("Exit", 400, 300);
                g.dispose();
                bs.show();
            }
        }
    }
    

    【讨论】:

    • 我查看了链接,我相信我几乎完成了示例 2 中所做的工作。我在程序的早期有类似的代码,它可以工作,但在这里,背景图像不会由于某种原因没有出现。我添加了之前的代码,以防大家想看。
    猜你喜欢
    • 2012-10-20
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 2015-04-13
    • 2021-02-23
    相关资源
    最近更新 更多