package elte.java2_utikalauz5.gui; /** Példaprogram a fókuszkezelés szemléltetésére. A felhasználói felület közepén egy szövegmező látható, ennek láthatóságát, engedélyezettségét és fókuszálhatóságát szabályozhatjuk a felette és mellette látható gombokkal (ezek feliratán az aktuális állapot is megjelenik). Ezen szövegmezőben naplózzuk a mező fókuszállapotának változása, valamint a globális fókuszváltozás figyelésének eredménye. Alul további hat nyomógomb látható, melyek egy saját megvalósítású fókuszléptetési körhöz tartoznak, amiből az Esc billentyű megnyomásával lehet kilépni. Feliratukon a fókuszléptetési körben elfoglalt helyük (sorszámuk, illetve külön jelöltük az első, utolsó és az alapértelmezett komponenst), valamint a fókuszléptetési kör tulajdonságai láthatóak (ezeket megnyomva a megfelelő tulajdonság megváltozik). A léptetés a gombokon látható sorszámok sorrendjében történik. A törlő gombra kattintva a központi szövegmező tartalma törlődik, valamint ezután egyik komponens sem marad fókuszált. A fókuszléptetési kör elejét, végét és alapértelmezett komponensét jelölő gombot megnyomva pedig a kör sorrendjének véletlenszerű összekeverését kérhetjük.

Érdemes a különböző állapotvezérlő gombok segítségével minden beállítható állapot esetén a szokásos (Tab) fókuszléptetés működését végigpróbálni. A kipróbálás során azt is észrevehetjük, hogy a többsoros szövegmezőben a fókuszváltáshoz a Ctrl módosítóbillenytűt is nyomva kell tartanunk, a Tab önmagában nem idéz elő fókuszváltást. @link.forrásfájl {@docRoot}/../data/gui/src FokuszTeszt.java @link.letöltés {@docRoot}/../data/gui FokuszTeszt.jar @see java.awt.KeyboardFocusManager @since Java 2 Útikalauz programozóknak 5.0 */ class FokuszTeszt extends java.awt.FocusTraversalPolicy implements java.beans.PropertyChangeListener, java.awt.event.FocusListener, java.awt.event.ActionListener { /** Szövegmező láthatóságát állító gomb */ private java.awt.Button látható = new java.awt.Button(); /** Szövegmező fókuszálhatóságát állító gomb */ private java.awt.Button fókuszálható = new java.awt.Button(); /** Szövegmező engedélyezettségét állító gomb */ private java.awt.Button engedélyezett = new java.awt.Button(); /** Eseménynaplózó szövegmező */ private java.awt.TextArea szöveg = new java.awt.TextArea() { private final static long serialVersionUID = 15L; //verziószám @Override public String toString() { //fix szöveges reprezentáció az exponenciális return "központi szövegmező"; //növekedés elkerülése érdekében } }; /** GUI-t felépítő konstruktor. @param felület a felhasználói felületet tartalmazó konténer */ private FokuszTeszt(java.awt.Container felület) { felület.setLayout(new java.awt.BorderLayout()); felület.add(szöveg); //központi szövegmező felvétele az ablakba felület.add(látható, java.awt.BorderLayout.NORTH); //vezérlő gombok látható.addActionListener( this ); felület.add(engedélyezett, java.awt.BorderLayout.WEST); engedélyezett.addActionListener( this ); felület.add(fókuszálható, java.awt.BorderLayout.EAST); fókuszálható.addActionListener( this ); java.awt.Panel gombpanel = new java.awt.Panel(); //fókuszkör gombjai felület.add(gombpanel, java.awt.BorderLayout.SOUTH); for (int i=1; i<=6; i++) { java.awt.Button gomb = new java.awt.Button(); gombpanel.add( gomb ); gomb.addActionListener( this ); } gombpanel.setFocusCycleRoot( true ); gombpanel.setFocusTraversalPolicy( this ); fókuszkör( gombpanel, false ); actionPerformed( null ); //kezdő állapot kijelzése } /** Nyomógomb megnyomásakor művelet elvégzése. @param esemény A gombnyomást reprezentáló eseményobjektum. */ public void actionPerformed(java.awt.event.ActionEvent esemény) { boolean fókuszál = esemény!=null; //kell-e fókuszálni a szövegmezőt if (fókuszál) { java.awt.Button gomb = (java.awt.Button)esemény.getSource(); if (gomb==látható) szöveg.setVisible(!szöveg.isVisible());//vezérlő- else if (gomb==engedélyezett) //gombok végrehajtása szöveg.setEnabled(!szöveg.isEnabled()); else if (gomb==fókuszálható) szöveg.setFocusable(!szöveg.isFocusable()); else { //fókuszléptetési kör gombjainak végrehajtása fókuszál = false; java.awt.Container konténer = gomb.getParent(); if (gomb==konténer.getComponent(sorrend[1])) konténer.setFocusCycleRoot(!konténer.isFocusCycleRoot()); else if (gomb==konténer.getComponent(sorrend[4])) konténer.setFocusTraversalPolicyProvider( !konténer.isFocusTraversalPolicyProvider()); else if (gomb==konténer.getComponent(sorrend[3])) { //törlés java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager(). clearGlobalFocusOwner(); szöveg.setText(null); } else fókuszál = true; //új fókuszléptetési kör kérése fókuszkör( gomb.getParent(), fókuszál ); fókuszál = false; } } //vezérlőgombok feliratainak beállítása látható.setLabel("isVisible="+szöveg.isVisible()); engedélyezett.setLabel("isEnabled="+szöveg.isEnabled()); fókuszálható.setLabel("isFocusable="+szöveg.isFocusable()); if (fókuszál) szöveg.requestFocus(); látható.getParent().validate(); //új feliratok miatt újraméretezés } /** Saját fókuszléptetési kör sorrendje */ private int sorrend[] = {0, 1, 2, 3, 4, 5}; /** Új fókuszléptetési kör megkeveréséhez véletlenszámgenerátor */ private java.util.Random véletlen = new java.util.Random(); /** Fókuszléptetési kör gombjainak feliratozása, igény esetén összekeverése. @param konténer A gombokat tartalmazó konténer. @param új Igaz értéke esetén új fókuszléptetési kör létrehozása. */ private void fókuszkör( java.awt.Container konténer, boolean új ) { if (új) for (int i=sorrend.length; i>1; i--) { //összekeverés int csere = sorrend[i-1]; int index = véletlen.nextInt( i ); sorrend[i-1] = sorrend[index]; sorrend[index] = csere; } //gombok feliratozása sorrendjüknek megfelelően java.awt.Button gomb=(java.awt.Button)konténer.getComponent(sorrend[0]); gomb.setLabel("1. (első)"); gomb = (java.awt.Button)konténer.getComponent(sorrend[1]); gomb.setLabel("2. (isFocusCycleRoot="+konténer.isFocusCycleRoot()+")"); gomb = (java.awt.Button)konténer.getComponent(sorrend[2]); gomb.setLabel("3. (alapértelmezett)"); gomb = (java.awt.Button)konténer.getComponent(sorrend[3]); gomb.setLabel("4. (törlés)"); gomb = (java.awt.Button)konténer.getComponent(sorrend[4]); gomb.setLabel("5. (isFocusTraversalPolicyProvider="+ konténer.isFocusTraversalPolicyProvider()+")"); gomb = (java.awt.Button)konténer.getComponent(sorrend[5]); gomb.setLabel("6. (utolsó)"); } /** Fókuszléptetési kör alapértelmezett komponensének lekérdezése. @param konténer Az aktuális konténer. @return A fókuszléptetési kör alapértelmezett komponense. */ @Override public java.awt.Component getDefaultComponent(java.awt.Container konténer) { return konténer.getComponent(sorrend[2]); } /** Fókuszléptetési kör első komponensének lekérdezése. @param konténer Az aktuális konténer. @return A fókuszléptetési kör első komponense. */ @Override public java.awt.Component getFirstComponent( java.awt.Container konténer ) { return konténer.getComponent(sorrend[0]); } /** Fókuszléptetési kör utolsó komponensének lekérdezése. @param konténer Az aktuális konténer. @return A fókuszléptetési kör utolsó komponense. */ @Override public java.awt.Component getLastComponent( java.awt.Container konténer ) { return konténer.getComponent(sorrend[5]); } /** Fókuszléptetési kör rákövetkező komponensének lekérdezése. @param konténer Az aktuális konténer. @param komponens Az aktuálisan fókuszált komponens. @return A fókuszléptetési kör alapján a következő komponens. */ @Override public java.awt.Component getComponentAfter( java.awt.Container konténer, java.awt.Component komponens ){ int index = 0; //aktuális index a fókuszléptetési körön belül while (konténer.getComponent(sorrend[index])!=komponens) index++; index++; //következő komponens if (index==konténer.getComponentCount()) //ha a kör végén túlléptünk, return getFirstComponent(konténer); //akkor az első visszaadása return konténer.getComponent(sorrend[index]); } /** Fókuszléptetési kör megelőző komponensének lekérdezése. @param konténer Az aktuális konténer. @param komponens Az aktuálisan fókuszált komponens. @return A fókuszléptetési kör alapján a megelőző komponens. */ @Override public java.awt.Component getComponentBefore( java.awt.Container konténer, java.awt.Component komponens){ int index = 0; //aktuális index a fókuszléptetési körön belül while (konténer.getComponent(sorrend[index])!=komponens) index++; index--; //előző komponens if (index<0) return getLastComponent(konténer);//túllépés: utolsó vissza return konténer.getComponent(sorrend[index]); } /** Központi szövegmező fókusz megszerzésének figyelése. @param fókuszesemény A fókusz eseményobjektum. */ public void focusGained( java.awt.event.FocusEvent fókuszesemény ) { szöveg.append(fókuszesemény+"\n"); //esemény naplózása } /** Központi szövegmező fókusz elvesztésének figyelése. @param fókuszesemény A fókusz eseményobjektum. */ public void focusLost( java.awt.event.FocusEvent fókuszesemény ) { szöveg.append(fókuszesemény+"\n"); //esemény naplózása } /** A központi fókuszkezelő fókusztulajdonos jellemzője változásának figyelése. @param esemény A változást tartalmazó eseményobjektum. */ public void propertyChange( java.beans.PropertyChangeEvent esemény ) { szöveg.append("Fókuszváltás: "+esemény.getOldValue()+//változás naplózása " -> "+esemény.getNewValue()+"\n"); } /** A grafikus felhasználói felület felépítése @param felület A felhasználói felületet tartalmazó konténer. @param argumentumok Az indításkor megadott paraméterek. */ public static void felépít( java.awt.Container felület, String argumentumok[]) { FokuszTeszt teszt = new FokuszTeszt( felület ); //GUI felépítése teszt.szöveg.addFocusListener( teszt ); //szövegmező fókuszfigyelése java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager()//globális .addPropertyChangeListener("focusOwner", teszt); //fókuszfigyelés java.util.Set billentyűk =//a felfelé léptetéshez new java.util.HashSet(1); billentyűk.add(java.awt.AWTKeyStroke.getAWTKeyStroke( //Esc használható java.awt.event.KeyEvent.VK_ESCAPE, 0)); java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager(). setDefaultFocusTraversalKeys( java.awt.KeyboardFocusManager. UP_CYCLE_TRAVERSAL_KEYS, billentyűk ); } /** A tesztprogram indítása. @param argumentumok Az indításkor megadott paraméterek. */ public static void main(String argumentumok[]) { java.awt.Frame ablak = new AblakTeszt.Ablak("Fókusz teszt"); felépít( ablak, argumentumok ); //felület felépítése ablak.setVisible(true); //és megjelenítése } }