Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Also am Anfang, ich wusste nicht, wo ich das Thema machen sollte, also habe ich es mal hier gemacht.
Ich hab folgendes Problem: Ich hab jetzt mit Eclipse ein Applet programmiert und das läuft auch alles solang ich es über Eclipse laufen lasse. Wenn ich es aber im Browser laufen lassen möchte gibt Java immer folgene Fehlermeldung raus:
java.lang.NullPointerException
at sun.plugin2.applet.Plugin2Manager.findAppletJDKLevel(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Ausnahme: java.lang.NullPointerException
Kann mir einer sagen was das heißt, und wie man das beheben kann?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hier Titel eintragen</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>
<body>
<applet code="Main.class" width="400" height="300"></applet> <!-- Bei code habe ich auch andere Angaben probiert -->
</body>
</html>
und als Jar so:
HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hier Titel eintragen</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
</head>
<body>
<applet code="ball/Main.class" archives="ball.jar" width="400" height="300"></applet> <!-- Bei code habe ich wieder mehrer Varianten probiert -->
</body>
</html>
Ja aber ich habe es auch mal mit ball.Main.class oder ball/Main.class versucht.
Und bei simplen Applets, die nicht viel machen klappt es eigentlich auch.
Ich habe dein Programm soweit zum Laufen bekommen, daß der Ende-Bildschirm angezeigt wird.
Was genau das Problem war, kann ich nicht sagen.
Die Bilder haben einen absoluten Pfad (den du natürlich nicht mitliefern konntest) und sind deswegen von mir entfernt worden.
Die Zeile SwingUtilities.invokeAndWait ... solltest du dir im SDK noch einmal anschauen (Java Platform SE 6), damit habe ich noch nie programmiert, aber so wie es aussieht, brauchst du zwei neue Threads, um die Methode richtig zu starten.
Was noch fehlt, ist, daß dein Programm von vorn anfängt und bei 30 Sekunden übrigbleibender Spielzeit anfängt zu zählen. Das wirst du bestimmt selber hinbekommen.
Bei der Fehlersuche ist mir wieder einmal aufgefallen, daß Daten und Java-Klassen im Cache gespeichert bleiben und statt der neuen, berichtigten Klassen immer noch die alten, fehlerhaften Klassen verwendet wurden. Es bleibt dir, wenn der Fehler wieder einmal auftritt, nicht viel übrig, als den Browser immer wieder zu beenden und neu zu starten.
Erst hatte ich das Applet mit Firefox aufgerufen, bin dann aber auf Opera umgestiegen, weil die Fehlermeldungen hier aussagekräftiger waren.
Ich habe dein Programm in vier Klassen zerlegt:
Main.java
Java:
package ball;
//import java.awt.;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;
import java.applet.*;
public class Main
extends JApplet
implements ImageObserver
{
private static final long serialVersionUID = 1L;
private Animation2 animation = new Animation2();
private Time2 time = new Time2();
private Thread tha = new Thread(animation);
private Thread thb = new Thread(time);
private MyListener2 handler;// = new MyListener();
/* private MediaTracker mt;// = new MediaTracker(this);*/
private static BufferedImage bild1;// = Toolkit.getDefaultToolkit().getImage("c:\\Java\\Test\\Ball\\ball1.png");
private static BufferedImage bild2;// = Toolkit.getDefaultToolkit().getImage("c:\\Java\\Test\\Ball\\ball2.png");*/
private static int appletsize_x = 400;
private static int appletsize_y = 300;
private static int boden = 20;
private static int x_pos1 = 200;
private static int y_pos1 = 200;
private static int radius1 = 0;
private static boolean up1 = false;
private static boolean down1 = false;
private static boolean right1 = false;
private static boolean left1 = false;
private static int x_pos2 = 0;
private static int y_pos2 = 0;
private static int radius2 = 10;
private static boolean neu = true;
private static int zeit = 30;
// Zeit berechnen
public static int getTime()
{
return zeit;
}
public static void setTime(int z)
{
zeit = zeit + z;
}
// Bilder laden
public static BufferedImage getImage1()
{
return bild1;
}
public static BufferedImage getImage2()
{
return bild2;
}
// Größe des Applets ermitteln
public static int getAppletsize_x()
{
return appletsize_x;
}
public static int getAppletsize_y()
{
return appletsize_y;
}
public static int getGround()
{
return boden;
}
// Daten für Spielerball
public static int getX_pos1()
{
return x_pos1;
}
public static void setX_pos1(int z)
{
x_pos1 = x_pos1 + z;
}
public static int getY_pos1()
{
return y_pos1;
}
public static void setY_pos1(int z)
{
y_pos1 = y_pos1 + z;
}
public static int getRadius1()
{
return radius1;
}
public static void setRadius1(int z)
{
radius1 = z;
}
public static boolean getUp()
{
return up1;
}
public static void setUp(boolean b)
{
up1 = b;
}
public static boolean getDown()
{
return down1;
}
public static void setDown(boolean b)
{
down1 = b;
}
public static boolean getRight()
{
return right1;
}
public static void setRight(boolean b)
{
right1 = b;
}
public static boolean getLeft()
{
return left1;
}
public static void setLeft(boolean b)
{
left1 = b;
}
// Daten für Computerball
public static int getX_pos2()
{
return x_pos2;
}
public static void setX_pos2(int z)
{
x_pos2 = z;
}
public static int getY_pos2()
{
return y_pos2;
}
public static void setY_pos2(int z)
{
y_pos2 = z;
}
public static int getRadius2()
{
return radius2;
}
public static void setRadius2(int z)
{
radius2 = z;
}
public static boolean getNew()
{
return neu;
}
public static void setNew(boolean b)
{
neu = b;
}
public void init()
{
this.setSize(getAppletsize_x(),getAppletsize_y());
this.addKeyListener(handler);
bild1=new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);
bild2=new BufferedImage(1,1,BufferedImage.TYPE_INT_RGB);
/* mt.addImage(bild1, 0);
mt.addImage(bild2, 1);
try
{
mt.waitForID(0);
mt.waitForID(1);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}*/
radius1 = bild1.getWidth(this) / 2;
radius2 = bild2.getWidth(this) / 2;
new Thread(new Runnable()
{
public void run()
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
public void run()
{
add(animation);
}
});
}
catch (Exception ex)
{
ex.printStackTrace();
ex.printStackTrace();
}
}
}).start();
}
public void start()
{
tha.start();
thb.start();
}
}
Animation2:
Java:
package ball;
import java.awt.*;
import java.util.Random;
import javax.swing.JPanel;
public class Animation2
extends JPanel
implements Runnable
{
private static final long serialVersionUID = 1L;
private Random r = new Random();
private int sx = 0;
private int sy = 0;
private int radius = 0;
private int setx = 0;
private int sety = 0;
private int punkte = 0;
public void run()
{
while (true)
{
if ((Main.getUp() == true) && (Main.getY_pos1() > Main.getRadius1()))
{
Main.setY_pos1(-1);
}
if ((Main.getDown() == true) && (Main.getY_pos1() < Main.getAppletsize_y() - Main.getGround() - Main.getRadius1()))
{
Main.setY_pos1(1);
}
if ((Main.getLeft() == true) && (Main.getX_pos1() > Main.getRadius1()))
{
Main.setX_pos1(-1);
}
if ((Main.getRight() == true) && (Main.getX_pos1() < Main.getAppletsize_x() - Main.getRadius1()))
{
Main.setX_pos1(1);
}
// x-Abstand wird berechnet
sx = Main.getX_pos1() - Main.getX_pos2();
if (sx < 0)
{
sx = Main.getX_pos2() - Main.getX_pos1();
}
// y-Abstand wird berechnet
sy = Main.getY_pos1() - Main.getY_pos2();
if (sy < 0) {
sy = Main.getY_pos2() - Main.getY_pos1();
}
// Computerball wird getroffen
radius = Main.getRadius1() + Main.getRadius2();
if ((sx * sx + sy * sy < radius * radius) || Main.getNew() == true)
{
// Computerball wird neu gesetzt bis er nicht mehr den anderen Ball berührt
do
{
setx = r.nextInt(Main.getAppletsize_x() - 2 * Main.getRadius2()) + Main.getRadius2();
} while ((setx >= Main.getX_pos1() - Main.getRadius1()) && (setx <= Main.getX_pos1() + Main.getRadius1()));
do
{
sety = r.nextInt(Main.getAppletsize_y() - Main.getGround() - 2 * Main.getRadius2()) + Main.getRadius2();
} while ((sety >= Main.getY_pos1() - Main.getRadius1()) && (sety <= Main.getY_pos1() + Main.getRadius1()));
// neue Position wird übernommen
Main.setX_pos2(setx);
Main.setY_pos2(sety);
// pro Hit ein Punkt, maximal 9999
if ((punkte < 9999) && (Main.getNew() == false))
{
punkte++;
}
Main.setNew(false);
}
repaint();
try
{
Thread.sleep(5);
}
catch (InterruptedException ex)
{
}
}
}
// Bildschirm wird bemalt
public void paintComponent(final Graphics g)
{
super.paintComponent(g);
if (Main.getTime() > 0)
{
g.setColor(new Color(0,200,200));
g.fillRect(0, 0, Main.getAppletsize_x(), Main.getAppletsize_y() - Main.getGround());
g.setColor(new Color(0, 255, 0));
g.fillRect(0, Main.getAppletsize_y() - Main.getGround(), Main.getAppletsize_x(), Main.getGround());
g.drawImage(Main.getImage1(), Main.getX_pos1() - Main.getRadius1(), Main.getY_pos1() - Main.getRadius1(), this);
g.drawImage(Main.getImage2(), Main.getX_pos2() - Main.getRadius2(), Main.getY_pos2() - Main.getRadius2(), this);
g.setColor(Color.yellow);
g.drawString("Punkte : " + punkte, Main.getAppletsize_x() - 80, 20);
g.drawString("Zeit: " + Main.getTime(), 20, 20);
}
if (Main.getTime() == 0)
{
g.setColor(new Color(0,200,200));
g.fillRect(0, 0, Main.getAppletsize_x(), Main.getAppletsize_y() - Main.getGround());
g.setColor(new Color(0, 255, 0));
g.fillRect(0, Main.getAppletsize_y() - Main.getGround(), Main.getAppletsize_x(), Main.getGround());
g.setColor(Color.red);
g.setFont(new Font("Arial", Font.BOLD, 26));
g.drawString("E N D E", Main.getAppletsize_x() / 2 - 40, Main.getAppletsize_y() / 2);
}
}
}
MyListener2:
Java:
package ball;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class MyListener2
implements KeyListener
{
public void keyPressed(KeyEvent e)
{
switch(e.getKeyCode())
{
case KeyEvent.VK_UP:
Main.setUp(true);
break;
case KeyEvent.VK_DOWN:
Main.setDown(true);
break;
case KeyEvent.VK_LEFT:
Main.setLeft(true);
break;
case KeyEvent.VK_RIGHT:
Main.setRight(true);
break;
}
}
public void keyReleased(KeyEvent e)
{
switch(e.getKeyCode())
{
case KeyEvent.VK_UP:
Main.setUp(false);
break;
case KeyEvent.VK_DOWN:
Main.setDown(false);
break;
case KeyEvent.VK_LEFT:
Main.setLeft(false);
break;
case KeyEvent.VK_RIGHT:
Main.setRight(false);
break;
}
}
public void keyTyped(KeyEvent e)
{
}
}
Time2:
Java:
package ball;
public class Time2
implements Runnable
{
public void run()
{
while (true)
{
if (Main.getTime() > 0)
{
Main.setTime(-1);
}
try
{
Thread.sleep(1000);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
Laß mal von dir hören, wenn das Programm fertig ist.
Dann aber besser eine ZIP-Datei beilegen, damit auch die Bilder mit dabei sind.
Edit: Ich habe das Programm eben noch einmal mit Firefox und Opera gestartet: das Programm fängt jetzt doch bei 30 Sekunden Anfangszeit an zu zählen - das liegt eben am Cache, in dem vorher noch die alten Java-Klassen waren.
Edit: Jetzt ist im bin-Ordner noch die HTML-Datei mit dabei.
Noch eine Anmerkung von mir: In Applets und schon gar nicht in JApplets sollten Bilder mit dem Toolkit geladen werden.
In Applets ist die Variante mit einem vorgeschalteten MediaTracker zu bevorzugen, der sicherstellt, dass die Bilder wirklich geladen sind, bevor sie gezeichnet werden. Zum Laden der Bilder ist dann die getImage()-Methode aus Applet benutzen, nicht das Toolkit.
In JApplets können wir auf den MediaTracker verzichten, wenn wir Bilder mit den wesentlich effizienteren ImageIO-Klassen die Bilder laden. Hier ist dann eine passende read()-Methode auszuwählen.
Also ich habe jetzt mal den Code von Oliver bei mir kopert und ihn ein bisschen angepasst.
Bis dahin lief dann alles. Dann habe ich mit dem Tipp L-ectron-X es mal mit ImageIO probiert, da ich aber keine Ahnung von BufferedImage oder ImageIO habe, habe ich mal ein bisschen gegooglet und mir das hier zusammengewürfelt:
Die absoluten Pfäde sind übrigens nur zum Test.
Wieder in Eclipse getestet und die Bälle waren da, konnte sie aber nicht bewegen. Also habe ich aus
Java:
private MyListener2 handler;// = new MyListener();
Java:
private MyListener2 handler = new MyListener2();
gemacht. Wieso wurde das überhaupt auskommentiert?
So in Eclipse getestet und es lief. Dann alles in Firefox getestet aber der hat mir folgene Meldung angezeigt:
java.security.AccessControlException: access denied (java.io.FilePermission c:\Java\Test\Ball\ball1.png read)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkRead(Unknown Source)
at java.io.File.canRead(Unknown Source)
at javax.imageio.ImageIO.read(Unknown Source)
at ball2.Main2.init(Main2.java:198)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Ausnahme: java.security.AccessControlException: access denied (java.io.FilePermission c:\Java\Test\Ball\ball1.png read)
Dass ganze in Opera getestet und Opera hat nur "Applet crashed!" rausgerückt. Wie komme ich an die Fehlermeldungen bei Opera? Ich arbeite sonst nie damit.
Außerdem ist mir bei meinem alten Applet aufgefallen, dass es nach dem Compilieren nicht nur eine Main.class sondern auch eine Main$1.class gibt. Bei decompilieren kam folgendes raus:
Java:
package ball;
// Referenced classes of package ball:
// Main
class Main$1
implements Runnable
{
public void run()
{
add(Main.access$0(Main.this));
}
final Main this$0;
Main$1()
{
this$0 = Main.this;
super();
}
}
woraus ich aber irgendwie nicht schlau werden kann. Hab dann mal versucht die Main$1.class über den Browser zu starten, kam aber auch nur mist raus.
Ich habe jetzt mal alles inklusive Bilder in ein Zip gepackt und angehängt.
PS: Habe gerade noch gemerkt das bei es bei dem neuen Applet einmal noch Main2$1.class und Main2$1$1.class gibt ???:L
Die Fehlermeldungen stehen bei Opera 10.10 in Extras->Weiteres->Java-Console. (Eigentlich kann hier auch nur der StackTrace ausgegeben werden, aber mir kam es vor, daß Firefox einmal von einem GLContext sprach (ist bei normalem Java eigentlich doch unmöglich) und Opera von einem NoClassDefFoundError.)
Die Dollarzeichen im Klassennamen ("Main$1.class ") entstehen, wenn in einer Klassen-Source-Datei mehrere Klassen angegeben werden:
Java:
public class Main
{
...
}
class Animation
{
...
}
Die Klasse Animation bekäme ungefähr den Namen "Main$Animation.class". Die "1" ("Main$1.class") entsteht bei Verwendung anonymer Klassen:
Java:
new Thread(new Runnable()
{
public void run()
{
....
}
}).start();
Danke Oliver, endlich weiß ich was dieses $-Zeichen sind
Aber das mit den lokalen Pfaden klappt nicht Opera und Firefox spucken immernoch die gleichen Meldungen aus, auch nach neu starten ???:L
PS: Die Seite werde ich mir morgen mal in Ruhe anschauen
EDIT: Jetzt habe ich einmal dein Applet geöffnet und prompt klappt auch meins, und das obwohl ich auch schon vorher ein paar mal Firefox neu gestartet habe...
Allerdings ruckelt das Applet ziemlich, und läuft nicht flüssig...
Ich habe bei mir eben mein Applet aus der HTML-Datei im bin-Ordner starten können, allerdings muß man bei Opera manchmal die Seite noch einmal neu laden, damit das Applet tatsächlich startet.
Firefox prüft seit einiger Zeit die Java-Policy (Opera anscheinend nicht), habe ich eben von Hand eingetragen: geht jetzt auch.
Auf File sollte bei der Verwendung in Applets abgesehen werden, es sei denn man möchte sich mit AccessControlExceptions herum schlagen. File greift auf die lokale Verzeichnisebene zu, was ja bekanntermaßen unsignierten Applets verboten ist.
File wird aber auch gar nicht gebraucht. Besser: Gleich in ein Image (Bufferedmage) laden
Schau dir mal die read()-Methoden an, die von ImageIO bereitgestellt werden, da sind die passenden dabei.
Also: File weg!
Ich wills jetzt auch nicht weiter spannend machen und um den heißen Brei herum reden, deshalb noch gleich etwas Code nachgeschoben, der in deinem Fall so aussehen kann:
gemacht, in der hoffnung, das es flüssiger läuft. Wieso wurde überhaupt ein Thread draus gemacht?
Allerdings ruckelt das Applet genauso wie vorher, weiß aber nicht wieso.
Beachtlich .
Im Ende-Bildschirm fehlen die Punkte (das Endergebnis ("Habe ich gewonnen oder verloren ? Bin ich besser als andere ?")).
Wieso wurde ein Thread daraus gemacht: weil es in der Dokumentation so drin steht.
Applet ist ruckelig: bei mir ruckelt es nicht.
Dann wirst du dich bestimmt bald an dein nächstes Spiel heranwagen.
Wenn du noch nach einer Spielidee suchst: auf meiner Homepage unter "Anregungen" stehen ungefähr 40 Applets und Flashplayer-Animationen von einfachen Videospielen (viele aus den 80ern). Kannst dir ja eines von aussuchen :rtfm:- du kannst natürlich auch selber im Internet suchenueh:.
Danke, Oliver
Aber ich hab das Applet auch nur mit diesem Forum hier hinbekommen
Wegen der unvollständigkeit, ich hab ja auch am Anfang geschrieben, dass es noch unvollständig ist und das mit der Highscore wollte ich auch noch machen. Allerdings muss ich mir noch überlegen, wie ich die Highscore aus der Textdatei auf den Bildschirm bringe.
Und wegen dem ruckeln, ich habe es gerade mal auf einem älteren Computer ausprobiert, und da ruckelt es auch nicht. Es scheint wohl, dass es an meinem Computer liegt.
Ich habe mir das Applet mal herunter geladen, aber noch nicht zerlegt.
Unter Ubuntu läuft es weder im Firefox noch im Opera. Es wird jeweils nur das vermutlich erste Bild angezeigt. Die Anzeige steht also.
Ich habe mir das Applet mal herunter geladen, aber noch nicht zerlegt.
Unter Ubuntu läuft es weder im Firefox noch im Opera. Es wird jeweils nur das vermutlich erste Bild angezeigt. Die Anzeige steht also.