# JApplet parallel zu Java-Applikation entwickeln



## ggirl (11. Dez 2007)

Hallo,

ich bin mir nicht sicher, ob meine Frage hierhin oder in die Kategorie "Anfängerfragen" gehört. Da ich ein Problem mit einem JApplet habe, poste ich einmal hier.

Es geht um Folgendes: Ich habe ien Spiel als Java-Applikation entwickelt und möchte jetzt die Möglichkeit haben, dieses als Applikation und als Applet starten zu können.

Habe hierfür 2 neue Klassen angelegt:


```
public class ApplikationSpiel extends JFrame
```

und


```
public class AppletSpiel extends JApplet
```

in diese beiden Klassen wird jeweil ein Objekt meiner Spieloberfläche (Gui extends JPanel) erzeugt, die wiederum viele andere Klassen braucht (überwiegend JPanels), damit das Spiel so aussieht, wie ich mir das vorstelle.

Dazu habe ich eine Klasse ImageLoader angelegt, die mir die Bilder in Abhängigkeit davon, ob das Applet oder die Applikation läuft aus den richtigen Verzeichnissen ziehen soll. Bin nämlich schon mehrere Tage am recherchieren und habe u. a. herausgefunden, dass man für Applets die Bilder anders laden muss. Der Part für die Applikation sieht im ImageLoader so aus (er funktioniert auch):


```
/*
 * ImageLoader.java
 */

import javax.swing.*;

public class ImageLoader {
	
	private String pathApplication;
	private String pathApplet;
	private String currentPath;
	
	public ImageLoader(){
		
		pathApplication = "images/"; // Speicherort der Bilder im Programmverzeichnis
		//pathApplet = ???  über getCodeBase() realisieren versuchen
		currentPath = "";
		
	}
	
                // Für alle anderen Klassen, die Bilder haben
	public ImageIcon createImageIcon(String pfad){
		
		// auskommentierter Code war einer von mehreren Versuchen, der so auch nicht geht
                                // if (AppletSpiel){
			
		//    currentPath = pathApplet;
		// }else{
		//    currentPath = pathApplication;
		//}
		
		return new ImageIcon (pathApplication + pfad);
	}
	
	// fuer Klasse ImageButton.java
	public ImageIcon createImageIcon(String pfad, String name){
		
        // return new ImageIcon (currentPath + pfad, name);
		return new ImageIcon ("images/" + pfad, name);
	}


}
```

alles, was auskommentiert sind Reste von verzweifelten Versuchen, in der Klasse abzufragen, ob die Bilder duchrs Applet oder den JFrame gebraucht werden.

Nach dem ich so viele Postings gelesen habe bin ich ganz verwirrt und weiß garnicht mehr, wie ich mein Vorhaben realisieren sollte. Alles sind nur Bruchstücke und es handelt sich hier um mein erstes Applet. Auch für die Bücher die ich hier rumligen habe ist dieser Fall wohl zu speziell bzw. vielleicht verstehe auch ich die Zusammenhänge nicht ganz richtig...

Ich arbeite im ganzen Spiel wenn ich Bilder brauche mit ImageIcon, da wir in der Vorlesung noch nichts über JAVA 2D gehört haben und dies möglichst deshalb auch nicht verwenden sollten. Wenn ich mal ein Image brauche, hole ich mir dieses über getImage();

Bis jetzt habe ich folgendes unternommen:

Jede Oberfläche, die Bilder benötigt, hat ImageIcons und eine Instanz vom ImageLoader. Über diese rufe ich die Methode createImageIcon auf und übergebe den Namen des Bildes und ggf. den Ordner, wenn es sich um einen Unterordner von "Images/" handelt. (bei Applikation getestet: Das geht so  )

Mein AppletSpiel und meine ApplikationSpiel haben kein ImageLoader-Objekt, da ich momentan keinen Grund dafür sehe, dass sie dieses bräuchten. Sie sind nur dazu da, eine Instanz der Oberfläche zu erzeugen. Wie kann man denn abfragen, ob jetzt grad die Methode createImageIcon() vom Applet oder vom JFrame gebraucht wird? Wie macht man die beiden Objekte der Klasse ImageLoader bekannt?

Da das Applet meines Wissens ja kein Recht hat, auf lokale Daten der Festplatte zuzugreifen, muss ich - soviel ich gelesen habe - über die URL rankommen. Deshalb komme ich mit dem auskommentierten Codezeilen auch nicht weiter.

Außerdem wäre in dieser Lösung mit dem pathApplet meiner Meinung nach die Pfadangabe auch statisch und ich hätte sie gerne dynamisch über die URL abgefragt. Aber wie mach ich aus der URL einen Pfad? oder ist das keine gute Idee? Ich weiss es nicht...

Ich habe das Gefühl, dass ich gerade viele verschiedene Dinge durcheinanderwürfle und bitte dies zu entschuldigen. Fühle mich doch noch ganz schön als Anfänger diesbezüglich.  Hat jemand von euch einen Tipp, wo ich ansetzten könnte, um mein Vorhaben zu realisieren?


Liebe Grüße

*ggirl*


----------



## Gast (11. Dez 2007)

Du könnste im applet sowas machen:



```
URL baseurl = applet.getDocumentBase(); // die URL zur HTML-Datei mit der du das Applet startest
Image img = applet.getImage(baseurl , "ordnername/bild.jpg"); // der Ordner muss dann im gleichen verzeichnis liegen wie die HTML-Datei
ImageIcon icon = new ImageIcon(img); // erstellt dein icon
```


----------



## ggirl (11. Dez 2007)

Danke für deine Antwort!

Der Code erinnert mich stark an den aus meinem Java-Buch, alledings bin ich net drauf gekommen, aus dem image ein ImageIcon zu machen (letzte Zeile)..das hilft mir schon einmal weiter und bringt schon mal ein wenig klarheit in die Sache.

Darf ich dich fragen wie man es schafft, dass die Methode, die die ImageIcons erzeugt mal sich den Pfad über getCodeBase() fürs Applet und mal über den PathApplikation-String für die Applikation holt? Kann man das mit einer if-Abfrage machen? Und wenn ja, wie muss dann die Expresssion aussehen, dass sie true ergibt, wenn die Methode in einer der Unterklassen übers Appet aufgerufen wird?


----------



## Wildcard (11. Dez 2007)

Mach die Sache einheitlich:
Alle Resourcen kommen in ein jar, dann können sowohl Applikation als auch Applet über getClass().getResource das Bild laden.


----------



## ggirl (11. Dez 2007)

ok, jetzt steig ich grad aus...was ist denn ein jar? :bahnhof: 
Werd mal danach recherchieren... das Wort hab ich bis jetzt nur einmal in einem posting gelesen und konnte mir nix darunter vorstellen...werd mal googeln gehen...


----------



## Wildcard (11. Dez 2007)

Ein jar kann eine Bibliothek sein (wie .so oder .dll), oder ein ausführbares Programm (wie .sh oder .exe)


----------



## Gast (12. Dez 2007)

ein jar ist eigentlich nichts anderes wie ein zip-File, in den du alle deine Sache die zum Programm gehören reinpacken kannst. wenn man möchte kann man das ganze dann noch ausführbar machen (startet beim doppelklick).


ansonsten um auf deine frage zurückzukommen.

```
class BilderVerwalten{

  Container c;

  public BilderVerwalten(Container c){
    this.c = c;
  }

  public void ladeBilder(){
    if(c instanceof JFrame){
        ladeApplikationsBilder();
    } 
    else if(c instanceof JApplet){
        ladeAppletBilder();
    }
  }

  ...
}
```


----------



## ggirl (12. Dez 2007)

Hallo, danke für die Antwort!

Sowas habe ich gesucht

Derzeit rufe ich die die Methode ladeBilder nur in JPanels auf, die von der Klasse Gui instanziiert werden. In meiner Startklasse fürs Applet und für die Applikation erzeuge ich dann so ein Gui-Objekt.

So wie ich es verstehe, muss ich, damit der Code geht, in beiden Startklassen ein Objekt von Bilder erzeugen anlegen und dabei jeweils (this) mit übergeben.

Dann bräuchte ich glaub ich noch glaub ich in beiden Klassen eine Methode, die dann über das BilderVerwalten-Objekt die Methode ladeBilder() aufruft.

Nur was mache ich dann in den JPanels?

In den JPanels-Ableitungen habe ich es bis jetzt so gelöst:



```
BilderVerwalten loader;
ImageIcon icon;

...

// im Konstruktor:


icon = loader.ladeBilder("bild.jpg");
```

Da jetzt den Objekttyp, der das Icon anfragt mitgeben, ist denk ich net sinvoll, da es immer ein JPanel ist.

Kann mir gerade ich so ganz vorstellen, was ich in den den JPanel-Ableitungen jetzt machen muss. 

Wenn ich in diesen Klassen jeweils ein Objekt meiner Startklasse fürs Applet und für die Applikation erzeuge um in letztgenannten Klassen dann die Methode auzurufen, die dann die Bilder über das BilderVerwalten-Objekt aufruft, müsste ich ja dann irgendwie auch in den JPanels unterscheiden, aus welcher Klasse (JFrame oder JApplet) ich die Methode zum Bilder laden aufrufe.

Geht sowas überhaupt? Es ist ja erst zur Laufzeit bekannt, ob das Applet oder die Applikation die Gui mit ihren JPanels instanziiert. Wie behandle ich das in den JPanels?


Würde mich sehr drüber freuen, wenn ihr mir hierzu noch einen Tipp geben könntet. 

Liebe Grüße *ggirl*


----------



## Guest (12. Dez 2007)

eine möglichkeite wäre das du die klasse BilderVerwalten als singleton schreibst.


```
public class BilderVerwalten {

    private static BilderVerwalten instance = null;
    private Container c;

    private BilderVerwalten () {}
   
    public static BilderVerwalten getInstance(){
        if(instance == null){
            instance = new BilderVerwalten ();
        }
        return instance;
    }

    public void setContainer(Container c){
      this.c = c; 
    }


    public ImageIcon getImageIcon(String pfadZumBild){
       ... bild erzeugen ...
       return icon;
    }
}
```


du musst die klasse dann im japplet oder im jframe erzeuge und kannst sie dann von überall aufrufen.

erzeugen...

```
class JApplet/JFrame{

   public konstruktor/init(){
     BildVerwalten bv = BildVerwaltern.getInstance();
     bv.setContainer(this);
   }

}
```


aus jpanel zugreifen...

```
class JPanel{

   public konstruktor/init(){
     BildVerwalten bv = BildVerwaltern.getInstance();
     ImageIcon icon = bv.getImageIcon(irgendeinpfad);
   }

}
```


----------



## Wildcard (12. Dez 2007)

Hallo? Jar!?


----------



## Gast (12. Dez 2007)

nicht jeder möchte alle daten in einen jar-file packen.

das kann auch nachteile haben, weil der jarfile unnötig gross wird und bei jedem programmupdate alle bilder neu vom servergeladen werden, obwohl sie sich vielleicht nicht geändert haben.

wenn er es lieber so lösen möchte, kann er das auch tun, es spricht imo nichts dagegen.


----------



## Wildcard (12. Dez 2007)

Man kann Bilder auch in ein anderes jar als die class files packen.


----------

