# Applet in JFrame einbinden



## Shadow66 (28. Jan 2011)

Hi,
bevor mir unterstellt wir, ich hätte nicht gegooglet - das habe ich, aber nichts Brauchbares gefunden.

Ich möchte ein Applet in einen JFrame einbinden, damit es auch außerhalb des Browsers (als .jar) gestartet werden kann.
Der Frame existiert, aber anstatt das Applets gibts nur eine transparente Fläche.

Hier der Code:


```
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Timer;

public class Shooting extends JApplet implements ActionListener, MouseListener
{
	/**
	 * Serial Version
	 */
	
	public static final long serialVersionUID = 2011-01-27/01;
	
	/**
	 * Declarations 
	 */
	
	int controller, xco, yco, xpos ,ypos, score, time;
	boolean hit;
	Image welcome_screen, bg, snowman, finish_screen;
	MediaTracker MT;
	Button start, exit;
	Random R;
	Timer T;
	Font standard, special;
	
	
	/**
	 * Initializations
	 */
	
	public void init()
	{	
		setLayout(null);
		
		R = new Random();
		
		standard = new Font("Arial", Font.BOLD, 16);
		special = new Font("Arial", Font.BOLD, 23);
		
		start = new Button("Start");
		exit = new Button("Exit");
		
		start.setBounds(280, 440, 100, 20);
		exit.setBounds(280, 440, 100, 20);
		
		add(start);
		
		start.addActionListener(this);
		
		MT = new MediaTracker(this);
		
		welcome_screen = getImage(getDocumentBase(), "Shooting_WelcomeScreen.png");
		bg = getImage(getDocumentBase(), "Shooting_BackgroundImage.png");
		snowman = getImage(getDocumentBase(), "Shooting_Snowman.png");
		finish_screen = getImage(getDocumentBase(), "Shooting_FinishScreen.png");
		
		MT.addImage(welcome_screen, 1);
		MT.addImage(bg, 2);
		MT.addImage(snowman, 3);
		MT.addImage(finish_screen, 4);
		
		try
		{
			MT.waitForAll();
		}
		catch(InterruptedException IE)
		{
			JOptionPane.showMessageDialog(null, "Fehler:\n"+IE, "Fehlermeldung", JOptionPane.ERROR_MESSAGE);
		}
		
		controller = 0;
		
		T = new Timer();
		
		addMouseListener(this);
	}
	
	/**
	 * Paint JApplet
	 */
	
	public void paint(Graphics g)
	{
		if(controller == 1)
		{
			g.setColor(Color.white);
			g.fillRect(0, 0, 640, 480);
			g.drawImage(bg, 0, 0, this);
			g.drawImage(snowman, xco, yco, this);
			
			if(hit)
			{
				score++;
			}
			
			g.setColor(Color.black);
			g.setFont(standard);
			g.drawString("Score: "+score+"  Time: "+time, 0, 460);
		}
		else if(controller == 2)
		{
			g.setColor(Color.white);
			g.fillRect(0, 0, 640, 480);
			g.drawImage(finish_screen, 0, 0, this);
			g.setColor(Color.black);
			g.setFont(special);
			g.drawString("Your Score: "+score, 60, 240);
			
			T.cancel();
			
			exit.setVisible(true);
			exit.addActionListener(this);
			add(exit);
		}
		else
		{	
			g.drawImage(welcome_screen, 0, 0, this);
		}
	}
	
	public void actionPerformed(ActionEvent AE)
	{
		if(AE.getSource() == start)
		{
			score = 0;
			time = 60;
			
			start.setVisible(false);
			exit.setVisible(false);
			
			controller = 1;
			
			T.schedule(new TimerTask() 
			{
				public void run()
				{
					xco = R.nextInt(540);
					yco = R.nextInt(380);
					
					time--;
					
					if(time == 0)
					{
						controller = 2;
					}
					
					hit = false;
					
					repaint();
				}
			}, 0, 1000);
			
			repaint();
		}
		else if(AE.getSource() == exit)
		{
			System.exit(0);
		}
	}

	public void mouseClicked(MouseEvent ME) 
	{
		xpos = ME.getX();
		ypos = ME.getY();
		
		if (xpos > xco && xpos < xco+100 && ypos > yco && ypos < yco+100)
		{
			xco = R.nextInt(540);
			yco = R.nextInt(380);
			
			hit = true;
			
			repaint();
		}
		else
		{
			hit = false;
		}
	}

	public void mouseEntered(MouseEvent ME) {}

	public void mouseExited(MouseEvent ME) {}

	public void mousePressed(MouseEvent ME) {}

	public void mouseReleased(MouseEvent ME) {}
	
	public static void main(String[] args)
	{
		Shooting game = new Shooting();
		
		JFrame main = new JFrame();
		JLabel head = new JLabel("Instructions: Click to shoot!");
		
		main.setLayout(new BorderLayout());
		main.setTitle("Shoot The Evil Snowman!");
		main.setSize(new Dimension(640, 480));
		main.getContentPane().add(head, BorderLayout.NORTH);
		main.getContentPane().add(game, BorderLayout.CENTER);
		main.setVisible(true);
	}
}
```

(Ich weiß, kein besonders tolles Spiel, aber eine bessere Idee hatte ich nicht xD)

Ich hoffe, ihr könnt mir helfen (bin am verzweifeln), schonmal danke und Gruß

shadow


----------



## L-ectron-X (28. Jan 2011)

Die main()-Methode wird vom Applet ignoriert.

Am besten ist es, wenn du das Spiel auf einem JPanel hast und dieses Panel dann ins Applet und in eine Klasse, die von JFrame erbt, einfügst.
Die Bilder brauchst du nicht mehr mit veralteten kompilizierten Methoden laden. Das geht in Swing deutlich einfacher und effektiver mit ImageIO: Grafikdateien laden und anzeigen - Byte-Welt Wiki

BTW: Bei Swing-Komponenten, also Komponenten, die mit einem _*J*_ beginnen, sollte man nicht die paint()-Methode aufrufen.
Da aber JApplet nur die paint()-Methode hat, sollte man auf JPanel ausweichen.


----------



## Shadow66 (28. Jan 2011)

danke für die schnelle antwort...

ich hoffe ich habe das jetz richtig verstanden:

-ich erzeuge eine neue klasse die von JFrame erbt
-füge das, was ich bis jetzt hatte ohne main methode an ein JPanel an
-und binde dann das panel in den frame ein...

soweit richtig??
(will jetz nich damit anfangen und nachher hab ichs falsch verstanden ^^)

gruß 
shadow


----------



## L-ectron-X (28. Jan 2011)

Ja, stimmt so. Ich möchte es noch ein wenig präzisieren.
Stell dir das JPanel einfach als ein Container vor, auf dem sich das ganze Programm optisch darstellt.
Du kannst solche Panels bekanntermaßen auf einem weiteren JPanel, einem JApplet oder einem JFrame oder JDialog hinzufügen (_add()_).
Der Unterschied zwischen Applet und Desktop-Anwendung besteht darin, dass das Applet im Internet "lebt" und dort auch seine Resourcen (Bilder etc) findet, damit es vollständig auf einem Client arbeiten kann. Die Desktop-Anwendung findet seine Resourcen meist auf der lokalen Festplatte.

Das bedeutet, dass du die Bilder bei Verwendung als Applet aus dem Internet laden musst, bei Verwendung als Applikation meist von der lokalen Festplatte.

Daraus ergibt sich, dass dein Applet die Bilder, die auf dem Panel später angezeigt werden sollen, selbst laden muss. Die Bilder übergibt es dann bspw. per Konstruktor an das JPanel, welches sie dann entsprechend weiter verarbeitet/zeichnet.

Denkbar wäre auch ein Callback-Mechanismus, wenn man die Referenz (this) des Objektes an den überladenen Konstruktor des JPanels mitgibt. So kann ermittelt werden, wer das Panel instanziiert hat und entsprechenden Code im Panel abarbeiten.



Hier mal ein völlig anderer Weg, wenn die Anzeige generell in einem JFrame passieren soll:
Applet

```
import javax.swing.*;

public class MyApplet extends JApplet {
  public void init() {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new MyFrame(MyApplet.this).setVisible(true);
      }
    });
  }
}
```

Applikation

```
import javax.swing.*;

public class MyFrame extends JFrame {
  public MyFrame(String title) {
    super(title);
    setSize(800, 600);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
  
  public MyFrame(MyApplet applet) {
    super("MyFrame-Appletcation");
    setSize(800, 600);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  }
  
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new MyFrame("MyFrame-Application").setVisible(true);
      }
    });
  }
}
```
Das Applet erzeugt also eine Instanz des JFrames und zeigt ihn an. Über die Applet-Referenz ist die Kommuniaktion mit dem Applet möglich.
Die Applikation wird ganz normal über die main()-Methode gestartet.



Ein Komplettbeispiel zum Download mit Quelltext in der Jar-Datei findest du im Anhang.
Die Jar-Datei ist per Doppelklick als Applikation und per mitgelieferten Webseite als Applet ausführbar.
Das Beispiel entspricht meinem ersten Vorschlag. Du brauchst also nur noch entscheiden, was genau du haben möchtest.


----------



## Shadow66 (28. Jan 2011)

okay ich werds mal mit dem ersten weg versuchen...
aber eins versteh ich noch nich ganz:
die art und weise wies ursprünglich laufen sollte hab ich hierher: http://java.sun.com/products/java-media/2D/samples/suite/Image/DukeAnim.java

komischerweise funktionert es dabei wenn ichs als jar exportiere...wo is der unterschied zu meinem applet??


----------



## Shadow66 (28. Jan 2011)

fertig funktioniert aber leider immernoch nicht =((
hier mein versuch:

Frame:

```
import javax.swing.*;
import java.awt.*;

public class Starter extends JFrame
{
	/**
	 * Serial Version
	 */
	
	public static final long serialVersionUID = 2011-01-27/02;
	
	/**
	 * Declarations
	 */
	
	JFrame mainframe;
	JPanel maincontent;
	JLabel headline;
	
	/**
	 * Initializations 
	 */
	
	public Starter()
	{	
		headline = new JLabel("Click to shoot!");
		
		maincontent = new JPanel();
		maincontent.setLayout(null);
		maincontent.setSize(new Dimension(640, 480));
		maincontent.add(new Shooting());
		
		mainframe = new JFrame();
		mainframe.setTitle("Shoot The Evil Snowman");
		mainframe.setLayout(new BorderLayout());
		mainframe.setSize(new Dimension(640, 480));
		mainframe.getContentPane().add(headline, BorderLayout.NORTH);
		mainframe.getContentPane().add(maincontent, BorderLayout.CENTER);
		mainframe.setVisible(true);
	}
	
	public static void main(String[] args)
	{
		new Starter();
	}
}
```

Applet:

```
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Timer;

public class Shooting extends JApplet implements ActionListener, MouseListener
{
	/**
	 * Serial Version
	 */
	
	public static final long serialVersionUID = 2011-01-27/01;
	
	/**
	 * Declarations 
	 */
	
	int controller, xco, yco, xpos ,ypos, score, time;
	boolean hit;
	MediaTracker MT;
	Image welcome_screen, bg, snowman, finish_screen, cursor_image;
	Button start, exit;
	Random R;
	Timer T;
	Font standard, special;
	Point P;
	Cursor standard_cursor, crosshairs;
	
	
	/**
	 * Initializations
	 */
	
	public void init()
	{	
		controller = 0;
			
		MT = new MediaTracker(this);
			
		MT.addImage(welcome_screen, 1);
		MT.addImage(bg, 2);
		MT.addImage(snowman, 3);
		MT.addImage(finish_screen, 4);
		
		welcome_screen = getImage(getDocumentBase(), "Shooting_WelcomeScreen.png");
		bg = getImage(getDocumentBase(), "Shooting_BackgroundImage.png");
		snowman = getImage(getDocumentBase(), "Shooting_Snowman.png");
		finish_screen = getImage(getDocumentBase(), "Shooting_FinishScreen.png");
		cursor_image = new ImageIcon("Cursor.gif").getImage();
		
		start = new Button("Start");
		exit = new Button("Exit");
			
		start.setBounds(280, 440, 100, 20);
		exit.setBounds(280, 440, 100, 20);
			
		start.setVisible(true);
		add(start);
			
		exit.setVisible(false);
		add(exit);
			
		start.addActionListener(this);
		exit.addActionListener(this);
			
		R = new Random();
			
		T = new Timer();
			
		standard = new Font("Arial", Font.BOLD, 16);
		special = new Font("Arial", Font.BOLD, 23);
			
		P = new Point(10, 10);
			
		standard_cursor = new Cursor(Cursor.DEFAULT_CURSOR);
		crosshairs = getToolkit().createCustomCursor(cursor_image, P, "Crosshair");
		
		try
		{
			MT.waitForAll();
		}
		catch(InterruptedException IE)
		{
			JOptionPane.showMessageDialog(null, "Fehler:\n"+IE, "Fehlermeldung", JOptionPane.ERROR_MESSAGE);
		}
		
		
		setLayout(null);
		
		addMouseListener(this);
	}
	
	/**
	 * Paint JApplet
	 */
	
	public void paint(Graphics g)
	{
		if(controller == 1)
		{
			setCursor(crosshairs);
			
			g.setColor(Color.white);
			g.fillRect(0, 0, 640, 480);
			g.drawImage(bg, 0, 0, this);
			g.drawImage(snowman, xco, yco, this);
			
			if(hit)
			{
				score++;
			}
			
			g.setColor(Color.black);
			g.setFont(standard);
			g.drawString("Score: "+score+"  Time: "+time, 0, 460);
		}
		else if(controller == 2)
		{	
			setCursor(standard_cursor);
			
			g.setColor(Color.white);
			g.fillRect(0, 0, 640, 480);
			g.drawImage(finish_screen, 0, 0, this);
			g.setColor(Color.black);
			g.setFont(special);
			g.drawString("Your Score: "+score, 60, 240);
			
			T.cancel();
			
			exit.setVisible(true);
		}
		else
		{	
			setCursor(standard_cursor);
			
			g.drawImage(welcome_screen, 0, 0, this);
		}
	}
	
	public void actionPerformed(ActionEvent AE)
	{
		if(AE.getSource() == start)
		{
			score = 0;
			time = 60;
			
			start.setVisible(false);
			exit.setVisible(false);
			
			controller = 1;
			
			T.schedule(new TimerTask() 
			{
				public void run()
				{
					xco = R.nextInt(540);
					yco = R.nextInt(380);
					
					time--;
					
					if(time == 0)
					{
						controller = 2;
					}
					
					hit = false;
					
					repaint();
				}
			}, 0, 1000);
			
			repaint();
		}
		else if(AE.getSource() == exit)
		{
			System.exit(0);
		}
	}

	public void mouseClicked(MouseEvent ME) 
	{
		xpos = ME.getX();
		ypos = ME.getY();
		
		if (xpos > xco && xpos < xco+100 && ypos > yco && ypos < yco+100)
		{
			xco = R.nextInt(540);
			yco = R.nextInt(380);
			
			hit = true;
			
			repaint();
		}
		else
		{
			hit = false;
		}
	}

	public void mouseEntered(MouseEvent ME) {}

	public void mouseExited(MouseEvent ME) {}

	public void mousePressed(MouseEvent ME) {}

	public void mouseReleased(MouseEvent ME) {}
}
```

hab ich was übersehn??


----------



## L-ectron-X (29. Jan 2011)

Du solltest ja auch nicht das Applet einem Panel hinzufügen, sondern das Panel dem Applet. Halte dich einfach an meinen Beispielcode.

Und du solltest alles was in der paint()-Methode deines Applets gezeichnet wird, im Prinzip den gesamten Code des Applets in dieses Panel verlegen. Gezeichnet wird dann aber in der paintComponent()-Methode.

Das Applet hält dann nur noch den Code zum Einlesen der Bilder und eine Instanz des Panels.


----------

