2010-11-16 14 views
0

J'ai un JPanel et je crée, dynamiquement, JCheckBoxes à l'intérieur. Ceux-ci doivent être ajoutés JCheckBox toujours côte à côte. Au cas où il y aurait plus d'espace à insérer sur le côté, une nouvelle ligne de JCheckBoxes est créée, comme dans un simple éditeur de texte.JPanel à l'intérieur d'un JScrollPane

Cela se passe parfaitement. Mais ...

Je définis la mise en page sur ce JPanel à FlowLayout, exactement ce que je veux.

Le problème évident est qu'une fenêtre a un espace limité. Donc une bonne solution à ceci est: Insertion de ce JPanel dans un JScrollPane, et cela ne se produira que dans le défilement vertical. Mais j'ai des problèmes. Bien que vous ne puissiez faire apparaître qu'une barre de défilement verticale, les éléments sont toujours ajoutés côte à côte "pour toujours". Et le défilement vertical ne fonctionne tout simplement pas, seulement horizontalement.

J'ai essayé plusieurs façons de faire le défilement uniquement verticalement, mais rien n'a fonctionné (si cela avait fonctionné je ne serais pas ici:]).

Alors, quelqu'un a-t-il eu un problème similaire et peut-il m'aider?

Je serai très reconnaissant envers ceux qui m'aident.

Pas plus.

+2

Cette relents de mauvaise conception de l'interface utilisateur - JScrollPane est généralement utilisé pour fournir une vue sur une table ou une image, pas un panneau de commandes (après tout, combien de fois vous avez vu cette approche dans Windows, MacOs, etc.)? Une meilleure approche serait de séparer vos contrôles entre plusieurs onglets ou JPanels empilés en utilisant CardLayout. – Adamski

Répondre

4

J'ai traité le même problème avec ScrollPanes et FlowLayouts. J'ai trouvé que la meilleure solution est d'utiliser une version modifiée de FlowLayout qui prend en compte les changements verticaux. Voici le code pour une telle mise en page. Vous pouvez l'inclure dans votre projet et l'appeler comme un FlowLayout, mais il fonctionnera bien avec un scrollpane.

import java.awt.*; 

/** 
    * A modified version of FlowLayout that allows containers using this 
    * Layout to behave in a reasonable manner when placed inside a 
    * JScrollPane 

    * @author Babu Kalakrishnan 
    * Modifications by greearb and jzd 
    */ 

public class ModifiedFlowLayout extends FlowLayout { 
     public ModifiedFlowLayout() { 
       super(); 
      } 

      public ModifiedFlowLayout(int align) { 
       super(align); 
      } 
     public ModifiedFlowLayout(int align, int hgap, int vgap) { 
      super(align, hgap, vgap); 
     } 

     public Dimension minimumLayoutSize(Container target) { 
      // Size of largest component, so we can resize it in 
      // either direction with something like a split-pane. 
      return computeMinSize(target); 
     } 

     public Dimension preferredLayoutSize(Container target) { 
      return computeSize(target); 
     } 

     private Dimension computeSize(Container target) { 
      synchronized (target.getTreeLock()) { 
      int hgap = getHgap(); 
      int vgap = getVgap(); 
      int w = target.getWidth(); 

      // Let this behave like a regular FlowLayout (single row) 
      // if the container hasn't been assigned any size yet 
      if (w == 0) { 
       w = Integer.MAX_VALUE; 
      } 

      Insets insets = target.getInsets(); 
      if (insets == null){ 
       insets = new Insets(0, 0, 0, 0); 
      } 
      int reqdWidth = 0; 

      int maxwidth = w - (insets.left + insets.right + hgap * 2); 
      int n = target.getComponentCount(); 
      int x = 0; 
      int y = insets.top + vgap; // FlowLayout starts by adding vgap, so do that here too. 
      int rowHeight = 0; 

      for (int i = 0; i < n; i++) { 
       Component c = target.getComponent(i); 
       if (c.isVisible()) { 
        Dimension d = c.getPreferredSize(); 
        if ((x == 0) || ((x + d.width) <= maxwidth)) { 
         // fits in current row. 
         if (x > 0) { 
         x += hgap; 
         } 
         x += d.width; 
         rowHeight = Math.max(rowHeight, d.height); 
        } 
        else { 
         // Start of new row 
         x = d.width; 
         y += vgap + rowHeight; 
         rowHeight = d.height; 
        } 
        reqdWidth = Math.max(reqdWidth, x); 
       } 
      } 
      y += rowHeight; 
      y += insets.bottom; 
      return new Dimension(reqdWidth+insets.left+insets.right, y); 
      } 
     } 

     private Dimension computeMinSize(Container target) { 
      synchronized (target.getTreeLock()) { 
      int minx = Integer.MAX_VALUE; 
      int miny = Integer.MIN_VALUE; 
      boolean found_one = false; 
      int n = target.getComponentCount(); 

      for (int i = 0; i < n; i++) { 
       Component c = target.getComponent(i); 
       if (c.isVisible()) { 
        found_one = true; 
        Dimension d = c.getPreferredSize(); 
        minx = Math.min(minx, d.width); 
        miny = Math.min(miny, d.height); 
       } 
      } 
      if (found_one) { 
       return new Dimension(minx, miny); 
      } 
      return new Dimension(0, 0); 
      } 
     } 

    } 
+0

"@author Babu Kalakrishnan - Modifications .." Ah oui. Un des gourous GUI de Usenet (bien, c'est de là que je les connais, en tout cas). ;) –