Je souhaite implémenter une fonctionnalité de saisie semi-automatique. Actuellement, j'ai un JPanel contenant JTextField et, lorsque l'utilisateur commence à taper, une saisie semi-automatique (JPopupMenu) apparaît, contenant plusieurs options. Le problème est qu'il prend le focus à partir du champ de texte et que l'utilisateur ne peut plus taper. Lorsque je reviens sur le champ de texte, l'utilisateur n'a plus de navigation entre les options (en utilisant les boutons haut et bas). Avoir aussi l'accent sur le menu ne me permet pas d'intercepter son KeyListener (je ne sais pas pourquoi), et quand j'essaie de traiter l'entrée sur le champ de texte, j'ai des problèmes avec les éléments de menu.Implémentation de la saisie semi-automatique avec jtextfield et jpopupmenu
Alors que je veux avoir:
- Un menu contextuel avec des options qui change de manière dynamique lorsque l'utilisateur modifie le texte TextField, ayant menu actif
- encore L'utilisateur peut naviguer entre les options à l'aide et les touches fléchées , ainsi que les touches Entrée et Échap pour utiliser l'option ou fermer la fenêtre contextuelle respectivement.
Est-il possible de traiter les événements de clavier dans le menu et de renvoyer les événements de saisie au champ de texte?
Quelle est la bonne façon d'aborder mon problème?
Voici le code ci-dessous. Merci d'avance!
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
class TagVisual extends JPanel {
private JTextField editField;
public TagVisual() {
FlowLayout layout = new FlowLayout();
layout.setHgap(0);
layout.setVgap(0);
setLayout(layout);
editField = new JTextField();
editField.setBackground(Color.RED);
editField.setPreferredSize(new Dimension(200, 20));
editField.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
JPopupMenu menu = new JPopupMenu();
menu.add("Item 1");
menu.add("Item 2");
menu.add("Item 3");
menu.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
JOptionPane.showMessageDialog(TagVisual.this, "keyTyped");
}
@Override
public void keyPressed(KeyEvent e) {
JOptionPane.showMessageDialog(TagVisual.this, "keyPressed");
}
@Override
public void keyReleased(KeyEvent e) {
JOptionPane.showMessageDialog(TagVisual.this, "keyReleased");
}
});
menu.show(editField, 0, getHeight());
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
});
add(editField, FlowLayout.LEFT);
}
public void place(JPanel panel) {
panel.add(this);
editField.grabFocus();
}
}
public class MainWindow {
private JPanel mainPanel;
private JFrame frame;
public MainWindow(JFrame frame) {
mainPanel = new JPanel(new FlowLayout());
TagVisual v = new TagVisual();
v.place(mainPanel);
this.frame = frame;
}
public static void main(String[] args) {
JFrame frame = new JFrame("TextFieldPopupIssue");
frame.setContentPane(new MainWindow(frame).mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
Ou utilisez une bibliothèque tierce. Voir par exemple https://stackoverflow.com/q/14186955/1076463 – Robin