Advanced   Java   Services
Kommunikation zwischen Applets
Back Next Up Home

Kommunikation innerhalb einer HTML-Datei


Wiederum mit Hilfe des AppletContextes ist es möglich, daß mehrere Applets in einer HTML-Datei miteinander daten austauschen. Der AppletContext bietet zwei Methoden, über die ein Applet Information enthält, ob noch andere Applets im gleichen HTML-file vorhanden sind.

AppletContext
ReturntypName der Methode
Applet
 
getApplet(String name)
Finds and returns the applet in the document represented by this applet context with the given name.
Enumeration
 
getApplets()
Finds all the applets in the document represented by this applet context.


getApplets()

Die Methode getApplets() liefert eine Enumeration aller Applets, die in die HTML-Datei eingebettet sind. Damit kann ein Applet alle public-Methoden anderer Applets verwenden, sofern es sich um öffentliche Methode der Klasse Applet handelt. Selbst entworfene Methoden können so aber nicht gerufen werden.

getApplet(String name)

Man kann auch einen Namen für ein Applet vergeben. Übergibt man der Methode diesen Namen, so liefert sie das zugehörige Appletobjekt. Der Name für ein Applet wird in der HTML-Datei im applet-Tag vergeben. Der Name ist wie eine ID. Für das folgende Applet vergeben wir den Namen "InfoApplet" wie folgt

<applet code="NameApplet.class" width=300 height=200 name="InfoApplet">



Und hier der Quelltext des Applets. Die in unserem Zusammenhang wichtigen Stellen sind rot hervorgehoben. Man sieht, daß die Information über andere Applets in der start()-Methode noch nicht zur Verfügung steht. Das Applet verwendet eine Klasse JTextArea2, die eine nützliche Erweiterung zur Klasse JTextArea darstellt. Über die Vorzüge dieser Klasse, siehe Die Klasse JTextArea2

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

public class NameApplet extends JApplet
{
   private JLabel label = new JLabel( getClass().getName() , SwingConstants.CENTER) ;
   private JButton infoButton = new JButton("show all Appletnames");
   private JButton clearButton = new JButton("clear");
   private JPanel southPanel = new JPanel();
   private JTextArea2 tear = new JTextArea2();
   private JScrollPane sp = new JScrollPane(tear);
   private Container conPane = getContentPane();

   public void init()
   {
      initJMenuBar();
      initInfoButton();
      initMessageArea();
      initSouth();
   }

   public void start()
   {
      tear.appendln("infos in start:");
      
      Enumeration enum = getAppletContext().getApplets();
      while( enum.hasMoreElements() )
      {
         Object app = enum.nextElement();
         tear.appendln( app.getClass().getName() );
      }
      
      tear.appendln("-------------------------------------");
   }

   private void initJMenuBar()
   {
      JMenuBar jmb = new JMenuBar();
      jmb.setLayout( new BorderLayout());
      setJMenuBar(jmb);
      jmb.add(label);

      label.setOpaque(true);
      label.setPreferredSize( new Dimension(100,24) ) ;
      //label.setBackground( new Color( 240, 240, 200 ) );
   }

   private void initInfoButton()
   {
      infoButton.setPreferredSize( new Dimension(100,22) ) ;
      infoButton.addActionListener( new InfoHandler() );
      conPane.add(infoButton, BorderLayout.NORTH);
   }

   private void initMessageArea()
   {
      conPane.add(sp, BorderLayout.CENTER);
   }

   private void initSouth()
   {
      southPanel.setLayout( new GridLayout() );

      clearButton.addActionListener( new ClearHandler() );
      southPanel.add(clearButton);

      conPane.add(southPanel, BorderLayout.SOUTH);
   }


   class InfoHandler implements ActionListener
   {
      public void actionPerformed(ActionEvent e)
      {
         tear.appendln("other applets in this file");
         tear.appendln("-------------------------------------");
         
         Enumeration enum = getAppletContext().getApplets();
         while( enum.hasMoreElements() )
         {
            Object app = enum.nextElement();
            if (app!=NameApplet.this)
               tear.appendln( app.getClass().getName() );
         } 
         tear.appendln("-------------------------------------");
         
         java.applet.Applet theApp = getAppletContext().getApplet("InfoApplet");
         tear.appendln("and this is my classname:");
         tear.appendln(theApp.getClass().getName() );
         tear.appendln("-------------------------------------");
         tear.setCaretPosition(-1);
      }
   }

   class ClearHandler implements ActionListener
   {
      public void actionPerformed(ActionEvent e)
      {
         tear.setText("");
      }
   }
}  // end class

Der im applet-tag vergebene name ist übrigens nicht case-sensitiv, doch sollte man ihn aus Sicherheitsgründen case-sensitiv verwenden.

Wie aber kann man Methoden aufrufen, die man zusätzlich in einer eigenen Appletklasse eingebaut hat ? Eine Möglichkeit zeigt das nächste Beispiel. Die drei Applets dieses Beispiels kommunizieren miteinander auf die folgende Weise: Jedes Applet kann an die anderen Applets ein Rundschreiben versenden, das in der JTextArea verfaßt werden kann und durch Buttondruck verschickt wird. Dabei ist es nicht entscheidend, das es sich um JApplets handelt.








Die drei Applets haben eine gemeinsame Oberklasse, die mit entsprechenden Methoden einen Zugriff auf die gezeigte JTextArea erlaubt. Über eine setText()-Methode kann man direkt in die JTextArea schreiben. Alle drei Applets erben diese Methode. Die Basisklasse heißt CommunicationApplet und sieht wie folgt aus. Die wichtigen Stellen sind rot hervorgehoben.

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

public class CommunicationApplet extends JApplet
{
   private JLabel label = new JLabel( getClass().getName() , SwingConstants.CENTER) ;
   private JButton infoButton = new JButton("info about other Applets");
   private JButton clearButton = new JButton("clear");
   private JButton sendButton = new JButton("send circular");
   private JPanel southPanel = new JPanel();
   private JTextArea2 tear = new JTextArea2();
   private JScrollPane sp = new JScrollPane(tear);
   private Container conPane = getContentPane();

   public void init()
   {
      initJMenuBar();
      initInfoButton();
      initMessageArea();
      initSouth();
   }

   private void initJMenuBar()
   {
      JMenuBar jmb = new JMenuBar();
      jmb.setLayout( new BorderLayout());
      setJMenuBar(jmb);
      jmb.add(label);

      label.setOpaque(true);
      label.setPreferredSize( new Dimension(100,24) ) ;
      //label.setBackground( new Color( 240, 240, 200 ) );
   }

   private void initInfoButton()
   {
      infoButton.setPreferredSize( new Dimension(100,22) ) ;
      infoButton.addActionListener( new InfoHandler() );
      conPane.add(infoButton, BorderLayout.NORTH);
   }

   private void initMessageArea()
   {
      conPane.add(sp, BorderLayout.CENTER);
   }

   private void initSouth()
   {
      southPanel.setLayout( new GridLayout() );

      clearButton.addActionListener( new ClearHandler() );
      southPanel.add(clearButton);

      sendButton.addActionListener( new MessageHandler() );
      southPanel.add(sendButton);

      conPane.add(southPanel, BorderLayout.SOUTH);
   }
   
   public void setText(String msg)
   {
      tear.setText(msg);
   }

   public void setTitleBackground(Color col)
   {
      label.setBackground(col);
   }
   
   class InfoHandler implements ActionListener
   {
      public void actionPerformed(ActionEvent e)
      {
         Enumeration enum = getAppletContext().getApplets();
         while( enum.hasMoreElements() )
         {
            Object app = enum.nextElement();
            if (app!=CommunicationApplet.this)
               tear.appendln( app.getClass().getName() );
         }
         tear.appendln("-------------------------------------");
         tear.setCaretPosition(-1);
      }
   }

   class ClearHandler implements ActionListener
   {
      public void actionPerformed(ActionEvent e)
      {
         tear.setText("");
      }
   }

   class MessageHandler implements ActionListener
   {
      public void actionPerformed(ActionEvent e)
      {
         Enumeration enum = getAppletContext().getApplets();
         String text = tear.getText() ;
         tear.setText("");
         while( enum.hasMoreElements() )
         {
            Object app = enum.nextElement();
            if ( app instanceof CommunicationApplet && app!=CommunicationApplet.this)
            {
               ((CommunicationApplet)app).setText(text);
               tear.appendln("message send: "+ app.getClass().getName() );
            }
         }
         tear.setCaretPosition(-1);
      }
   }
   
}  // end class

Die drei oben gezeigten Applets entstehen durch Ableitung aus dem CommunicationApplet

import java.awt.* ;

public class CommunicationApplet1 extends CommunicationApplet
{
   public void init()
   {
      super.init();
      setTitleBackground( new Color(240, 240, 200) );
   }

}  // end class

Analog für die beiden anderen Applets.

Kommunikation zwichen Applets über Dateigrenzen hinweg


Nicht selten hat man mehrere Browserfenster geöffnet und eine Kommunikation von Applets in den verschiedenen Browserinstanzen kann ein interessantes Feature sein. Falls ein Browser für mehrere seiner Instanzen dieselbe Javalaufzeitumgebung benützt ist das vermittels statischer Daten tatsächlich möglich. Das folgende bringt die Kerngedanken eines Artikels von Tobias Hill in

http://www.javaworld.com/javatips/jw-javatip101_p.html

Wieder sollen mehrere Applets miteinander kommunizieren. Wir schaffen uns einen Analogon zu den Methoden getApplet() und getApplets() auf statischer Ebene. Dazu führen wir eine Applettabelle ein, bei der sich jedes Applet registriert. Applets können mit statischen Methoden auf diese Tabelle zugreifen und Zeiger auf andere Applets erhalten. Die hier verwendete Appletliste erweitert diejenige von Tobias Hill um die Methode keys().

import java.util.*;
import java.applet.*;

public class AppletList
{
   private static Hashtable applets = new Hashtable();

   public static void register(String name, Applet applet)
   {
      applets.put(name,applet);
   }

   public static void remove(String name)
   {
      applets.remove(name);
   }
   
   public static Applet getApplet(String name)
   {
      return (Applet)applets.get(name);
   }

   public static Enumeration getApplets()
   {
      return applets.elements();
   }

   public static Enumeration keys()
   {
      return applets.keys();
   }
   
   public static int size()
   {
      return applets.size();
   }
}

Jedes Applet, das kommunizieren will, registriert sich in der init()-Methode in diese Liste. Um für die HashTable eine eindeutige ID zu erhalten verwenden wir die hashCode()-Methode. Auf diese Weise können wir sogar mehrere Instanzen des gleichen Applets unterscheiden

public void init()
{
   AppletList.register( getClass().getName() + "_" + hashCode(), this);
   // ...
}

Das folgende Beispiel zeigt die Kommunikation. Zwei Applets befinden sich in dieser Datei. Mit dem Link darunter lassen sich neue Browserfenster öffnen mit jeweils einer Instanz der gleichen Appletklasse.





neues Browserfenster mit Applet öffnen

top Back Next Up Home