Da diese Focus-Geschichten manchmal recht verwirrend sein können hier mal eine kurze Anleitung wie man es machen könnte.
Focus setzen
In erster Linie gibt es mal 2 Befehle die einem den Focus verschaffen können:
JComponent.requestFocus
Verschafft einem den Focus und dem ParentFenster auch (falls dieses den Focus noch nicht hat).
JComponent.requestFocusInWindow()
Verschafft einem den Focus wenn das ParentFenster bereits den Focus besitzt (ansonsten nicht).
Ein großes Problem stellt sich zeitweise unter Linux da.
Gleich nachdem man das Fenster sieht, hat nichts einen Focus. Aber wenn man ganz schnell hinsieht, hat man gesehen dass die Komponente der man eigentlich gesagt hat, du sollst den Focus haben ganz kurz den Focus hat und dann wieder nicht.
Soweit ich das rausgefunden habe, ist das so, weil er mit dem Zeichnen nicht so nachkommt und die Komponente zwar zuerst den Focus hat, Linux (bzw KDE 3.0) das ganze aber erst neu zeichnen lässt und somit das ganze Fenster den Focus besitzt (also mehr keine Komponente).
Dieses Problem kann man entweder kompliziert mit synchronized und notfiyAll oder mit einem Timer (die etwas unsaubere Lösung).
Gegebenenfalls sollte man einen Timer nach der letzten add Methode aufrufen, der dann einem den Focus setzt.
Für die Methoden mit synchronized könnte man so vorgehen.
Synchronized Focus setzen
Zuerst überschreibt man die paint - Methode
Am Ende (also nachdem man show gesagt hat) fügt man noch diese Zeilen hinzu (macht man es vorher, wird nie etwas aufgebaut).
Focusreihenfolge setzen
Um eine gewisse Focus-Reihenfolge festlegen zu können gab es früher mal die Methoden
JComponent.setNextFocusableComponent
Diese wurde aber durch die FocusTraversalPolicy ersetzt.
Aber wie kann man diese benutzen?
In meinem Bsp. setzt die FocusTraversalPolicy einfach die sequentiellie Reihenfolge fest. Man könnte es aber je nach Bedarf abändern und sich seine Reihenfolge selbst zusammenbauen oder nach bestimmten Abfragekriterien weiterverarbeiten (zB isEnabled(), oder dergleichen).
Man schreibt sich einfach eine Funktion die einem die FocusTraversalPolicy zurückgibt.
Bsp.:
Diese Funktion gibt jetzt einfach die FocusTravesalPolicy zurück die für die übergebenen Komponenten erstellt worden sind.
Aufruf:
Focus setzen
In erster Linie gibt es mal 2 Befehle die einem den Focus verschaffen können:
JComponent.requestFocus
Verschafft einem den Focus und dem ParentFenster auch (falls dieses den Focus noch nicht hat).
JComponent.requestFocusInWindow()
Verschafft einem den Focus wenn das ParentFenster bereits den Focus besitzt (ansonsten nicht).
Ein großes Problem stellt sich zeitweise unter Linux da.
Gleich nachdem man das Fenster sieht, hat nichts einen Focus. Aber wenn man ganz schnell hinsieht, hat man gesehen dass die Komponente der man eigentlich gesagt hat, du sollst den Focus haben ganz kurz den Focus hat und dann wieder nicht.
Soweit ich das rausgefunden habe, ist das so, weil er mit dem Zeichnen nicht so nachkommt und die Komponente zwar zuerst den Focus hat, Linux (bzw KDE 3.0) das ganze aber erst neu zeichnen lässt und somit das ganze Fenster den Focus besitzt (also mehr keine Komponente).
Dieses Problem kann man entweder kompliziert mit synchronized und notfiyAll oder mit einem Timer (die etwas unsaubere Lösung).
Gegebenenfalls sollte man einen Timer nach der letzten add Methode aufrufen, der dann einem den Focus setzt.
Für die Methoden mit synchronized könnte man so vorgehen.
Synchronized Focus setzen
Zuerst überschreibt man die paint - Methode
Code:
/**************************************************************************
* Ueberschriebene paint Methode
* @param g Graphics
*************************************************************************/
public void paint(Graphics g)
{
super.paint(g);
if (! bPaintCalled) <--boolsche Klassenvariable die am Anfang false gesetzt wird
{
bPaintCalled = true;
synchronized (this) { notifyAll();
}
}
}
Am Ende (also nachdem man show gesagt hat) fügt man noch diese Zeilen hinzu (macht man es vorher, wird nie etwas aufgebaut).
Code:
if (! EventQueue.isDispatchThread()) {
synchronized (this) {
while (! this.bPaintCalled) { //<- solange bPaintCalled nicht fertig aufgerufen wurde (solange ist es false)
try {
this.wait(); <-- solange warte
} catch (InterruptedException e) {}
}
JComponet.requestFocus(); //<-- und hier dann der Komponente den Focus verschaffen
}
}
Focusreihenfolge setzen
Um eine gewisse Focus-Reihenfolge festlegen zu können gab es früher mal die Methoden
JComponent.setNextFocusableComponent
Diese wurde aber durch die FocusTraversalPolicy ersetzt.
Aber wie kann man diese benutzen?
In meinem Bsp. setzt die FocusTraversalPolicy einfach die sequentiellie Reihenfolge fest. Man könnte es aber je nach Bedarf abändern und sich seine Reihenfolge selbst zusammenbauen oder nach bestimmten Abfragekriterien weiterverarbeiten (zB isEnabled(), oder dergleichen).
Man schreibt sich einfach eine Funktion die einem die FocusTraversalPolicy zurückgibt.
Bsp.:
Code:
/****************************************************************************
* Gibt die Reihenfolge der in order[] gespeicherten Componenten als FocusTraversalPolicy Objekt zurück
* @param order sind die Componenten in richtiger Reihenfolge und notfalls muss eine Typkonvertierung
* mittels (JComponent) durchgeführt werden
* @return das Objekt mit dem man mit setFocusTraversalPolicy(FocsTraersalPolicy) und aktivieren mit
* setFocusCycleRoot(true)
***************************************************************************/
public static FocusTraversalPolicy getFocusTraversal(final JComponent order[])
{
FocusTraversalPolicy policy = new FocusTraversalPolicy()
{
java.util.List list = java.util.Arrays.asList(order);
public java.awt.Component getFirstComponent(java.awt.Container
focusCycleRoot)
{
return order[0];
}
public java.awt.Component getLastComponent(java.awt.Container
focusCycleRoot)
{
return order[order.length - 1];
}
public java.awt.Component getComponentAfter(java.awt.Container
focusCycleRoot,
java.awt.Component aComponent)
{
int index = list.indexOf(aComponent);
return order[ (index + 1) % order.length];
}
public java.awt.Component getComponentBefore(java.awt.Container
focusCycleRoot,
java.awt.Component aComponent)
{
int index = list.indexOf(aComponent);
return order[ (index - 1 + order.length) % order.length];
}
public java.awt.Component getDefaultComponent(java.awt.Container
focusCycleRoot)
{
return order[0];
}
public java.awt.Component getInitialComponent(java.awt.Window window)
{
return order[0];
}
};
return policy;
}
Diese Funktion gibt jetzt einfach die FocusTravesalPolicy zurück die für die übergebenen Komponenten erstellt worden sind.
Aufruf:
Code:
/*Setzt die richtige Tabulatorenreihenfolge */
FocusTraversalPolicy policy = getFocusTraversal(
new JComponent[]
{button1, textfield1, button3,textarea1}); //hier alles eintragen was man focussieren will
setFocusTraversalPolicy(policy); //setzen
setFocusCycleRoot(true);//enablen