Java中的ImageIO问题

时间:2013-01-01 01:00:48

标签: java image applet awt javax.imageio

我遇到的问题是我无法在JAVA中的Applet Viewer上看到我用ImageIO类引用的任何图片。我在网上接受了一个教程并且还没有收到作者的回复 - 他的页面上有类似的问题,他没有回答,所以我假设他正试图弄清楚自己。

这是我到目前为止所拥有的。

import java.applet.Applet;
import java.awt.Graphics;


public class SuperheroGame extends SuperHeroGameLoop{


/**
 * 
 */
private static final long serialVersionUID = 1L;

public void init () {
    setSize(320,240);
    Thread th = new Thread(this) ;
    th.start();
    offscreen = createImage(320,240);
    d = offscreen.getGraphics();
    addKeyListener(this);
}

public void paint (Graphics g) {
    d.clearRect(0, 0, 320, 240);
    d.drawImage(background, 0, 0, this);
    d.drawImage(w2, x,y, this);
    //d.drawImage(foreground, 0, 0, this);
    //g.drawImage(offscreen, 0, 0, this);

}

public void update(Graphics g) {
    paint(g);
}

}

以下是我的Tester类,其中大部分函数嵌套在代码中。

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;


public class SuperHeroGameLoop extends Applet implements Runnable, KeyListener {

/**
 * 
 */
private static final long serialVersionUID = 1L;
public int x,y;
public Image offscreen;
public Graphics d;
public boolean up, down, left, right;
public BufferedImage background, foreground, w1, w2, w3, w4;

public void run() {

    x = 100;
    y = 100;
    try {
        //background = ImageIO.read(new File ("background.png"));
        //foreground = ImageIO.read(new File ("foreground.png"));
        w1 = ImageIO.read(new File("red copy.png"));
        w2 = ImageIO.read(new File("red copy.png"));
        w3 = ImageIO.read(new File("red copy.png"));
        w4 = ImageIO.read(new File("red copy.png"));
    } catch (IOException e1) {

        e1.printStackTrace();
    }
    while(true) {
    if (left == true) {
        x-=2;
    }
    if (right == true) {
        x+=2;
    }
    if (up == true) {
        y-=2;
    }
    if (down == true) {
        y+=2;
    }

    repaint();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == 37) {
        left = true;
    }

    if (e.getKeyCode() == 39) {
        right = true;
    }

    if (e.getKeyCode() == 38) {
        up = true;
    }

    if (e.getKeyCode() == 40) {
        down = true;
    }
}
public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == 37) {
        left = false;
    }

    if (e.getKeyCode() == 39) {
        right = false;
    }

    if (e.getKeyCode() == 38) {
        up = false;
    }

    if (e.getKeyCode() == 40) {
        down = false;
    }
}
public void keyTyped(KeyEvent e) {

}

}

任何帮助或反馈将不胜感激。

2 个答案:

答案 0 :(得分:4)

  

..我的图像文件仅在我的计算机上,而不是从URL或网络上的任何内容远程读取。

当applet部署到万维网上的受众群体时,它应该如何工作?

当小程序从您的网站加载到我的电脑时,没有任何选项可以将 PC < / strong> (除非您的PC是服务器)。 applet的图片必须来自URL而不是File,并且除了受信任的applet之外,他们必须来自与applet位于同一网站的网址。

ImageIO.read(..)因流,文件或网址而超载,因此仍可用于加载图片。

要形成applet的URL,至少有3种方法。如果图像是:

  • 同一服务器上的松散资源。形成相对于文档库或代码库的URL。
  • archive属性中提到的Jar中(位于运行时类路径中)。使用:
URL urlToImage = this.getClass().getResource("/path/to/image.png");

进一步提示。

  1. 目前尚不完全清楚,但似乎SuperheroGameApplet的一个实例。这个千禧年使用Swing,因此应该扩展JApplet
  2. 但接下来我们遇到第二个问题,其中SuperheroGame实际上延伸SuperHeroGameLoop(颤抖)。在这一点上,我们认识到SuperHeroGameLoop应该在PanelJPanel中编码,而不是扩展Applet JApplet。一般原则是“在容器中进行自定义绘制,该容器本身可以添加到applet,框架,对话框或窗口,或布局中的约束,或选项卡或内部框架中。”。
  3. setSize(320,240);这在大多数GUI中都是不可取的,但在applet中更是如此。 applet的大小在HTML中设置,并且应该遵循该大小。
  4. Thread th = new Thread(this) ;要制作动画,请使用Swing Timer。以下消息是为Swing编写的,但同样适用于AWT AFAIU(毕竟,EDT本身是由AWT启动,使用和控制的线程)。
    不要阻止EDT(事件调度线程) - 当发生这种情况时,GUI将“冻结”。而不是调用Thread.sleep(n)为重复任务实现Swing Timer或为长时间运行的任务实现SwingWorker。有关详细信息,请参阅Concurrency in Swing
  5. addKeyListener(this);
    1. 为了获得更可靠的焦点,GUI可以自由浮动。为此,请将游戏置于框架(JFrame)中,然后使用Java Web Start从链接启动游戏。
    2. 对于基于Swing的GUI,请查看Key Bindings
  6. 这是5个以上的提示,我们刚刚到达init的末尾。这表明学习编写来自不同源代码的代码比导致该代码的代码更为理想。

答案 1 :(得分:3)

您正在使用applet - 它旨在在浏览器中运行并受到安全管理器的约束。安全管理器可能会阻止您进行本地磁盘i / o。

Trashgod和Philip指出了有关这一主题的有用文章。

然而,如果我们采取不同的策略......

AppletComponent,可以添加到JFrame的内容窗格中。您可以通过执行以下操作将您的applet转变为独立的应用程序(没有限制性的安全管理器)...

添加新课程:

public class SwingApp
{
  public static void main(String[] args)
  {
    final JFrame frame = new JFrame("Swing App");

    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        final SuperHeroGameLoop loop = new SuperHeroGameLoop();

        frame.getContentPane().add(loop);
        frame.setSize(320, 240);

        loop.init();

        frame.setVisible(true);
      }
    });
  }
}

(但是,我确实只是从内存中输入它而不通过编译器运行它 - 所以我为任何编译错误道歉)...

编译并将其作为独立应用程序运行。

另一种方法是完全抛弃 applet 方法,并使用JComponent s将其作为桌面Swing应用程序写入...