JTextField & JPopupMenu

PeteProgram

Mitglied
Hallo

folgendes Problem kann ich nicht lösen:

Ich habe ein JTextField und füge diesem einen KeyListener hinzu. Durch keyReleased wird ein JPopupMenu, genauer ein BasicComboPopup geöffnet. Nun würde ich gerne über dieses PopupMenu mit den Cursortasten eine Auswahl treffen, leider bekommt das PopupMenu keinen Focus und ich kann es nicht mit der Tastatur verwenden.

requestFocus() als auch requestFocusInWindow() haben sowohl im Konstruktor als auch in keysReleased() nix gebracht.

Code:

Code:
package test.textfield;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.text.DefaultCaret;
public class TextFieldPopup extends BasicComboPopup {
 
 private static String[] items = {"eins","zwei","drei","vier","fünf"};
 
 public static JTextField jt = new JTextField(20); 
 
 public TextFieldPopup()  {
  super(new JComboBox(items));
 }
 public static void main(String[] args) {
  JFrame jf = new JFrame();
 
  jt.addKeyListener(new MyKeyListener());
  jf.getContentPane().add(jt);
 
  jf.pack();
  jf.setVisible(true);
 }
 
 static class MyKeyListener implements KeyListener  {
  public void keyTyped(KeyEvent e) {
  }
  public void keyPressed(KeyEvent e) {
  }
  public void keyReleased(KeyEvent e) {
   TextFieldPopup tfp = new TextFieldPopup();
   DefaultCaret bc = (DefaultCaret)jt.getCaret();
   tfp.show(jt,bc.x,bc.y);
  }
 }
}

sollte übrigens nicht daran liegen, das einige Felder und der Listener static sind, weil ich den Code für diese Frage fix zusammengebaut habe und ansonsten alles "nicht-static" ist.

weiß jemand ein Lösung?
 
Moin,

weiss nicht ob ich es richtig verstanden habe, wenn nicht, auch egal:

Hab deine ComboBox mal explizit erzeugt, und ihr nen zusätzlichen ActionListener zugewiesen, der das klicken auf dieser abfängt.


Java:
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.text.DefaultCaret;

import com.sun.corba.se.spi.orbutil.fsm.Action;
public class TextFieldPopup extends BasicComboPopup {
	
 private static String[] items = {"eins","zwei","drei","vier","fünf"};
 static JComboBox cbb=new JComboBox(items);
 public static JTextField jt = new JTextField(20); 
 
 public TextFieldPopup()  {
	 super(cbb);

 }
 public static void main(String[] args) {
  JFrame jf = new JFrame();
 
  jt.addKeyListener(new MyKeyListener());
  jf.getContentPane().add(jt);
 
  jf.pack();
  jf.setVisible(true);

   ActionListener AL=new ActionListener()
   {
	   public void actionPerformed(java.awt.event.ActionEvent arg0) 
	   {
		   //Was du mit dem Menüeintrag auch immer machen willst...
		   System.out.println(cbb.getSelectedItem().toString());
	   }
   };
   cbb.addActionListener(AL);
 }
 
 static class MyKeyListener implements KeyListener  {
  public void keyTyped(KeyEvent e) {
  }
  public void keyPressed(KeyEvent e) {
  }
  public void keyReleased(KeyEvent e) {
   TextFieldPopup tfp = new TextFieldPopup();
   DefaultCaret bc = (DefaultCaret)jt.getCaret();
   tfp.show(jt,bc.x,bc.y);

  }
 }
}

Wenns so passt: Bitte gern geschehen, Wenns daneben ging: *duckundweg*

grüße
Dom
 
Zuletzt bearbeitet von einem Moderator:
Moin ich noch mal,

deine Frage noch mal überdacht, bzw noch mal gelesen, das du das ganze mit den Tasten auswählen willst, grade keine Zeit nen Code zu basteln, aber das Problem liegt darin, das meiner Ansicht nach die Pfeiltasten auf der Textbox ebenfalls ein "KeyEvent" auslösen, somit wird quasi der Menüeintrag makiert, bzw der Menü Eintrag darunter oder darüber ausgewählt, dann aber ein neues PopUpMenü erzeugt (KeyEvent : release), in dem das erste Item wieder makiert ist.

Mfg
Dom
 
Ja das ist das Problem, es sollte sich rein theoretisch lösen, wenn das PopupMenu beim "Erscheinen" den Focus bekommen würde, weil dann (ebenfalls theoretisch) der KeyListener nix empfangen würde - oder?
 
Hallo Pete,

wie wärs mit einer Combobox mit Autovervollständigung, oder muss es unbedingt ein reines Textfeld sein?

Code:
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class ComboExtended extends JFrame implements KeyListener {

	String[] items = { "", "eins", "zwei", "drei", "vier", "fünf" };

	JList helplist = new JList(items);

	JTextComponent comboeditor;

	JComboBox combo = new JComboBox(items);

	public ComboExtended() {
		combo.setEditable(true);
		comboeditor = (JTextComponent) combo.getComponent(2);

		add(combo);

		comboeditor.addKeyListener(this);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
		setVisible(true);
	}

	public static void main(String[] args) {
		new ComboExtended();
	}

	public void keyTyped(KeyEvent e) {
	}

	public void keyPressed(KeyEvent e) {
	}

	public void keyReleased(KeyEvent e) {
		int index = -1;
		if (!comboeditor.getText().equals(""))
			index = helplist.getNextMatch(comboeditor.getText(), 1,
					Position.Bias.Forward);

		if (index != -1) {
			combo.setSelectedIndex(index);
			combo.showPopup();
		} else
			combo.hidePopup();
	}
}

Vg Erdal
 
Hallo Pete,

hier jetzt ein JTextField mit Popup:

Code:
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class TextFieldExtended extends JFrame implements KeyListener {

	String[] items = { "auto", "apfel", "rot", "regen", "birne", "blau",
			"benzin", "gelb","blaue"};

	JList list = new JList(items);

	JTextField textfeld = new JTextField(20);

	JScrollPane scroll = new JScrollPane(list);

	JPopupMenu pop = new JPopupMenu();
	
	DefaultCaret dcaret = (DefaultCaret) textfeld.getCaret();

	public TextFieldExtended() {

		list.setFocusable(false);
		scroll.getVerticalScrollBar().setFocusable(false);
		scroll.getHorizontalScrollBar().setFocusable(false);

		scroll.setBorder(null);
		pop.add(scroll);

		add(textfeld);

		setLocationByPlatform(true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
		setVisible(true);

		textfeld.addKeyListener(this);
		pop.addKeyListener(this);
	}

	public static void main(String[] args) {
		new TextFieldExtended();
	}

	public void keyTyped(KeyEvent e) {

	}

	public void keyPressed(KeyEvent e) {
	}

	public void keyReleased(KeyEvent e) {
		switch (e.getKeyCode()) {
		case KeyEvent.VK_DOWN:
			list.setSelectedIndex(list.getSelectedIndex() + 1);
			break;
		case KeyEvent.VK_UP:
			list.setSelectedIndex(list.getSelectedIndex() - 1);
			break;
		case KeyEvent.VK_ENTER:
			if (pop.isShowing())
				textfeld.setText(list.getSelectedValue().toString());
			break;
		default: {
			int index = -1;
			if (!textfeld.getText().equals(""))
				index = list.getNextMatch(textfeld.getText(), 1,
						Position.Bias.Forward);

			if (index != -1) {
				list.setSelectedIndex(index);
				pop.setLocation((int) textfeld.getLocationOnScreen().getX()
						+ dcaret.x, (int) textfeld.getLocationOnScreen().getY()
						+ textfeld.getHeight());
				pop
						.show(textfeld, dcaret.x, textfeld.getY()
								+ textfeld.getHeight());
			} else
				pop.setVisible(false);
			textfeld.requestFocus();

		}
		}
		if (list.getSelectedValue() != null
				&& list.getSelectedValue().equals(textfeld.getText()))
			pop.setVisible(false);
	}
}

Vg Erdal
 
Hallo Pete,

Wenn du genau hinschaust, im letzten Beispiel ist ein KeyListener integriert.


Vg Erdal
 
Okay - Entschuldige ich meinte Mouselistener, aber da Du nicht mit einer JComboBox (so wie ich) sondern mit einer JList gearbeitet hast, sollte man da die Mouseselection ganz einfach rausbekommen können.

Danke
 

Neue Beiträge

Zurück