Swing Problem mit Focus setzen

Status
Nicht offen für weitere Antworten.

Verjigorm

Top Contributor
Hallo,

ich wollte mal fragen, wie man einer bestimmten Komponente zuverlässig den Focus gibt.
Im Beispiel unten hat die (blöde) JCombobox immer den Fokus, egal wie rum ich die Komponenten zum JPanel adde oder sonstwas aufrufe.
Ich habe es mit grabFocus() und requestFocus() an allen möglichen Stellen versucht, aber es wollte einfach nicht so wie ich möchte.
Erst setFocusable(false) auf die JCombobox hat das Problem gelöst, aber irgendwie nicht zu meiner Zufriedenheit, da ich denke, dass muss doch irgendwie anders gehen.


Folgendes KSKB zeigt mein Problem:

Code:
import java.awt.GridLayout;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class FocusTest {

	public static void main(String[] args) 
	{
		JFrame frame = new JFrame();
		
		JPanel panel = new JPanel();
		panel.setLayout(new GridLayout(1,2));
		
		JComboBox box = new JComboBox();
		box.addItem("1");
		box.addItem("2");
		box.addItem("3");
		JTextField text = new JTextField();
		
		panel.add(box);
		panel.add(text);
		
		text.grabFocus();
		text.requestFocus();
//		box.setFocusable(false); // <<<<<-------- hilft, aber unschön oder?
		
		frame.setContentPane(panel);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocationRelativeTo(null);
		frame.setSize(200, 50);
		frame.setVisible(true);
	}

}

mfg Verjigorm
 
Ok mein Beispiel ist falsch gewählt, bei meinem eigentlichen Problem geht es um einen modalen Dialog und da geht das eindeutig nicht

Code:
import java.awt.GridLayout;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class FocusTest {

	public static void main(String[] args) 
	{
		JDialog dialog = new JDialog();
		
		JPanel panel = new JPanel();
		panel.setLayout(new GridLayout(1,2));
		
		JComboBox box = new JComboBox();
		box.addItem("1");
		box.addItem("2");
		box.addItem("3");
		JTextField text = new JTextField();
		
		panel.add(box);
		panel.add(text);
		
		dialog.setContentPane(panel);
		dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		dialog.setLocationRelativeTo(null);
		dialog.setSize(200, 50);
		dialog.setModal(true);
		dialog.setVisible(true);
		text.requestFocus();
	}
}
 
Du bist gemein jetzt hab ich mich so gefreut... 🙁

Ähm ja. Was mir grade aufgefallen ist, ist, dass setModal() dafür verantwortlich ist... Allerdings nehme ich an, dass das benötigt wird. Von dem her is die einzige andere mir bekannte Möglichkeit das Textfeld zuerst zu adden 😉

Mehr weiß ich leider nicht... 🙁
 
Die Alternative ist, eine eigene FocusTraversalPolicy auf den Dialog zu schrauben. Das ist aber vergleichsweise kompliziert. Daher würde ich -- sofern möglich -- auch einfach das Textfeld zuerst hinzufügen. Falls Du Dich mit FocusTraversalPolicy herumärgern möchtest: Sun Java™ Tutorial: Customizing Focus Traversal.

Nachtrag: Wenn es mit der Reihenfolge nicht funktioniert, könnte es daran liegen, dass Swing klüger sein möchte als Du. In dem Fall ärgert Dich die LayoutFocusTraversalPolicy und Du willst eventuell statt derer die ContainerOrderFocusTraversalPolicy auf das RootPane des Dialogs setzen.

Ebenius
 
Zuletzt bearbeitet:
Nachtrag: Wenn es mit der Reihenfolge nicht funktioniert, könnte es daran liegen, dass Swing klüger sein möchte als Du.

Ich habs zuhause bei einem einfachen Dialog ausprobiert, da gehts wenn ich die Komponente als erstes adde.
Aber das Problem auf der Arbeit konnte ich auch damit nicht lösen, ich muss morgen nochmal das Ganze genauer anschauen, ist ein etwas komplizierterer Dialog.
 
Hi
ich hatte bei einem modalen JDialog ein ähnliches Problem. Die .requestFocus() Methode muss definitiv NACH .setVisible() aufgerufen werden. Ich habe das Problem durch einen WindowsFocusListener gelöst. Sprich wenn das Fenster den focus bekommt kann man diesen einer bestimmten componente geben.

Java:
this.addWindowFocusListener(new WindowFocusListener() {
	public void windowLostFocus(WindowEvent evt) {
	}
	public void windowGainedFocus(WindowEvent evt) {
		jtf.requestFocus();
	}
});
Eventuell bekommt die komponente auch dann den focus wenn man das fenster zwischendurch mal wechselt. Dies müsste man dann durch eine weitere Prüfung abfangen. Bei mit allerdings unwichtig. 🙂
mfg nathon
 
Ich habe das Problem durch einen WindowsFocusListener gelöst.
Schöner ist's so:
Java:
public static void main(String[] args) {
  final JPanel contentPane = new JPanel(new GridLayout(6, 6, 6, 6));
  for (int i = 0; i < 35; i++) {
    contentPane.add(new JButton("#"));
  }
  final JButton focusedButton = new JButton("Focused");
  contentPane.add(focusedButton, 17);

  final JDialog d = new JDialog((Frame) null, "Test Frame: A");

  final FocusTraversalPolicy orgFocusPolicy = d.getFocusTraversalPolicy();
  d.setFocusTraversalPolicy(new FocusTraversalPolicy() {

    @Override
    public Component getDefaultComponent(Container container) {
      return focusedButton;
    }

    @Override
    public Component getFirstComponent(Container container) {
      return orgFocusPolicy.getFirstComponent(container);
    }

    @Override
    public Component getLastComponent(Container container) {
      return orgFocusPolicy.getLastComponent(container);
    }

    @Override
    public Component getComponentBefore(
          Container container,
          Component component) {
      return orgFocusPolicy.getComponentBefore(container, component);
    }

    @Override
    public Component getComponentAfter(
          Container container,
          Component component) {
      return orgFocusPolicy.getComponentAfter(container, component);
    }
  });

  d.setModal(true);
  d.setContentPane(contentPane);
  d.pack();
  d.setLocationRelativeTo(null);
  d.setVisible(true);
  System.exit(0);
}
Ebenius
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben