JList – utilise une barre de défilement verticale au lieu d’horizontal avec une orientation verticale?

J’essaie de placer une JList intérieur d’un JScrollPane et de la JScrollPane alphabétiquement les entrées en colonnes verticales, comme ceci:

 ADG BEH CF 

Cependant, lorsque la liste JList manque d’espace pour afficher plus d’entrées, j’aimerais que JScrollPane défile uniquement dans le sens vertical.

Cela fonctionne lorsque j’utilise VERTICAL_WRAP . Cependant, il me semble que lorsque j’utilise un habillage vertical, je reçois une barre de défilement horizontale et lorsque j’utilise HORIZONTAL_WRAP je reçois la barre de défilement souhaitée, mais les éléments sont placés dans un ordre que je n’aime pas. Puis-je avoir mon gâteau et le manger aussi? Voici un exemple simple de ce que j’essaie de faire.

entrez la description de l'image ici

C’est le plus proche que je puisse obtenir, mais j’aimerais pouvoir faire défiler verticalement tout en maintenant l’ordre alphabétique vertical.

 public class ScrollListExample { static List ssortingngList = new ArrayList(); static { for (int i = 0; i < 500; i++) { stringList.add("test" + i); } } public static void main(final String[] args) { final JFrame frame = new JFrame(); final Container contentPane = frame.getContentPane(); final JList list = new JList(stringList.toArray()); list.setLayoutOrientation(JList.VERTICAL_WRAP); list.setVisibleRowCount(0); final JScrollPane scrollPane = new JScrollPane(list); contentPane.add(scrollPane); frame.setPreferredSize(new Dimension(800, 400)); frame.pack(); frame.setVisible(true); } } 

Une solution à laquelle j’ai pensé est la suivante: si la taille de la cellule est connue, je peux créer un écouteur de composant et écouter un événement de redimensionnement. Lorsque cet événement est déclenché, je peux calculer le nombre de lignes souhaité afin d’empêcher le défilement horizontal. Cela ressemble à un bidouillage et je ne sais pas comment cela pourrait fonctionner avec des composants de texte de taille variable.

Je pense que votre solution est juste, et pas du tout un hack. De toute façon, toute fonctionnalité intégrée devrait faire fondamentalement la même chose.

Voici une modification de votre exemple qui fait ce que vous voulez.

 public class ScrollListExample { static List ssortingngList = new ArrayList(); static { for (int i = 0; i < 500; i++) { stringList.add("test" + i); } } public static void main(final String[] args) { final JFrame frame = new JFrame(); final Container contentPane = frame.getContentPane(); final JList list = new JList(stringList.toArray()); list.setLayoutOrientation(JList.VERTICAL_WRAP); final JScrollPane scrollPane = new JScrollPane(list); contentPane.add(scrollPane); frame.setPreferredSize(new Dimension(800, 400)); frame.pack(); list.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { fixRowCountForVisibleColumns(list); } }); fixRowCountForVisibleColumns(list); frame.setVisible(true); } private static void fixRowCountForVisibleColumns(JList list) { int nCols = computeVisibleColumnCount(list); int nItems = list.getModel().getSize(); // Compute the number of rows that will result in the desired number of // columns int nRows = nItems / nCols; if (nItems % nCols > 0) nRows++; list.setVisibleRowCount(nRows); } private static int computeVisibleColumnCount(JList list) { // It's assumed here that all cells have the same width. This method // could be modified if this assumption is false. If there was cell // padding, it would have to be accounted for here as well. int cellWidth = list.getCellBounds(0, 0).width; int width = list.getVisibleRect().width; return width / cellWidth; } } 

Est-ce ce que vous allez faire? (Peut-être besoin de changer la taille préférée …)

 public class ScrollListExample { static List ssortingngList = new ArrayList(); static { for (int i = 0; i < 500; i++) { stringList.add("test" + i); } } public static void main(final String[] args) { final JFrame frame = new JFrame(); final Container contentPane = frame.getContentPane(); final JList list = new JList(stringList.toArray()); final JScrollPane scrollPane = new JScrollPane(list); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); contentPane.add(scrollPane); frame.setPreferredSize(new Dimension(200,200)); frame.pack(); frame.setVisible(true); } } 

Brilliant Code @Kevin K … Je suggère une petite modification pour éviter ArithmeticException (Divide by zéro)

 private int computeVisibleColumnCount(JList list) { int cellWidth = list.getCellBounds(0, 0).width; int width = list.getVisibleRect().width; return width == 0 ? 1 : width / cellWidth; }