2009-04-25 9 views
0

J'ai un JComboBox qui contient une liste déroulante MRU list et un pour un panneau d'arborescence de répertoires. Ensemble, les deux forment le panneau de gauche de mon GUI (le MRU est au-dessus du panneau d'arbre) qui est un JSplitPane, ainsi le panneau de gauche est redimensionnable. Le problème est que le texte du répertoire est toujours plus long que la largeur requise pour voir ce répertoire dans le panneau de l'arborescence, donc je dois dimensionner mon volet de gauche beaucoup plus large que nécessaire pour l'arborescence afin de arrête la combo-box de montrer un nom de répertoire tronqué. La zone de liste déroulante n'est pas très utile avec la fin du nom de fichier tronquée, mais en rendant le volet de gauche assez large pour le nom de fichier le rend très souvent trop large pour la fenêtre globale, en particulier. si ce n'est pas en cours d'exécution maximisé. Et ce n'est généralement que la partie finale du nom de fichier qui présente un intérêt. Si je pouvais seulement provoquer JComboBox à montrer "commencer ... fin" au lieu de "commencer ..." mon problème serait résolu.Un widget texte peut-il déborder avec le "..." au milieu du texte au lieu de la fin?

Screen Shot http://www.freeimagehosting.net/uploads/da9810ed86.png


MISE À JOUR: J'ai une solution qui fonctionne (voir auto-réponse ci-dessous), mais ce n'est pas parfait. Si quelqu'un sait comment je peux l'améliorer, ce serait très apprécié.

Répondre

0

travail sur l'idée d'Oscar d'utiliser un ListCellRenderer, je suis venu avec quelque chose qui fonctionne presque ... La valeur de composant est rendu correctement, mais les valeurs de la liste exigent une bidouille horrible. Le hack est nécessaire car pour les éléments de la liste, la taille du rendu (de getSize()) reflète la largeur du texte de l'élément le plus long, pas la largeur de l'espace disponible pour rendre la valeur. J'ai essayé d'utiliser le JComboBox lui-même, mais sa largeur inclut le petit bouton déroulant, donc s'il y a une barre de défilement présente, sa largeur n'est pas prise en compte. Le hack consiste à stocker la largeur du rendu s'il est inférieur à la largeur de la zone de liste déroulante et à utiliser la largeur stockée si la largeur du rendu est supérieure à la largeur de la zone de liste déroulante. Cela a un cas où la largeur du rendu est comprise entre celle du JLabel interne et la largeur de la combo-box. Puisque l'espace de rendu sera la largeur de la combo-box, moins la largeur d'une barre de défilement et des incrustations, si quelqu'un a une suggestion sur la façon dont je peux savoir que la liste a une barre de défilement et comment obtenir le barre de défilement afin que je puisse extraire la largeur, je suis tout oreilles. Peut-être que je peux faire list.getParent() et m'attendre à ce qu'il s'agisse d'un JScrollPane (le doco JComboBox ou JList indique qu'il utilise un volet de défilement).

D'autres suggestions pour mieux faire sont les bienvenues.

Code suit:

recentDirs.setRenderer(new ComboTextRenderer(recentDirs)); 

... 

static private class ComboTextRenderer 
extends DefaultListCellRenderer 
implements SwingConstants 
{ 
JComponent       parent; 
int         renderWidth; 

ComboTextRenderer(JComponent par) { 
    super(); 

    parent=par; 
    renderWidth=-1; 
    } 

public void paint(Graphics gc) { 
    String       txt=getText(); 

    int        len=txt.length(); 
    int        wid=getSize().width; 
    Insets       ins=getInsets(); 
    FontMetrics      met=gc.getFontMetrics(); 

    if(renderWidth==-1 || wid<parent.getSize().width) { renderWidth=wid; } 
    else            { wid=renderWidth; } 
    wid-=(ins.left+ins.right); 

    if(met.stringWidth(txt)>wid) { 
     String rpl=null; 
     for(int xa=0,pfx=Math.min(15,((len/2)-1)),sfx=(pfx+2); pfx>0 && sfx<len; xa++) { 
      rpl=(txt.substring(0,pfx)+" ... "+txt.substring(sfx)); 
      if(met.stringWidth(rpl)<=wid) { break; } 
      rpl=null; 
      if  ((len-sfx)>15) { sfx++; } 
      else if((xa%2)==0 ) { pfx--; } 
      else     { sfx++; } 
      } 
     if(rpl!=null) { setText(rpl); } 
     } 

    super.paint(gc); 
    } 
} 
1

mmHhh peut-être fournir un rendu personnalisé? .... Je pense que c'est un rendu de type listcell ou quelque chose comme ça. Pour ce que je comprends, le défaut est enveloppé quand il n'y a pas assez d'espace disponible, en créant/ou en modifiant la cellule rendue vous pouvez savoir quelle est la largeur disponible du composant et modifier le texte à rendre à votre gré.

mmmhh Je n'ai pas été proche de cette API (le rendu des cellules) pour quelques années, donc je pourrais être probablement un peu confus.

:)

+0

Je vais vous donner qu'un tourbillon ce week-end; En supposant que cela fonctionne, cela vous dérangerait-il si je modifiais votre réponse avec le code du moteur de rendu et que je l'acceptais ensuite? –

+0

Pas du tout, ce serait un honneur pour moi:) ... si cela fonctionne ....: P – OscarRyz

+0

Vous pourriez avoir des problèmes avec le JScrollPane si vous l'utilisez bien :( – OscarRyz

Questions connexes