2012-06-24 76 views
3

好吧,所以我想知道是否有人能告诉我我错在哪里。将JApplet嵌入到JFrame中

我有一个JApplet叫做Game,它运行良好,如果我使用AppletViewer和一个名为GUI的JFrame在JApplet中运行JApplet。以下是两者的代码:

PS。我摆脱了Game的大部分代码,使它更小,现在只是基本的。

Game.java:

package com.ion.brickdodge; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Image; 

import javax.swing.JApplet; 


public class Game extends JApplet implements Runnable{ 

private static final long serialVersionUID = 1L; 
Image man1; 
Image man2; 
Image cman; 
int WIDTH = 250; 
int HEIGHT = 350; 
int lives = 3; 
int spx = WIDTH/2; 
int score = 0; 

Image dbImage; 
Graphics dbg; 

public void init() { 
    setSize (WIDTH, HEIGHT); 
    setFocusable(true); 
    setBackground(Color.LIGHT_GRAY); 

    man1 = getImage(getCodeBase(), "res/man1.png"); 
    man2 = getImage(getCodeBase(), "res/man2.png"); 

    cman = man1; 

} 

public void start() { 
    Thread th = new Thread(this); 
    th.start(); 
} 

public void run() { 
    Thread.currentThread().setPriority(Thread.MIN_PRIORITY); 
    while(true){ 
     repaint(); 

     try { 
      Thread.sleep(10); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 

     Thread.currentThread().setPriority(Thread.MAX_PRIORITY); 
    } 
} 

public void paint(Graphics g) { 

    g.drawImage(cman, spx, 320, this); 
    g.setColor(Color.BLACK); 
    g.drawString("Score: " + score, 5, 10); 
    g.drawString("Lives: " + lives, 5, 25); 

} 

public void update(Graphics g){ 
    if (dbImage == null) 
    { 
     dbImage = createImage (this.getSize().width, this.getSize().height); 
     dbg = dbImage.getGraphics(); 
    } 

    dbg.setColor (getBackground()); 
    dbg.fillRect (0, 0, this.getSize().width, this.getSize().height); 

    dbg.setColor (getForeground()); 
    paint (dbg); 

    g.drawImage (dbImage, 0, 0, this); 
} 
    } 

这里是GUI.java:

package com.ion.brickdodge; 

import java.awt.BorderLayout; 

import javax.swing.JApplet; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 


public class GUI { 

public static void main(String args[]) { 
     JFrame frame = new JFrame("test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(1000, 1000); 

     JPanel panel = new JPanel(new BorderLayout()); 
     frame.add(panel); 

     JApplet applet = new Game(); 
     panel.add(applet, BorderLayout.CENTER); 
     applet.init(); 
     frame.pack(); 

     frame.setVisible(true); 
    } 
} 

的错误,当我运行它是GUI.java抛出...

Exception in thread "main" java.lang.NullPointerException 
at java.applet.Applet.getCodeBase(Unknown Source) 
at com.ion.brickdodge.Game.init(Game.java:30) 
at com.ion.brickdodge.GUI.main(GUI.java:22) 

任何帮助将不胜感激

+0

为什么你想这样做吗?为什么不让你的类创建一个JPanel,然后根据需要将它用作applet或桌面,只需将它放入JApplet或JFrame中即可? –

+0

您的NPE可能是由'man1 = getImage(getCodeBase(),“res/man1.png”)生成的;' –

+0

图像文件是否与applet本身在同一目录中? – fireshadow52

回答

3

我这将是一个答案:我认为更好的解决方案是将GUI用于创建JPanel。然后,如果您希望将GUI作为applet运行,则可以简单地创建JPanel并将其放入JApplet的contentPane中。同样,如果你想创建一个JFrame,然后创建你的JPanel并把它放在JFrame的contentPane中。

其他问题:

  • 考虑让你的图像作为资源,因为他们很可能会在JAR文件中举行。
  • 不要直接在顶层窗口(如JApplet)中绘制,也不要使用绘画方法。
  • 反而在JPanel的覆盖的paintComponent(...)方法中绘制。这将允许您的代码利用Swing的双缓冲。
  • 请勿在Swing GUI中重写update(...)。这是为AWT完成的,但应该避免Swing。
  • 请勿读取任何图像或在绘画方法中执行任何其他CPU密集型操作。
  • 查看Swing绘画教程,了解应该如何进行这种编码。你可以找到入门教程here,以及更先进的文章here
+0

OK我仍然有点困惑这款游戏是一个Applet,因为它需要在网页中运行,但我需要为这个特定的游戏制作一个独立的应用程序。我以为我可以将它改为JApplet,并将其包含在JFrame中,但这不可能吗? –

+0

这是可能的,但很尴尬。你仍然需要创建一个带有'paintComponent(...)'覆盖的JPanel或者JComponent来完成你的绘制。你是否浏览过Swing图形教程(我假设没有给出你的代码)。在这个项目中移动得太远之前,请考虑这样做。 –

+0

@Lucas:请参阅编辑链接到教程。 –

3

注:如果问题是“为什么会这样”答案就是JVM自动为applet设置一个applet上下文和存根。但是,除非applet加载到网页中,否则不会发生。如果您自己正在加载它,则需要实施,例示&附加这些设施。

这样做并不是非常困难,一旦你掌握了通常由applet元素提供的细节。

(OTOH最好的策略是将游戏转换为面板,把它放在一个框架,并使用JWS启动它。)