package elte.java2_utikalauz5.chat; import java.awt.*; import java.awt.event.*; import java.applet.*; import java.rmi.*; import java.util.Hashtable; import java.util.Enumeration; /***** Java Chat Program - Felhasználói felület.

Használatakor ne feledjünk el a következő jogokat megadni!
grant signedBy "utikalauz" {
  permission java.net.SocketPermission "localhost", "connect,accept";
};
@link.forrásfájl {@docRoot}/../data/chat/src JavaChat.java @link.letöltés {@docRoot}/../data/chat JavaChat.jar @since Java 2 Útikalauz programozóknak 1.3 */ public class JavaChat extends Applet /* Java Chat applet. */ implements ActionListener, TextListener { /** Verziószám. */ private final static long serialVersionUID = 15L; /*** * Az appleten található ablakelemek. ***/ private TextArea Uzenetek; /* A beszélgetés folyása. */ private List Tarsak; /* A résztvevők listája. */ private TextField Uzenet; /* A küldendő üzenet. */ private Button Kuldes; /* Az üzenet elküldése. */ private TextField SajatNev; /* A felhasználó neve. */ private Button Belepes; /* Nyomógomb a belépéshez. */ private Button Kilepes; /* Nyomógomb a kilépéshez. */ private RMIChatClientIf Kli; /* Kliensoldali kommunikáció */ private RMIChatServerIf Srv; /* Szerveroldali kommunikáció */ private static String hn; /* Chatszerver számítógép neve */ /*** * Az applet konstruktora. * Létrehozza a szükséges felületelemeket. ***/ public JavaChat() { /* Konstruktormetódus */ super(); /* öröklött konstruktor hívása. */ /* Nem állítunk be LayoutManagert, mert az ablakban minden */ /* komponenst kézzel helyezünk el és méretezünk a setBounds */ /* metódus segítségével. */ setLayout(null); /* Nincs LayoutManager. */ setSize(400,355); /* Átméretezi az appletet. */ /* Létrehozza az ablakon található komponenseket. */ /* A fogadott üzeneteket megjelenítő szövegdoboz. */ Uzenetek = new TextArea(); /* Létrehozza, felrakja az */ add(Uzenetek); /* ablakra és elhelyezi a */ Uzenetek.setBounds(5,5,290,260); /* fogadott üzenetek dobozát*/ Uzenetek.setEditable(false); /* A szöveg csak olvasható. */ /* A beszélgetésben résztvevők nevét megjelenítő lista. */ Tarsak = new List(); /* Létrehozza, felrakja az */ add(Tarsak); /* ablakra és elhelyezi a */ Tarsak.setBounds(300,5,95,260); /* résztvevők listáját. */ /* Felirat a felhasználó üzenetét bekérő szövegdoboz fölött. */ Label L = new Label("Üzenet:"); /* Létrehoz egy feliratot, */ add(L); /* és felrakja az appletre. */ L.setBounds(5,270,290,20); /* A felirat méretezése. */ /* A felhasználó üzeneteit bekérő szövegmező. */ Uzenet = new TextField(); /* Létrehozza, felrakja az */ add(Uzenet); /* ablakra és elhelyezi az */ Uzenet.setBounds(5,290,290,30); /* üzenetbekérő szövegmezőt.*/ Uzenet.setEnabled(false); /* A belépésig nem üzenhet. */ /* Regisztrálja az objektumot az editor eseményfigyelőjének, */ /* hogy érzékeljük a szöveg megváltozását, így üres üzenet- */ /* editor esetén le tudjuk tiltani a küldés gombot, ha akarjuk */ /* Megjegyzés: a tényleges implementációban megengedjük üres */ /* sorok elküldését is, amit igényeink szerint letilthatunk. */ /* A programban a szerver szűri ki az üres sorokat. */ Uzenet.addTextListener(this); /* Szövegváltozás figyelése.*/ Uzenet.addActionListener(this); /* Return bill. figyelése. */ /* Az üzenet elküldésére szolgáló nyomógomb. */ Kuldes = new Button("Küldés"); /* Létrehozza, felrakja az */ add(Kuldes); /* ablakra és elhelyezi az */ Kuldes.setBounds(305,293,85,25); /* üzenetküldő nyomógombot. */ Kuldes.setEnabled(false); /* A belépésig nem üzenhet. */ /* Regisztrálja az objektumot eseményfigyelőnek, hogy reagálni */ /* tudjon a nyomógomb lenyomására. */ Kuldes.addActionListener(this); /* Return bill. figyelése. */ /* A felhasználó becenevének bekérésére szolgáló szövegmező. */ SajatNev = new TextField(); /* Létrehozza, felrakja az */ add(SajatNev); /* ablakra és elhelyezi a */ SajatNev.setBounds(5,322,200,30); /* névbekérő szövegmezőt. */ SajatNev.addTextListener(this); /* Szövegváltozás figyelése.*/ /* A felhasználó bejelentkezésére szolgáló nyomógomb. */ Belepes = new Button("Belépés"); /* Létrehozza, felrakja az */ add(Belepes); /* ablakra és elhelyezi a */ Belepes.setBounds(210,325,85,25); /* belépés-nyomógombot. */ Belepes.addActionListener(this); /* Gomblenyomás figyelése. */ Belepes.setEnabled(false); /* Be kell írni valami nevet*/ /* A felhasználó kijelentkezésére szolgáló nyomógomb. */ Kilepes = new Button("Kilépés"); /* Létrehozza, felrakja az */ add(Kilepes); /* ablakra és elhelyezi a */ Kilepes.setBounds(305,325,85,25); /* kilépés-nyomógombot. */ Kilepes.setEnabled(false); /* Amíg a felhasználó nem */ /* lépett be, addig kilépni sem lehet a beszélgetésből. */ Kilepes.addActionListener(this); /* Gomblenyomás figyelése. */ } /* JavaChat() */ /*** * Billentyűzet fókusz beállítása a program elején a becenév mezőre ***/ public void kezdeti_focus() /* Kezdetben a felhasználó */ { /* beceneve kell, oda irá- */ SajatNev.requestFocus(); /* nyítjuk a fókuszt, ezért */ } /* kezdeti_focus() */ /* a felhasználó oda ír ... */ /*** * Létrehozzuk a hálózati kommunikációt megvalósító objektumot ***/ private void com_init(boolean applet_e) /* Kommunikációs objektum */ { /* inicializálása */ try { if (applet_e) /* Appleteknél ahhoz a szer-*/ { /* verhez kapcsolódunk, */ hn=getCodeBase().getHost(); /* ahonnan letöltöttek ... */ if (hn == null) { System.err.println("Chatszerver host alapértelmezés: localhost"); hn="localhost"; /* Próba-szerencse :) */ } } Kli=RMIChatClient.init(this,applet_e); /* Létrehozzuk a kliensoldali */ /* kommunikációs objektumot */ Srv=(RMIChatServerIf) Naming.lookup("rmi://"+hn+"/DefaultChatSzoba"); /* Megkerestük a szerveroldali*/ /* kommunikációs objektumot */ } catch (java.lang.Exception e) { System.err.println("Szerveroldal nem érhetö el, várj amíg elindul!"); } } /* com_init() */ /*** * A nyomógombok lenyomására (akcióesemény) reagáló metódus. * Az Uzenet mezőben a Return billentyű lenyomásának kezelése is itt van. ***/ public void actionPerformed(ActionEvent e) { Object src = e.getSource(); /* Ezt a gombot nyomták le. */ if ((src==Kuldes)||(src==Uzenet)) /* Az üzenet elküldése. */ { /* A küldés nyomógomb lenyomására elküldi a begépelt üze- */ /* netet, és törli az üzeneteditor tartalmát. */ String uzenet = Uzenet.getText(); /* Az üzenet. */ Uzenet.setText(""); /* Törli a szövegmezőt. */ Uzenet.requestFocus(); /* Fókusz ismét Uzenet-re */ try { int resztvevok_szama = Srv.uzenetFogadas(SajatNev.getText(),uzenet); /*Üzenetet küld ...*/ /* Ha a résztvevők száma változott (pl. kiesett valaki), */ /* akkor újra feltöltjük a listaobjektumot a szerverről. */ if (resztvevok_szama != Tarsak.getItemCount()) { /* Valoszinuleg valaki bontott ... tarsak nevet ujraallitja */ Hashtable ujlista=Srv.nevlistaSzinkronizalas(); Tarsak.removeAll(); /* Törli a nevek listáját. */ Enumeration rvEnum=ujlista.keys(); while (rvEnum.hasMoreElements()) { String rnev=(String) rvEnum.nextElement(); Tarsak.add(rnev); } } } catch (java.rmi.RemoteException ex) { System.err.println("Komoly hiba történt - szerver elérhetetlen!"); } } else if (src==Belepes) { /* Bejelentkezés-gomb. */ SajatNev.setEnabled(false); /* A következő kilépésig */ Belepes.setEnabled(false); /* nem lehet újra belépni. */ Kilepes.setEnabled(true); /* Most már szabad kilépni. */ Uzenet.setEnabled(true); /* Most már írhat üzenetet. */ Uzenet.requestFocus(); /* csb */ /* Felveszi a felhasználó nevét a beszélgetők listájába. */ /* Bejelentkezés a chatszerverhez */ try { Srv.tarsBelepes(SajatNev.getText(),Kli); } catch (java.rmi.RemoteException ex) { System.out.println("Komoly hiba törtent - szerver elerhetetlen:"+ex); } } else if (src==Kilepes) { /* Kijelentkezés-gomb. */ SajatNev.setEnabled(true); /* Most már újra be lehet */ Belepes.setEnabled(true); /* lépni (más névvel is). */ Kilepes.setEnabled(false); /* Most nem szabad kilépni. */ Uzenet.setEnabled(false); /* Nem lehet üzenetet írni */ Kuldes.setEnabled(false); /* és küldeni. */ Uzenet.setText(""); /* Kiüríti a szövegmezőt. */ Tarsak.removeAll(); /* Törli a nevek listáját. */ /* Kijelentkezés a chatszerverből */ try { Srv.tarsKilepes(SajatNev.getText()); } catch (java.rmi.RemoteException ex) { System.out.println("Komoly hiba történt - szerver elérhetetlen!"); } } } /* actionPerformed() */ /*** * Az editorok szövegének megváltozására reagáló metódus. * Az editor tartalmát felhasználó nyomógomb (pl: bejelenkezés * a megadott néven vagy egy üzenet elküldése) csak akkor * engedélyezett, ha az editor szövege nem üres. ***/ public void textValueChanged(TextEvent e) { Object src = e.getSource(); /* Ez az editor változott. */ if (src==Uzenet) { /* Az elküldendő üzenet. */ String uzenet = Uzenet.getText(); boolean ures = uzenet.equals(""); Kuldes.setEnabled(!ures); } else if (src==SajatNev) { /* A felhasználó neve. */ String uzenet = SajatNev.getText(); boolean ures = uzenet.equals(""); Belepes.setEnabled(!ures); } } /* textValueChanged() */ /***** A kommunikációs modul az alábbi három eljárást hívja meg.*****/ /*** * Egy új üzenet érkezett a "nev" nevű felhasználótól. ***/ public void uzenetFogadas(String nev, String szoveg) { /* Hozzáadja az üzenetek szövegdobozához az új üzenetet. */ /* Az új üzenet után egy soremelés is kerül a szövegbe. */ Uzenetek.append(nev+": "+szoveg+"\n"); } /* uzenetFogadas() */ /*** * Egy új beszélgetőtárs belépése. * Az új belépő nevét felveszi a beszélgetőtársak listájába. ***/ public void tarsBelepes(String nev) { Tarsak.add(nev); /* Berakja a listába az új nevet. */ } /* tarsBelepes() */ /*** * Egy beszélgetőtárs kilépése. Törli a nevet a listából. ***/ public void tarsKilepes(String nev) { try { /* Eltávolítja a listából a megadott */ Tarsak.remove(nev); /* elemet. */ } catch (Exception E) { /* A remove művelet kivételt válthat, */ System.err.println(E); /* a kivételt kiírjuk a */ } /* szabványos hibakimenetre.*/ } /* tarsKilepes() */ /*** * Appleteknél a kommunikációs modul inicializálását itt végezzük el. ***/ public void init() { com_init(true); } /* init() */ /*** * Alkalmazásként indítja el a programot. * Létrehoz egy ablakot, és felrak rá egy JavaChat appletet. ***/ public static void main(String arg[]) { hn="localhost"; if (arg.length > 0) { hn=arg[0]; /* Ha megadtak egy chatszervert a parancssorba, oda megyünk */ } Frame Ablak = new Frame("Java Chat"); /* Létrehoz egy ablakot.*/ Ablak.setBounds(50,50,410,385); /* Az ablak helye és mérete.*/ JavaChat jco=new JavaChat(); /* Létrehoz egy appletet. */ Ablak.add(jco); /* Beteszi az ablakba. */ jco.com_init(false); /* Kommunikációs modul inic.*/ Ablak.setVisible(true); /* Megjeleníti az ablakot. */ jco.kezdeti_focus(); /* Becenév beadását várja. */ } /* main() */ }