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