2010-04-27 15 views
0

J'ai une liste J dans un JScrollPane et j'ai défini une valeur prototype afin qu'elle n'ait pas à calculer la largeur pour les grandes listes, mais utilise simplement cette largeur par défaut.JList avec JScrollPane et la valeur de la cellule prototype enveloppe les noms d'éléments (remplace par des points au lieu d'afficher la barre de défilement horizontale), pourquoi?

Maintenant, le problème est que la liste J remplace pour une raison quelconque la fin d'un élément avec des points (...) de sorte qu'une barre de défilement horizontale ne sera jamais affichée. Comment désactiver avec "wrapping"? Alors que les longs éléments ne sont pas remplacés par des points s'ils sont plus larges que la largeur de la liste J?

J'ai reproduit le problème dans un petit exemple d'application. S'il vous plaît exécuter si vous ne comprenez pas ce que je veux dire:

import javax.swing.*; 
import java.awt.*; 

public class Test 
{ 
    //window 
    private static final int windowWidth = 450; 
    private static final int windowHeight = 500; 

    //components 
    private JFrame frame; 
    private JList classesList; 
    private DefaultListModel classesListModel; 

    public Test() 
    { 
     load(); 
    } 

    private void load() 
    { 
     //create window 
     frame = new JFrame("Test"); 
     frame.setSize(windowWidth, windowHeight); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setUndecorated(true); 
     frame.getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG); 

     //classes list 
     classesListModel = new DefaultListModel(); 
     classesList = new JList(classesListModel); 
     classesList.setPrototypeCellValue("prototype value"); 
     classesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     classesList.setVisibleRowCount(20); 
     JScrollPane scrollClasses = new JScrollPane(classesList, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);  

     for (int i = 0; i < 200; i++) 
     { 
      classesListModel.addElement("this is a long string, does not fit in width"); 
     } 

     //panel 
     JPanel drawingArea = new JPanel(); 
     drawingArea.setBackground(Color.white); 

     drawingArea.add(scrollClasses); 
     frame.add(drawingArea); 

     //set visible 
     frame.setVisible(true); 
    } 
} 

Même si vous forcez barre de défilement horizontale, vous ne serez pas toujours en mesure de faire défiler parce que l'élément est en fait pas plus large que la largeur en raison du point (...) emballage.

Merci d'avance.

Répondre

3

Les barres de défilement apparaissent automatiquement lorsque la taille préférée du composant ajouté au panneau de défilement est supérieure à la taille du panneau de défilement. En utilisant la méthode setPrototypeCellValue (...), vous modifiez la façon dont la liste calcule sa taille préférée, ce qui signifie que vous êtes responsable de fournir la valeur appropriée qui garantit que les chaînes ne seront pas tronquées.

Donc la solution simple n'est pas d'utiliser cette méthode, mais en plus vous aurez besoin de définir la taille préférée du scrollpane pour être ce que vous voulez. Ensuite, les barres de défilement horizontales apparaîtront si nécessaire.

+0

Comment puis-je régler la taille préférée alors? Je pensais que c'est ce que fait le setPrototypecellValue? – Tom

+1

A obtenu maintenant en utilisant scrollClasses.setPreferredSize (new Dimension (100, 400)) ;. Merci. – Tom

+0

Voir ma réponse ci-dessous. De plus, si vous n'appelez pas setPrototypecellValue(), la taille de JList sera automatiquement ajustée pour s'adapter à l'élément le plus large. setPrototypecellValue() n'est utile que si vous avez une liste très longue et que vous ne voulez pas que Java passe par chaque entrée pour trouver les exigences de largeur. – Alinium

1

Lorsque vous appelez classesList.setPrototypeCellValue("prototype value") vous dites la JListclassesList pour limiter sa largeur maximale à la longueur de la chaîne « valeur prototype ». (See javadocs)

Puis plus tard lorsque vous remplissez la liste avec les chaînes "c'est une longue chaîne, ne correspond pas à la largeur", pas étonnant qu'il ne rentre pas dans la largeur! Parce que la largeur du prototype que vous lui avez donné est plus petite que la largeur de la chaîne avec laquelle vous remplissez la liste. Le JScrollPane affiche automatiquement les barres de défilement et vous n'avez généralement pas besoin d'ajuster leur comportement. Le JList ajustera automatiquement sa largeur pour essayer et montrer l'article de largeur maximum dans la liste. Le problème se produit lorsque vous demandez à JList de corriger sa largeur en appelant le setPrototypeCellValue().

Si vous commentez

classesList.setPrototypeCellValue("prototype value");

ou le remplacer par

classesList.setPrototypeCellValue("this is a long string, does not fit in width");

alors il fonctionnera comme prévu à.

+0

Merci, camickr était un peu plus rapide mais vous méritez un upvote pour une élaboration supplémentaire! J'ai lu les documents en passant, mais je pense que je l'ai mal compris. :) – Tom

2

Ma réponse à cette question est que d'abord trouver l'élément le plus long dans la liste puis utilisez méthode setPrototype sur ce que les éléments