Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
bei vielen Anwendungen wird der Text in einem Textfeld makiert wenn man mit Tab rein springt. Wenn man mit der Maus reinklickt dann jedoch nicht. Ist sowas mit JTextfield auch möglich? wenn ich in focusGained selectAll() mache dann wird das auch bei einem maus klick passieren
Mhm...vllt gibts da was, aber ansonsten könntest du doch auch einfach den FocusListener UND MouseListener benutzen.
Also bei mousePressed setzt du ein boolean "clicked" oder so auf true...im focusGained überprüfst du ob !clicked --> selectAll()
bei focusLost setzt du clicked wieder auf false.
Evtl. irgendwie so:
Java:
feld.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
clicked = false;
}
@Override
public void focusGained(FocusEvent e) {
if (!clicked)
feld.selectAll();
}
});
feld.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
clicked = true;
}
});
Mhm...vllt gibts da was, aber ansonsten könntest du doch auch einfach den FocusListener UND MouseListener benutzen.
Also bei mousePressed setzt du ein boolean "clicked" oder so auf true...im focusGained überprüfst du ob !clicked --> selectAll()
bei focusLost setzt du clicked wieder auf false.
Evtl. irgendwie so:
Java:
feld.addFocusListener(new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
clicked = false;
}
@Override
public void focusGained(FocusEvent e) {
if (!clicked)
feld.selectAll();
}
});
feld.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
clicked = true;
}
});
Den einzigen Unterschied den ich jetzt beim FocusEvent erkennen kann, ist, dass wenn durch TAB der Fokus erlangt wird, [c]cause=TRAVERSAL_FORWARD[/c] ist, beim Mausklick allerdings [c]cause=UNKNOWN[/c]. Vllt. kann man sich darüber irgendwas basteln, woher jetzt aber das cause genau stammt, weiß ich auch nicht
Den einzigen Unterschied den ich jetzt beim FocusEvent erkennen kann, ist, dass wenn durch TAB der Fokus erlangt wird, [c]cause=TRAVERSAL_FORWARD[/c] ist, beim Mausklick allerdings [c]cause=UNKNOWN[/c]. Vllt. kann man sich darüber irgendwas basteln, woher jetzt aber das cause genau stammt, weiß ich auch nicht
Aber wie gesagt, ich weiß weder was genau das ist/woher es stammt(vllt weiß da ja jmd mehr), war mir halt nur so aufgefallen.
Allerdings hat das wohl nur Allgemein damit zu tun, wie der Fokus erlangt wurde und ob man jetzt darauf dann auf eine Komponente schließen kann - da bin ich mir eher nicht so sicher ;(
Wenn das Textfeld jetzt beispielsweise zu Beginn direkt den Fokus bekommt ist cause auch = ACTIVATION
Also ich glaube das ist wohl eher der falsche Weg...
Eine wirklich tolle Lösung habe ich nicht, aber immerhin ein Workaround: Wenn du deinem Fenster eine eigene FocusTraversalPolicy verpasst, kannst du darin reagieren. Etwa so (Vorsicht, nicht getestet... ):
Java:
public class MyFocusPolicy extends FocusTraversalPolicy
{
private FocusTraversalPolicy defaultPolicy = null;
public MyFocusPolicy()
{
super();
defaultPolicy = KeyboardFocusManager.getCurrentKeyboardFocusManager()
.getDefaultFocusTraversalPolicy();
}
@Override
public Component getComponentAfter( Container container, Component component )
{
Component comp = defaultPolicy.getComponentAfter(container, component);
if (comp instanceof JTextComponent)
((JTextComponent) comp).selectAll();
return comp;
}
// analog für die anderen Methoden der Policy
}
Dann für dein Fenster irgendwo zu Beginn die eigene Policy setzen:
Java:
public class MyWindow extends JFrame
{
public MyWindow()
{
//...
this.setFocusCycleRoot(true); // muss gesetzt sein, sonst keine Fokus-Traversals
this.setFocusTraversalPolicy(new MyFocusPolicy());
}
}
Also das Thema lässt mich nicht los, weil ichs auch für mein Projekt gut brauchen könnte. Ich habe hier und da etwas gefunden, aber leider nicht DIE Lösung. Daher möchte ich die Ergebnisse hier mal posten und vielleicht helfen sie anderen als Denkanstoß und bringen uns so zu einer guten Lösung... *hoff*
Schmutzige Variante
Ich habe mir das "cause" von eRaaaas Entdeckung angeschaut und festgestellt, dass es aus einem Sun-Event kommt. Die FocusEvents aus dem FocusListener sind tatsächlich vom Typ
Code:
sun.awt.CausedFocusEvent
und die haben eine Methode
Code:
getCause()
womit man abfragen kann, woher der Fokuswechsel kommt. Im Falle von Tastendrücken kann man hier also ein
Code:
selectAll()
aufrufen. ABER ... Sun-Klassen direkt benutzen ist böse!
Java:
textfield.addFocusListener(new FocusAdapter()
{
public void focusGained(FocusEvent event)
{
CausedFocusEvent ce = (CauseFocusEvent) event;
System.out.println("focusGained by "+ce.getCause());
...
}
});
Die fast einfache Variante
Ich habe mit den KeyboardFocusManager mal angeschaut. Hier im
Code:
dispatchEvent(AWTEvent)
was eigenes reinmachen halte ich für zu umständlich und unsicher. Aber es gibt eine andere, nette Eigenschaft:
Java:
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addPropertyChangeListener("focusOwner", new PropertyChangeListener()
{
@Override
public void propertyChange( PropertyChangeEvent evt )
{
if (evt.getNewValue() instanceof JTextComponent)
{
JTextComponent text = (JTextComponent) evt.getNewValue();
if (text.isEditable())
text.selectAll();
}
});
(Quelle: Swing: Select text on focus gain)
Damit bekommt man es hin, dass man nicht für jedes Textfeld einen Focuslistener setzen muss, sondern es gleich anwendungsweit für alle JTextComponents hat. Allerdings reagiert es auf mausbasierten sowie auf tastaturbasierten Fokuswechsel.
funktionierende Variante
Weiterhin im Zshg mit dem KeyboardFocusManager habe ich mit KeyEventDispatcher und KeyEventPostProcessor (kann man jeweils via einer
Code:
add()
-Methode an den KeyboardFocusManager hängen) beschäftigt. Man bekommt leicht raus, ob eine ein sog. FocusTraversalKey gedrückt wurde, allerdings muss man den Fokusnachfolger erfragen, da im KeyEvent nur der aktuelle Fokusinhaber benannt ist. Das kommt mir... nun ja, umständlich vor, aber ingesamt geht es bisher am besten:
Java:
class FocusSelectioner implements KeyEventPostProcessor
{
private Set<AWTKeyStroke> forwardKeys = null;
private Set<AWTKeyStroke> backwardKeys = null;
public FocusSelectioner()
{
super();
KeyboardFocusManager mgr = KeyboardFocusManager.getCurrentKeyboardFocusManager();
forwardKeys = mgr.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
backwardKeys = mgr.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
}
@Override
public boolean postProcessKeyEvent(KeyEvent event)
{
if (event.getID() != KeyEvent.KEY_PRESSED)
return false;
final Component comp = event.getComponent();
final Container root = comp.getFocusCycleRootAncestor();
final AWTKeyStroke strk = AWTKeyStroke.getAWTKeyStrokeForEvent(event);
final FocusTraversalPolicy policy = root.getFocusTraversalPolicy();
if (strk != null && policy != null)
{
if (forwardKeys.contains(strk))
{
final Component next = policy.getComponentAfter(root, comp);
if (next instanceof JTextComponent)
((JTextComponent) next).selectAll();
} //if fokus vor
else if (backwardKeys.contains(strk))
{
final Component prev = policy.getComponentBefore(root, comp);
if (prev instanceof JTextComponent)
((JTextComponent) prev).selectAll();
} //if fokus zurück
}
return false;
}
}
// ... im Hauptprogramm...
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventPostProcessor(new FocusSelectioner());
Problem sehe ich hier u.A. darin, dass man
Code:
.getDefaultFocusTraversalKeys()
macht, was spezifische Tasten nicht beachtet.
Nun, damit bin auch ich in der Sackgasse und höre mir gerne alle Anmerkungen an
Vielleicht hat SirWayne sogar was davon