J'ai une variable JComboBox
éditable qui contient une liste de valeurs à lettre unique. Pour cette raison, la liste déroulante est très petite.
Chaque lettre a une signification spéciale qui, parfois, n’est pas claire pour l’utilisateur lorsque les lettres sont rarement utilisées. À cause de cela, j'ai créé une variable ListCellRenderer
personnalisée qui indique la signification de chaque lettre de la liste déroulante.
Malheureusement, cette explication ne rentre pas dans la liste déroulante car elle est trop petite, car elle a la même largeur que la liste déroulante.
Est-il possible d'élargir la liste déroulante au-delà de la liste déroulante?
C'est ce que je veux réaliser:
---------------------
| Small JCombobox | V |
--------------------------------------------
| "Long item 1" |
--------------------------------------------
| "Long item 2" |
--------------------------------------------
| "Long item 3" |
--------------------------------------------
Je ne peux pas modifier la largeur de la liste déroulante car l'application est une reconstitution d'une ancienne application héritée dans laquelle certaines choses doivent être exactement comme avant. (Dans ce cas, la combobox doit conserver sa petite taille à tout prix)
Je crois que la seule façon de faire cela avec l'API publique est d'écrire une interface utilisateur personnalisée (il y a deux _ { bugs qui traitent de cela).
Si vous voulez juste quelque chose de rapide et sale, j'ai trouvé cette façon d'utiliser les détails d'implémentation pour le faire ( ici ):
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
JComboBox box = (JComboBox) e.getSource();
Object comp = box.getUI().getAccessibleChild(box, 0);
if (!(comp instanceof JPopupMenu)) return;
JComponent scrollPane = (JComponent) ((JPopupMenu) comp).getComponent(0);
Dimension size = new Dimension();
size.width = box.getPreferredSize().width;
size.height = scrollPane.getPreferredSize().height;
scrollPane.setPreferredSize(size);
// following line for Tiger
// scrollPane.setMaximumSize(size);
}
Mettez ceci dans un PopupMenuListener
et il pourrait travailler pour vous.
Ou vous pouvez utiliser le code du premier bogue lié :
class StyledComboBoxUI extends BasicComboBoxUI {
protected ComboPopup createPopup() {
BasicComboPopup popup = new BasicComboPopup(comboBox) {
@Override
protected Rectangle computePopupBounds(int px,int py,int pw,int ph) {
return super.computePopupBounds(
px,py,Math.max(comboBox.getPreferredSize().width,pw),ph
);
}
};
popup.getAccessibleContext().setAccessibleParent(comboBox);
return popup;
}
}
class StyledComboBox extends JComboBox {
public StyledComboBox() {
setUI(new StyledComboBoxUI());
}
}
J'aime un peu/ WideComboBox de Santhosh Kumar
Voici une excellente solution de Santhosh Kumar, sans avoir à vous soucier de l’interface utilisateur et d’autres choses désagréables comme celle-là!
http://www.jroller.com/santhosh/entry/make_jcombobox_popup_wide_enough
import javax.swing.*;
import Java.awt.*;
import Java.util.Vector;
// got this workaround from the following bug:
// http://bugs.Sun.com/bugdatabase/view_bug.do?bug_id=4618607
public class WideComboBox extends JComboBox{
public WideComboBox() {
}
public WideComboBox(final Object items[]){
super(items);
}
public WideComboBox(Vector items) {
super(items);
}
public WideComboBox(ComboBoxModel aModel) {
super(aModel);
}
private boolean layingOut = false;
public void doLayout(){
try{
layingOut = true;
super.doLayout();
}finally{
layingOut = false;
}
}
public Dimension getSize(){
Dimension dim = super.getSize();
if(!layingOut)
dim.width = Math.max(dim.width, getPreferredSize().width);
return dim;
}
}
Voici une belle solution de tutiez .
Avant de configurer la liste Dimension of popup, il en extrait le plus gros élément et calcule la largeur nécessaire pour l'afficher complètement.
public class WiderDropDownCombo extends JComboBox {
private String type;
private boolean layingOut = false;
private int widestLengh = 0;
private boolean wide = false;
public WiderDropDownCombo(Object[] objs) {
super(objs);
}
public boolean isWide() {
return wide;
}
// Setting the JComboBox wide
public void setWide(boolean wide) {
this.wide = wide;
widestLengh = getWidestItemWidth();
}
public Dimension getSize() {
Dimension dim = super.getSize();
if (!layingOut && isWide())
dim.width = Math.max(widestLengh, dim.width);
return dim;
}
public int getWidestItemWidth() {
int numOfItems = this.getItemCount();
Font font = this.getFont();
FontMetrics metrics = this.getFontMetrics(font);
int widest = 0;
for (int i = 0; i < numOfItems; i++) {
Object item = this.getItemAt(i);
int lineWidth = metrics.stringWidth(item.toString());
widest = Math.max(widest, lineWidth);
}
return widest + 5;
}
public void doLayout() {
try {
layingOut = true;
super.doLayout();
} finally {
layingOut = false;
}
}
public String getType() {
return type;
}
public void setType(String t) {
type = t;
}
public static void main(String[] args) {
String title = "Combo Test";
JFrame frame = new JFrame(title);
String[] items = {
"I need lot of width to be visible , oh am I visible now",
"I need lot of width to be visible , oh am I visible now" };
WiderDropDownCombo simpleCombo = new WiderDropDownCombo(items);
simpleCombo.setPreferredSize(new Dimension(180, 20));
simpleCombo.setWide(true);
JLabel label = new JLabel("Wider Drop Down Demo");
frame.getContentPane().add(simpleCombo, BorderLayout.NORTH);
frame.getContentPane().add(label, BorderLayout.SOUTH);
int width = 200;
int height = 150;
frame.setSize(width, height);
frame.setVisible(true);
}
}
Le code ci-dessus a déjà un principal pour un test rapide. Mais remarquez que l’énoncé ci-dessous peut être ajusté à environ20si vous souhaitez un défilement vertical.
return widest + 5;
J'espère que c'est utile pour référence future!
On dirait que vous aurez besoin d'écrire votre propre ComboBoxUI .
Il y a un bon exemple ici qui montre comment y parvenir.
Notez également que la méthode qui vous intéresserait probablement est la méthode createPopup()
. C'est la méthode qui crée la fenêtre contextuelle pour la liste déroulante et où vous pourrez la personnaliser.
Vous voudrez peut-être utiliser la méthode setSize()
.
combo.setSize(200, combo.getPreferredSize().height);
Ici vous avez un simple morceau de code sans extension JComboBox ni autre classe
Dans cet exemple, la fin de la liste est toujours 500. Vous pouvez également modifier la hauteur ou l'emplacement.
FaceCorrectiveReasonComboBox.getTextComponent().setUI(new BasicComboBoxUI() {
@Override protected ComboPopup createPopup() {
return new BasicComboPopup(comboBox) {
protected Rectangle computePopupBounds(int px,int py,int pw,int ph) {
return super.computePopupBounds(px, py, 500, ph);
}
};
}
});