Hallo,
ich habe ein JScrollPane, welches mehrere Objekte hat, die von JPanel erben. Das ganze soll so eine Art Liste sein, bei der man genau einen Eintrag auswählen kann.
Dieses JScrollPane wird mit mehreren JButtons in ein Fenster gepackt.
Ich möchte jetzt folgendes erreichen:
Man soll mit TAB und UMSCHALT+TAB zwischen den JButtons wechseln können. Wenn man von der Reihenfolge her auf das JScrollPane kommt, soll man die darin enthaltenen Objekte mit TAB und UMSCHALT+TAB ansteuern können, aber das JScrollPane nicht mehr verlassen können.
Erst mit STRG+TAB bzw. STRG+UMSCHALT+TAB soll man wieder auf den JButton vor bzw. nach dem JScrollPane kommen.
Das JScrollPane soll sich also so wie eine JTable verhalten, was den Fokus betrifft.
Ich habe es schon geschafft, daß man von den JButtons in die Liste springen kann, aber man braucht dafür 2 TAB-Schritte. (Es soll mit einem gehen). Aus der Liste kommt man auch nur mit 3 STRG+TAB-Schritten heraus, STRG+UMSCHALT+TAB funktioniert gar nicht. Beim Herauspringen aus der Liste bekommt auch nicht der nachfolgende JButton den Fokus, sondern der erste JButton im Fenster.
Ich habe schon mit der FocusTraversalPolicy herumgespielt, aber ich befürchte, daß ich da irgendwo ein schwerwiegendes Verständnisproblem bezüglich deren Funktionsweise habe.
Wie kriege ich es hin, daß sich das Programm so verhält, wie ich es oben beschrieben habe?
Hier mein Testprogramm:
Hier noch ein paar interessante Links:
Eigene FocusTraversalPolicy
The AWT Focus Subsystem
Ich hoffe, daß mir irgendjemand einen Stups in die richtige Richtung geben kann.
MfG
hansmueller
ich habe ein JScrollPane, welches mehrere Objekte hat, die von JPanel erben. Das ganze soll so eine Art Liste sein, bei der man genau einen Eintrag auswählen kann.
Dieses JScrollPane wird mit mehreren JButtons in ein Fenster gepackt.
Ich möchte jetzt folgendes erreichen:
Man soll mit TAB und UMSCHALT+TAB zwischen den JButtons wechseln können. Wenn man von der Reihenfolge her auf das JScrollPane kommt, soll man die darin enthaltenen Objekte mit TAB und UMSCHALT+TAB ansteuern können, aber das JScrollPane nicht mehr verlassen können.
Erst mit STRG+TAB bzw. STRG+UMSCHALT+TAB soll man wieder auf den JButton vor bzw. nach dem JScrollPane kommen.
Das JScrollPane soll sich also so wie eine JTable verhalten, was den Fokus betrifft.
Ich habe es schon geschafft, daß man von den JButtons in die Liste springen kann, aber man braucht dafür 2 TAB-Schritte. (Es soll mit einem gehen). Aus der Liste kommt man auch nur mit 3 STRG+TAB-Schritten heraus, STRG+UMSCHALT+TAB funktioniert gar nicht. Beim Herauspringen aus der Liste bekommt auch nicht der nachfolgende JButton den Fokus, sondern der erste JButton im Fenster.
Ich habe schon mit der FocusTraversalPolicy herumgespielt, aber ich befürchte, daß ich da irgendwo ein schwerwiegendes Verständnisproblem bezüglich deren Funktionsweise habe.
Wie kriege ich es hin, daß sich das Programm so verhält, wie ich es oben beschrieben habe?
Hier mein Testprogramm:
Java:
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.ContainerOrderFocusTraversalPolicy;
import java.awt.DefaultFocusTraversalPolicy;
import java.awt.Dimension;
import java.awt.FocusTraversalPolicy;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
public class MainProg
{
public static void main(String[] args)
{
MainProg x = new MainProg();
}
public MainProg()
{
JFrame Fenster = new JFrame("Test");
Fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Fenster.setLayout(new GridLayout(4, 1));
JButton btn1 = new JButton("Schaltfläche 1");
JButton btn2 = new JButton("Schaltfläche 2");
JButton btn3 = new JButton("Schaltfläche 3");
Auswahlflaeche af = new Auswahlflaeche();
//Fenster.setFocusTraversalPolicy(new DefaultFocusTraversalPolicy());
//Fenster.setFocusTraversalPolicy(new SkipContainerFocusTraversalPolicy(Fenster));
Fenster.add(btn1);
Fenster.add(btn2);
Fenster.add(af);
Fenster.add(btn3);
Fenster.pack();
Fenster.setVisible(true);
}
public class Auswahlflaeche extends JScrollPane
{
ListenerX lx;
Komponente k1, k2, k3, k4, k5;
JPanel Hauptflaeche;
public Auswahlflaeche()
{
this.setPreferredSize(new Dimension(400, 100));
Hauptflaeche = new JPanel();
Hauptflaeche.setLayout(new GridLayout(5, 1));
lx = new ListenerX();
k1 = new Komponente(Color.black);
k2 = new Komponente(Color.yellow);
k3 = new Komponente(Color.green);
k4 = new Komponente(Color.blue);
k5 = new Komponente(Color.white);
k1.addFocusListener(lx);
k2.addFocusListener(lx);
k3.addFocusListener(lx);
k4.addFocusListener(lx);
k5.addFocusListener(lx);
Hauptflaeche.add(k1);
Hauptflaeche.add(k2);
Hauptflaeche.add(k3);
Hauptflaeche.add(k4);
Hauptflaeche.add(k5);
this.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS);
this.setViewportView(Hauptflaeche);
this.setFocusable(true);
//Hauptflaeche.setFocusable(true);
this.setFocusCycleRoot(true);
//Hauptflaeche.setFocusTraversalPolicy(new DefaultFocusTraversalPolicy());
//this.setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy());
this.setFocusTraversalPolicy(new SkipContainerFocusTraversalPolicy(this));
System.out.println(this.isFocusCycleRoot());
System.out.println(this.isFocusTraversalPolicySet());
//this.setFocusTraversalPolicyProvider(true);
//Festlegung der Tasten für das Rückwärtsdurchlaufen der Liste
Set neuezTasten = new HashSet();
neuezTasten.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK));
//neuezTasten.add(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0));
this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, neuezTasten);
System.out.println(this.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
//Festlegung der Tasten für das Vorwärtsdurchlaufen der Liste
Set neuevTasten = new HashSet();
neuevTasten.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
//neuevTasten.add(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0));
this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, neuevTasten);
System.out.println(this.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
//Festlegung der Tasten für das Verlassen der Liste
Set neuezadKTasten = new HashSet();
neuezadKTasten.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_DOWN_MASK + InputEvent.SHIFT_DOWN_MASK ));
this.setFocusTraversalKeys(KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, neuezadKTasten);
System.out.println(this.getFocusTraversalKeys(KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS));
Set neuevadKTasten = new HashSet();
neuevadKTasten.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.CTRL_DOWN_MASK ));
this.setFocusTraversalKeys(KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, neuevadKTasten);
System.out.println(this.getFocusTraversalKeys(KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS));
}
public void mEintragauswaehlen(Komponente p_k)
{
for(int i = 0, n = Hauptflaeche.getComponentCount(); i < n; i++)
{
Hauptflaeche.getComponent(i).setBackground(Color.CYAN);
}
p_k.setBackground(Color.red);
}
public void mEintraghatFokus(Komponente p_k)
{
for(int i = 0, n = Hauptflaeche.getComponentCount(); i < n; i++)
{
((JLabel)((Komponente)Hauptflaeche.getComponent(i)).getComponent(0)).setText("Kein Fokus");
}
((JLabel)p_k.getComponent(0)).setText("Hat Fokus");
}
public class Komponente extends JPanel
{
public Komponente(Color p_Farbe)
{
this.setPreferredSize(new Dimension(300, 30));
this.setBorder(BorderFactory.createLineBorder(p_Farbe, 5));
this.setOpaque(true);
this.setBackground(Color.CYAN);
this.setFocusable(true);
this.add(new JLabel("Kein Fokus"));
}
}
class ListenerX implements FocusListener
{
@Override
public void focusGained(FocusEvent e)
{
mEintragauswaehlen((Komponente)e.getSource());
mEintraghatFokus((Komponente)e.getSource());
}
@Override
public void focusLost(FocusEvent e)
{
((JLabel)(((Komponente)e.getSource()).getComponent(0))).setText("Fokus verloren");
}
}
public class SkipContainerFocusTraversalPolicy extends ContainerOrderFocusTraversalPolicy
{
Container focusCycleRoot;
public SkipContainerFocusTraversalPolicy(Container toSkip)
{
focusCycleRoot = toSkip;
}
protected boolean accept(Component com)
{
if(com == focusCycleRoot)
{
System.out.println("Abgelehnt da CycleRoot");
return false;
}
else
{
if(com instanceof Komponente)
{
System.out.println("Akzeptiert");
return super.accept(com);
}
else
{
System.out.println("Abgelehnt da keine Komponente");
return false;
}
}
}
}
}
}
Eigene FocusTraversalPolicy
The AWT Focus Subsystem
Ich hoffe, daß mir irgendjemand einen Stups in die richtige Richtung geben kann.
MfG
hansmueller