将图像添加到JFrames的问题

时间:2013-04-07 17:40:59

标签: java image swing embedded-resource imageicon

我一直在尝试将图像加载到jframe中。我不知道为什么这段代码不起作用。我尝试过使用jpanel和jlabels,以及其他加载图像的方法,但这些方法也不起作用。我认为因为这与我设置的JFrame有关。我想远离jpanels和jlabels,因为至少据我所知,它们无法扩展。如果有人有添加图像的解决方案,请告诉我。这是代码:

import java.awt.Canvas;
import javax.swing.JFrame;
import java.awt.*;
import javax.swing.ImageIcon;
import java.awt.event.KeyEvent;
import java.awt.Graphics;


public class Base extends Canvas implements Runnable {

    private static final long serialVersionUID = 001;
    private Image rock1;
    private Image rock2;
    private Image wood1;

    private Thread thread;
    private boolean running = (false);
    private boolean paused = (false);

    int x = 0;
    int y = 0;
    int z = 512;


    private void start() {
        if (running)
            return;
        running = true;
        thread = new Thread(this);
    }

    public void run(){}

    public Base(){}

    public static void main(String[] Args) {
        Base game = new Base();
        JFrame frame = new JFrame();
        frame.add(game);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);
        frame.setTitle("Game");

        System.out.println("Running...");

        game.start();
        game.loadPics();

    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_A) {
            x = x - 5;
        }
        if (e.getKeyCode() == KeyEvent.VK_D) {
            x = x + 5;
        }
        if (e.getKeyCode() == KeyEvent.VK_SPACE) {
            y = y - 5;
        }
        if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
            y = y + 5;
        }
        if (e.getKeyCode() == KeyEvent.VK_W) {
            z = z + 5;
        }
        if (e.getKeyCode() == KeyEvent.VK_S) {
            z = z - 5;
        }
        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            paused = (true);
        }
    }

    public void loadPics(){

        rock1 = new ImageIcon("C\\...\\rock1.png").getImage();
        rock2 = new ImageIcon("C\\...\\rock2.png").getImage();
        wood1 = new ImageIcon("C\\....\\wood1.png").getImage();

        repaint();
    }

    public void paint(Graphics g){
        while(paused = false){
        g.drawImage(rock1, x, y, z, z, this);
        g.drawImage(rock2, x + 512, y, z, z, this);
        g.drawImage(wood1, x, y + 512, z, z, this);

        try{
            Thread.sleep(16);
        }catch(Exception e){}
        g.dispose();
        }

    }
}

同样,我认为问题在于我的JFrame,但我不能太确定,因为我不是最有经验的java程序员。无论如何,如果你知道解决方案或改变什么,请帮助。

2 个答案:

答案 0 :(得分:5)

本声明

while (paused = false){
当您使用分配表达式时,

将始终评估为false,因此不会发生对drawImage的后续调用。您可能打算使用==运算符来比较原始boolean值:

while (paused == false){
  • 请勿使用paint,使用来自子类paintComponent的{​​{1}}
  • 请勿在任何 JComponent方法中致电Thread.sleep。 Swing有自己的concurrency mechanisms。您可以使用Swing Timer定期执行图形更新,而不是在此处调用paint

除此之外,AWT是重量级组件,使用轻量级Swing组件无法很好地渲染。对于Swing应用程序,请使用Key Bindings而不是Thread.sleep

答案 1 :(得分:0)

我有很多这样的反复出现的问题,并且已经找到了解决这个问题的方法。 首先,您的public class Base需要双重缓冲。将方法paint(Graphics g)更改为paintComponent(Graphics g)。添加新的paint(Graphics g)方法并添加以下代码:

 public void paint(Graphics g) {
    // TODO Auto-generated method stub (IGNORE!!!)

    dbi = createImage (getWidth(),getHeight());
    dbg = dbi.getGraphics();
    paintComponent(dbg);
    g.drawImage(dbi , 0 , 0 , this);

 }

public class Base的顶部,添加以下变量:

 private Image dbi;
 private Graphics dbg;

这会自动调用paintComponent(Graphics g)并完成第一步。

接下来,删除paintComponent()中的try语句并将其写入run()

@Override
public void run() {

    try {

        while (true) {

            Thread.sleep(5); // we want this so the computer doesn't go too fast

        }

    } catch (Exception e) { // Never have an empty catch statement

        System.out.println ("Error! stacktrace: ");
        e.printStackTrace();

    }

} 

@Override注释,或者不会重绘。

下一部分是批评: 在其他任何事情之前,将super.paint(g);放在paintComponent(Graphics g)的顶部 和repaint();在底部。

这应该已经解决了,但我发现了一些潜在的问题;

  • JFrame初始化

    public Base(){
    
        add(game);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 600);
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
        setTitle("Game");
    
        start();
        loadPics();
    
    }
    
    public static void main(String[] Args) { // Makes game smoother
    
        Base base = new Base ();
        Thread t = new Thread (base);
        t.start();
    
    }
    
  • 删除private void start(),因为这不会影响游戏。

  • 检查文件目录,因为它们可能不正确。 提示:C \不会削减它。这是C:\

希望它能够成功并且编码愉快!