2009-08-08 7 views
3

J'ai une question complexe je ne peux pas trouver une réponse n'importe où.Comment mettre en page un composant dans un panneau de défilement vertical uniquement?

est un exemple ici:

public static void main(final String[] args) { 
    final JFrame frame = new JFrame("test"); 
    final JPanel bigPane = new JPanel(new GridLayout(0, 1)); 
    frame.setContentPane(new JScrollPane(bigPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, 
      ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER)); 
    bigPane.add(new JTextField("reterterter ertertrert erterter ert")); 
    bigPane.add(new JTextField(" ertertrert erterter ert")); 
    bigPane.add(new JTextField("reterterter ertertrert ert")); 
    bigPane.add(new JTextField("reterterter ertertrert erterter ")); 
    frame.pack(); 
    frame.setSize(frame.getSize().width/2, frame.getSize().height); 
    frame.setVisible(true); 
} 

Ici, clairement les champs de texte sont coupés. Plus précisément, bigPane est coupé. Mais je voudrais que les champs de texte soient redimensionnés au lieu de couper, donc nous pouvons toujours les utiliser. Comme la barre de défilement horizontale est interdite, je souhaite que la mise en page oublie la largeur préférée de la vue (bigPane) et force toujours la largeur de la vue à correspondre à la largeur de la fenêtre. Comme il n'y aurait pas de fenêtre virtuelle pour la direction horizontale, seulement dans la verticale.

Je ne trouve pas de solution à cela, et pas même un hack, si vous pouvez aider.

Nico.

PS: ressemble le code pour ViewportLayout ne contient pas de code pour cette

PS2: voici une casquette du résultat du code ci-dessus http://www.nraynaud.com/kilombo/testLayout.png voir le côté droit.

+0

Que voulez-vous dire par "Je voudrais que le texte à l'intérieur des champs de texte soit coupé"? Voulez-vous limiter la longueur du texte? –

+0

voici ce que je veux: http://www.nraynaud.com/kilombo/textcut.png (je l'ai fait en enlevant le scrollpane) voici ce que je reçois et ne veux pas: http: //www.nraynaud .com/kilombo/textfieldcut.png qui rend le champ de texte inutilisable. – nraynaud

+0

Je ne comprends pas les votes négatifs sur l'une ou l'autre de ces réponses. Ils font tous les deux ce que tu veux. – banjollity

Répondre

4

Je pense que la "bonne" façon de le faire est d'utiliser l'interface Scrollable:

public class ScrollPaneWidthTrackingPanel extends JPanel implements Scrollable { 
    private static final long serialVersionUID = 1L; 

    public ScrollPaneWidthTrackingPanel(LayoutManager layoutManager) { 
     super(layoutManager); 
    } 

    public Dimension getPreferredScrollableViewportSize() { 
     return getPreferredSize(); 
    } 

    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { 
     return Math.max(visibleRect.height * 9/10, 1); 
    } 

    public boolean getScrollableTracksViewportHeight() { 
     return false; 
    } 

    public boolean getScrollableTracksViewportWidth() { 
     return true; 
    } 

    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { 
     return Math.max(visibleRect.height/10, 1); 
    } 
} 

Deux lignes de votre code doivent alors être remplacées par:

final ScrollPaneWidthTrackingPanel bigPane = new ScrollPaneWidthTrackingPanel(new GridLayout(0, 1)); 
frame.setContentPane(new JScrollPane(bigPane)); 

Et les composants doivent toujours remplir toute la largeur du JScrollPane, quelle que soit la taille de la trame.Cette modification a pour effet secondaire que les composants ne rempliront plus la hauteur du JScrollPane. Pour résoudre cela, ajoutez le code suivant au début de la méthode getScrollableTracksViewportHeight:

if (getParent() instanceof JViewport) { 
    JViewport viewport = (JViewport) getParent(); 
    return component.getPreferredSize().height < viewport.getHeight(); 
} 
+0

J'ai vraiment lu le défilement javadoc trop vite. Clairement, ce que je veux est dans public boolean getScrollableTracksViewportWidth() { return true; } Merci beaucoup. – nraynaud

+0

Techniquement, j'ai déjà utilisé swingx dans mon projet, je vais utiliser un JXPanel et appeler panel.setScrollableTracksViewportHeight (false); dessus. Cela permettra d'éviter le reste du code personnalisé. – nraynaud

1

Utilisez le constructeur JTextField qui prend un int en tant que paramètre. C'est le nombre de caractères visibles dans le champ de texte. Vous pouvez ensuite utiliser setText pour initialiser le contenu du champ (si nécessaire).

Vous pouvez également définir la taille maximale et préférées (setMaximumSize, setMinimumSize) des champs de texte de manière appropriée.

+0

aucune de ces solutions adresse mon problème je pense. Je souhaite que le comportement actuel ne soit pas modifié pour la partie verticale, ce qui exclut toute possibilité de toucher n'importe quelle taille à la main. La définition du numéro de colonne ne change en rien le comportement de mise en page, mais modifie indirectement la valeur preferredSize. – nraynaud

+0

Je ne peux pas dire que je comprends ce que vous voulez alors. Quel est exactement le problème et que voulez-vous dire par "couper"? Le cadre apparaît-il trop large? Pas assez large? Quelle est la solution? –

+0

lors du redimensionnement de la trame, les champs sont coupés au lieu de redimensionner. voici ce que je reçois: http://www.nraynaud.com/kilombo/textfieldcut.png voici ce que je veux: http://www.nraynaud.com/kilombo/textcut.png – nraynaud

1

De l'JavaDoc:

Paramètres:
texte - le texte à afficher, ou null
colonnes - le nombre de colonnes à utiliser pour calculer la largeur préférée; si les colonnes sont mises à zéro, la largeur préférée sera celle qui résulte naturellement de l'implémentation du composant

Depuis que vous appelez le constructeur 0, vous obtenez l'implémentation "tout naturellement", qui prend les longueurs de vos cordes trop longues. Il suffit d'appeler le constructeur de colonnes, avec un non-zéro, pour résoudre ce problème. Essayez ces lignes:

bigPane.add(new JTextField("reterterter ertertrert erterter ert",3)); 
bigPane.add(new JTextField(" ertertrert erterter ert",3)); 
bigPane.add(new JTextField("reterterter ertertrert ert",3)); 
bigPane.add(new JTextField("reterterter ertertrert erterter ",3)); 

Voici une capture d'écran du panneau résultant:

alt text http://mcglashan.net/stackoverflow1.png

+0

Je pense que j'ai déjà répondu à ça. Cela détruira l'objectif de taille préféré et, à titre d'exemple, détruira l'intention JFrame.pack(). Je ne veux pas changer la taille préférée (à la main), je voudrais que la largeur préférée soit ignorée dans le calcul de la largeur de vue dans ce cas particulier. – nraynaud

Questions connexes