2009-08-28 3 views
2

Je tente de définir une largeur minimale pour mes éléments de menu, mais cela ne semble pas fonctionner. Voici ma fonction, qui crée les éléments:JMenuItem setMinimumSize ne fonctionne pas

private JMenuItem newItem(String text, String iconPath) { 
    JMenuItem myMenuItem; 
    if (iconPath == null || iconPath.isEmpty()) { 
     myMenuItem = new JMenuItem(text); 
    } 
    else { 
     ImageIcon icon = new ImageIcon(iconPath); 
     myMenuItem = new JMenuItem(text, icon); 
    } 
    // this would work, but then setMaximumSize doesn't have any effect 
    // myMenuItem.setPreferredSize(new Dimension(250,20)); 
    myMenuItem.setMinimumSize(new Dimension(250,20)); 
    myMenuItem.setMaximumSize(new Dimension(350,20)); 

    return myMenuItem; 
} 

Qu'est-ce que je fais mal?

PS. J'utilise jdk1.6 sous Windows XP, le Service Pack 3 avec le système Regardez & Feel

+1

Cette comparaison "iconPath ==" "ne fonctionnera pas, soit dit en passant. – Bombe

+0

oh, c'est vrai :). Merci! Donc utiliser pour les langages de script, que j'ai oublié la comparaison de chaînes n'est pas statique dans Java. – stefita

+0

Quelle version de Java utilisez-vous? Quel système d'exploitation utilisez-vous? Quel Look & Feel utilisez-vous? Dans Swing, cela compte :-( –

Répondre

4

Les tailles minimales et maximales sont ignorées par la plupart des gestionnaires de disposition. Voici une petite astuce utile qui oblige les tailles à respecter en tout gestionnaire de mise en page:

private class MyMenuItem extends JMenuItem { 
    @Override 
    public Dimension getPreferredSize() { 
     Dimension preferred = super.getPreferredSize(); 
     Dimension minimum = getMinimumSize(); 
     Dimension maximum = getMaximumSize(); 
     preferred.width = Math.min(Math.max(preferred.width, minimum.width), 
      maximum.width); 
     preferred.height = Math.min(Math.max(preferred.height, minimum.height), 
      maximum.height); 
     return preferred; 
    } 
} 

Cela a l'avantage de travailler même si le contenu de l'affichage change de menu. Vous devrez ajouter des constructeurs en fonction de vos objectifs.

+0

C'est une bonne solution de contournement! Je vous remercie! – stefita

1

i remplacé votre

myMenuItem.setMinimumSize(new Dimension(250, 20)); 
myMenuItem.setMaximumSize(new Dimension(350, 20)); 

avec

myMenuItem.setPreferredSize(new Dimension(250, 20)); 

et rend la largeur que vous recherchez pour. Dans mon expérience, les composants de swing répondent mieux à la taille préférée que la taille min et max.

EDIT:

après avoir pris un autre coup je pense que cela fonctionne assez bien .. il se résume à peu près la même que vous avez et je pense que ça va marcher, peu importe ce que la police (où que vous avez codé en dur la police).

il ne prend toutefois pas en compte la gouttière avant d'un élément de menu, mais si vous êtes texte est vraiment beaucoup de temps il ne devrait pas faire une différence ..

private JMenuItem newItem(String text, String iconPath) { 
    JMenuItem myMenuItem; 
    if (iconPath == null || iconPath.isEmpty()) { 
     myMenuItem = new JMenuItem(text); 
     myMenuItem.setPreferredSize(new Dimension(myMenuItem.getFontMetrics(myMenuItem.getFont()).stringWidth(text), 20)); 
    } else { 
     ImageIcon icon = new ImageIcon(iconPath); 
     myMenuItem = new JMenuItem(text, icon); 
     myMenuItem.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight())); 
    } 
    return myMenuItem; 
} 
0

Ok, donc j'ai trouvé Une solution, peut-être pas la meilleure mais elle semble fonctionner. Cependant, je suis encore un peu inquiet à propos de l'instruction FontMetrics. Donc, si quelqu'un a une meilleure solution, je serais heureux de le voir. Voici mon code (Menu.MINWIDTH est réglé à 200 et à 300 Menu.MAXWIDTH):

private JMenuItem newItem(String text, String iconPath) { 
    JMenuItem myMenuItem; 
    ImageIcon icon= null; 
    int iconPixels = 0; 
    if (iconPath == null || iconPath.isEmpty()) { 
     myMenuItem = new JMenuItem(text); 
    } 
    else { 
     icon = new ImageIcon(iconPath); 
     myMenuItem = new JMenuItem(text, icon); 
     iconPixels = icon.getIconWidth(); 
    } 

    FontMetrics fontM = myMenuItem.getFontMetrics(new Font("Default", Font.PLAIN, 12)); 
    int stringPixels = fontM.stringWidth(text); 

    int newWidth = stringPixels + iconPixels; 

    newWidth = newWidth < Menu.MINWIDTH ? Menu.MINWIDTH : newWidth; 
    newWidth = newWidth > Menu.MAXWIDTH ? Menu.MAXWIDTH : newWidth; 

    myMenuItem.setPreferredSize(new Dimension(newWidth, 20)); 
    System.out.println(text + " - " + newWidth); 
    return myMenuItem; 
} 
+0

Au lieu d'utiliser des métriques de polices, vous pouvez simplement construire un 'JLabel' avec la police, le texte et l'icône, et obtenir sa taille préférée. 'JMenuItem', ou presque assez –

+0

En fait - je viens juste de remarquer que vous construisez l'élément de menu ici - vous n'avez même pas besoin de' JLabel', vous pouvez simplement utiliser la taille préférée originale de l'élément de menu, comme dans la réponse de Russ Hayward –

0

Si je comprends la question que je ne sais pas pourquoi vous devez utiliser les FontMetrics. Appelez simplement getPreferredSize() sur l'élément de menu. Si la taille préférée est inférieure à votre minimum, réinitialisez la taille préférée à votre minimum.

+0

bien que la taille devrait varier en fonction de la longueur du texte de l'article.Si le texte est plus long que le minimum, l'élément de menu doit changer sa largeur, mais pas plus que le maximum autorisé. – stefita