JCombobox désactiver l'élément de sélection (faire des combos en lecture seule)
J'aimerais créer un readonly zone de liste déroulante. L'utilisateur ne doit pas être en mesure de sélectionner un autre élément de la liste déroulante. Cela signifie que la liste ne doit pas être ouverte ou doit être vide.
Je vois les solutions suivantes:
- Définir une zone de liste déroulante modèle avec un seul élément (l'élément sélectionné) ainsi, lorsque l'utilisateur clique sur le bouton de la flèche, d'une liste vide est présenté.
- Ajouter un
PopupMenuListener
et dans lepopupMenuWillBecomeVisible
masquer le menu. C'est problématique: Nous devons appelercombo.hidePopup();
de l'intérieur d'uneSwingUtilities.invokeLater()
Le vide d'un modèle d'approche semble un peu maladroit. La deuxième approche montre la liste déroulante pour une fraction de seconde, assez courte pour être remarqué. C'est très laid.
Est-il une troisième solution?
EDIT: solution mise en œuvre:
J'ai mis en œuvre la méthode proposée à partir de splungebob et voici mon code pour référence future:
private void makeComboReadonly() {
Component editorComponent = box.getEditor().getEditorComponent();
if (editorComponent instanceof JTextField) {
((JTextField) editorComponent).setEditable(false);
}
for (Component childComponent : box.getComponents()) {
if (childComponent instanceof AbstractButton) {
childComponent.setEnabled(false);
final MouseListener[] listeners = childComponent.getListeners(MouseListener.class);
for (MouseListener listener : listeners) {
childComponent.removeMouseListener(listener);
}
}
}
final MouseListener[] mouseListeners = box.getListeners(MouseListener.class);
for (MouseListener listener : mouseListeners) {
box.removeMouseListener(listener);
}
final KeyListener[] keyListeners = box.getListeners(KeyListener.class);
for (KeyListener keyListener : keyListeners) {
box.removeKeyListener(keyListener);
}
box.setFocusable(false);
//box.getActionMap().clear(); //no effect
//box.getInputMap().clear();
}
Le seul problème est l'Événement-Clé Alt-Bas qui oppens le menu pop-up, même si j'ai supprimer toutes les clés d'auditeurs et de préciser l'action de la carte. Je contourner ce problème en faisant le combo non peut recevoir le focus. Pas l'idéal, mais assez bon (-:
JLabel
ou un non modifiable JTextField
. J'ai pensé que vous voudriez une JComboBox
où les autres options sont visibles, mais vous ne pouvez pas changer l'sélectionnée, même si vous cliquez sur un autre élément de la liste.Un JLabel a une toute autre apparence d'un combo. Le champ n'est pas une option parce que le combo ne pas afficher le champ de texte. Je pense que son étrange si l'utilisateur clique sur un élément, mais rien ne se passe. Readonly composants n'ont généralement pas un indicateur visuel qu'ils sont en lecture seule. Je préfère une solution où le popup n'est pas affiché pour l'utilisateur en premier lieu.
Si, lorsque vous passez la souris sur un élément, il n'obtient aucun indice visuel qui est cliquable (typique de la couleur d'arrière-plan de changement), alors il ne serait pas étrange quand rien ne se passe. Je trouverais plus étrange qu'une zone de liste déroulante, qui est une entrée élément de l'INTERFACE utilisateur de choisir entre les différents éléments n'ont pas de n'importe quel élément, mais a "quelque chose" comme par magie sélectionné. De toute façon il y a 2 solutions faciles: remplacement de la peinture/appel de la pop-up ou juste créer un JComboBox avec seulement 1 point, celui que vous voulez.
Il n'y a aucun moyen de prévenir la liste déroulante pour être réellement ouvert?
Sur une note de côté, appelant hidePopup() à partir de invokeLater ou plutôt à partir de l'EDT n'est pas un problème, en fait, le problème serait de l'appeler à partir de l'extérieur de l'EDT.
OriginalL'auteur morpheus05 | 2014-05-06
Vous devez vous connecter pour publier un commentaire.
C'est effectivement une bonne question à propos de l'un de Swing limites (et m'énerve pour un long moment).
On aurait besoin d'un accès en lecture seule zone de liste déroulante quand... (wait for it)... la forme est actuellement en mode lecture seule. Notez que l'entrée de l'utilisateur elswhere peut retourner le formulaire dans le mode d'édition à la notification d'un moment, afin de changer d'JComponents (à l'aide d'un JLabel par exemple) ne serait pas visuellement souhaitable, de l'OMI. Notez également qu'une désactivé combo ne pas transmettre les mêmes informations à un utilisateur en lecture seule combo:
setEnabled(false)
-> entièrement grisé; le composant ne peut pas être en interaction avec; toutes les données peuvent être affichées est pas pertinentes et ne peut pas être sélectionné pour le Copier/Coller.setReadOnly(true)
-> texte de l'élément de zone de liste déroulante est pas grisé (mais la flèche est); le composant ne peut pas être en interaction avec; toutes les données peuvent être affichées est pertinentes et peut être sélectionné.Se justifie du fait que Balancer ne mettre en œuvre ce pour JTextComponents dans la forme de
setEditable(boolean)
. Merci les gars, mais j'ai aussi besoin pour JComboBox, JCheckbox, JRadioButton, etc. Nous avons dû rouler nos propres versions de ce manque d'API.Un autre Swing gaffe (IHMO) est l'incohérence de l'API.
JTextComponent.setEditable(boolean)
veille à l'application de lecture seule comportement, tandis que laJComboBox.setEditable(boolean)
ne pas.Arrrgh!!!
Donc, pour le problème. Tu dois retrousser vos manches un peu. Pour un modifiable combo:
Obtenir le combo est le composant de l'éditeur via
combo.getEditor().getEditorComponent()
. C'est un component swing jtextfield. Lancer, et d'appelersetEditable(false)
. Cela vous donne à la fois la fonctionnalité et l'apparence que vous voulez pour la partie texte de la liste déroulante.Obtenir le combo de la flèche composant par itération sur getComponents() de la liste déroulante. C'est la seule AbstractButton vous trouverez. Appel
setEnabled(false)
. C'est pour l'apparence seulement.Trouver tous les défaut de la souris auditeurs qui sont venus avec le combo (qui devrait être tous d'entre eux si vous n'avez pas d'ajouter tout de même) et les supprimer à la fois le combo et le bouton de la flèche.
De conserver une référence à ces auditeurs et le bouton de la flèche dans le cas où vous souhaitez changer de nouveau à lecture seule = false.
Ou quelque chose comme ça. Votre kilométrage peut varier.
De repère kleopatra avec une approbation pour SwingX, qui a probablement cette fonctionnalité déjà intégrée (je ne sais pas pour vous, je suis juste deviner).
Bonne chance.
OriginalL'auteur splungebob
Majeur:
devrait faire l'affaire.
OriginalL'auteur DSquare
Quoi de mal avec simplement désactivation la JComboBox?
OriginalL'auteur Durandal
J'ai eu une demande similaire. L'appel de
setEnabled(false)
donne un horrible apparence et l'utilisateur ne peut pas parcourir la liste déroulante. PrimordialshowPopup()
ne fonctionne pas. Essaie de l'écouter pour l'ouverture du menu, puis le fermer via invokeLater provoque le menu de flash, et encore, l'utilisateur ne peut pas parcourir le menu.En fin de compte je l'ai fait (en ne disant pas son parfait, mais il fait exactement ce que je voulais):
Vous devez appeler
setReadOnly(false)
sur leReadOnlyComboBox
avant le réglage de l'élément sélectionné par programmation si nécessaire, puis revenez à s'arrêter à l'utilisateur de faire des sélections.Note de la décoché cast, n'était pas un problème pour moi dans mon petit programme, mais ne devrait probablement remplacer le
setModel
de la méthode de jeter une exception si une tentative est faite pour l'utilisation de tout autre type de modèle.Edit: notez Aussi que l'action des auditeurs sont encore appelée (à l'identique de sélection).
OriginalL'auteur Duncan Macleod