2015-03-24 2 views
0

J'ai rencontré le problème suivant dans mon programme. J'ai un JPanel avec un GridBagLayout dans un JScrollPanel. Il devrait avoir le comportement suivant:JTextPane dans un GridBagLayout ne pas se comporter de la manière désirée

  1. Le défilement ne devrait être possible que verticalement.
  2. Dans les lignes JPanel sont ajoutés dynamiquement. Ces lignes ont deux colonnes. Les deux colonnes doivent diviser l'espace de manière égale.
  3. Chaque champ (colonne/ligne) de cette table est un JTextPane, car le texte peut être modifié et peut afficher du code HTML. Si le texte est trop long, il sera enveloppé avec l'effet que la hauteur du champ augmente.
  4. Lors du redimensionnement de la fenêtre, les colonnes sont également redimensionnées.

Le problème est, quand il y a un long texte:

  • Lorsque vous utilisez JTextPane sans PreferredSize que l'emballage ne fonctionne pas et les colonnes ne sont pas répartis également. Définition de la taille préférée, le JTextPane coupe le texte sur la deuxième ligne. JEditorPane ne fonctionne pas non plus.
  • Lorsque vous utilisez JTextArea avec l'habillage activé, cela fonctionne! Cependant, je ne peux pas afficher le HTML. De plus, le quatrième point n'est pas rempli. Lors de l'extension de la fenêtre, le champ est également redimensionné. Mais lorsque vous redimensionnez la fenêtre, elle ne se redimensionne pas.

Comment puis-je obtenir le comportement souhaité et éviter ces problèmes? J'ai déjà épuisé toutes les possibilités auxquelles je peux penser.

Voici une image du comportement souhaité à l'aide JTextPanes (mais sans HTML):

Here is a picture of the desired behavior using <code>JTextPanes</code> (but without HTML)

Voici le mauvais comportement à l'aide JTextPanes:

Here is the wrong behavior using JTextPanes:

Et ici un code pour un SSCCE:

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextPane; 
import javax.swing.ScrollPaneConstants; 
import javax.swing.WindowConstants; 

public class EditorTest extends JFrame { 
    private JPanel jPanel1; 
    private JPanel jPanel2; 
    private JScrollPane jScrollPane1; 
    private JTextPane jTextPane1; 
    private JTextPane jTextPane2; 

    public EditorTest() { 
     initComponents(); 
    } 

    private void initComponents() { 
     GridBagConstraints gridBagConstraints; 

     jScrollPane1 = new JScrollPane(); 
     jPanel2 = new JPanel(); 
     jPanel1 = new JPanel(); 
     jTextPane2 = new JTextPane(); 
     jTextPane1 = new JTextPane(); 

     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     setPreferredSize(new Dimension(500, 500)); 
     getContentPane().setLayout(new GridBagLayout()); 

     jScrollPane1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
     jScrollPane1.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 

     jPanel2.setBorder(BorderFactory.createEmptyBorder()); 
     jPanel2.setLayout(new BorderLayout()); 

     jPanel1.setLayout(new GridBagLayout()); 

     jTextPane2.setContentType("text/html"); 

     gridBagConstraints = new GridBagConstraints(); 
     gridBagConstraints.gridx = 1; 
     gridBagConstraints.gridy = 0; 
     gridBagConstraints.fill = GridBagConstraints.BOTH; 
     gridBagConstraints.weightx = 0.5; 
     gridBagConstraints.insets = new Insets(0, 0, 3, 3); 
     jPanel1.add(jTextPane2, gridBagConstraints); 

     jTextPane1.setContentType("text/html"); 
     jTextPane1.setText("This is a very long text that also sometimes is " 
       + "<span style=\"color:blue\">blue</span> and so on and so on."); 
     gridBagConstraints = new GridBagConstraints(); 
     gridBagConstraints.gridx = 0; 
     gridBagConstraints.gridy = 0; 
     gridBagConstraints.fill = GridBagConstraints.BOTH; 
     gridBagConstraints.weightx = 0.5; 
     gridBagConstraints.insets = new Insets(0, 0, 3, 3); 
     jPanel1.add(jTextPane1, gridBagConstraints); 

     jPanel2.add(jPanel1, BorderLayout.NORTH); 


     jScrollPane1.setViewportView(jPanel2); 

     gridBagConstraints = new GridBagConstraints(); 
     gridBagConstraints.gridx = 0; 
     gridBagConstraints.gridy = 0; 
     gridBagConstraints.fill = GridBagConstraints.BOTH; 
     gridBagConstraints.weightx = 1.0; 
     gridBagConstraints.weighty = 1.0; 
     getContentPane().add(jScrollPane1, gridBagConstraints); 

     pack(); 
    }      

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new EditorTest().setVisible(true); 
      } 
     }); 
    }    
} 

Merci beaucoup pour votre aide!

Update1

Pour rendre plus clair le comportement souhaité que j'ai créé une autre capture d'écran avec un JTextArea, comme dans la première tête d'image. Les TextPanes doivent être au sommet et seulement aussi élevés que nécessaire (c'est-à-dire le texte). Pour illustrer ce comportement, modifiez également l'arrière-plan du champ de texte.

enter image description here

+1

Vous devez spécifier la taille préférée et maximale de la feuille jtext. La largeur devrait être la moitié de votre jpanel, et la hauteur devrait être celle par défaut. (c'est-à-dire Super.getPreferredSize(). height). – Sharcoux

+0

Cher @ user1967800, merci pour votre commentaire! La définition de 'setMaximumSize()' n'a aucun effet. Cependant, en définissant 'getPreferredSize()' avec les paramètres que vous suggérez, la largeur est affichée correctement, mais la hauteur remplit toute la fenêtre. Peut-être que cela vient très près! Avez-vous une autre idée, comment ajuster la hauteur maintenant? – Rolch2015

Répondre

1

Je pense que vous me avez mal compris donc voici une classe pour vous montrer plus clairement:

private class MyJTextPane extends JTextPane { 
    public Dimension getPreferredSize() { 
     return new Dimension(245,super.getPreferredSize().height); 
    } 
    public Dimension getMaximumSize() { 
     return getPreferredSize(); 
    } 
} 

Vous pouvez utiliser cette classe dans votre SSCCE pour voir comment il se comporte.

Ceci est juste pour vous donner une idée de comment utiliser getMaximumSize et getPreferredSize pour atteindre votre objectif. Ce que vous devez comprendre, c'est que pour une largeur donnée, la méthode getPreferredSize par défaut renvoie la hauteur nécessaire pour afficher le contenu de JTextPane.

Dans votre cas, il vous suffit de remplacer 245 par la largeur finale que vous attendez. Vous pouvez également utiliser une fonction si la largeur dépend d'autres éléments.

Dites-moi si vous avez besoin de plus de détails.

+0

Cher @ user1967800, merci beaucoup, cela fonctionne parfaitement! Après avoir lu votre message, je lis aussi d'autres articles sur preferredSize, maximumSize etc. et pense, je le comprends maintenant beaucoup mieux. J'ai beaucoup appris de vous! – Rolch2015

2

Je pense avoir codé ce que vous vouliez.

J'ai dû définir une taille préférée pour le JPanel dans le volet de défilement. La largeur peut être ce que vous voulez. La hauteur devra être ajustée pour la taille des JTextPanes.

Voici une image de l'interface graphique.

Editor Test

Et voici le code.

package com.ggl.testing; 

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextPane; 
import javax.swing.ScrollPaneConstants; 
import javax.swing.WindowConstants; 

public class EditorTest extends JFrame { 
    private static final long serialVersionUID = 8019172274009058078L; 

    private JPanel jPanel1; 
    private JScrollPane jScrollPane1; 
    private JTextPane jTextPane1; 
    private JTextPane jTextPane2; 

    public EditorTest() { 
     initComponents(); 
    } 

    private void initComponents() { 
     GridBagConstraints gridBagConstraints; 

     jScrollPane1 = new JScrollPane(); 
     jPanel1 = new JPanel(); 
     jTextPane2 = new JTextPane(); 
     jTextPane1 = new JTextPane(); 

     setTitle("Editor Test"); 
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     getContentPane().setLayout(new GridBagLayout()); 

     jScrollPane1 
       .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
     jScrollPane1 
       .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); 

     jPanel1.setLayout(new GridLayout(0, 2)); 
     jPanel1.setPreferredSize(new Dimension(400, 400)); 

     jTextPane2.setContentType("text/html"); 
     jTextPane2 
       .setText("<html>This is a very long text that also sometimes is " 
         + "<span style=\"color:green\">green</span> and so on and so on."); 

     jTextPane1.setContentType("text/html"); 
     jTextPane1 
       .setText("<html>This is a very long text that also sometimes is " 
         + "<span style=\"color:blue\">blue</span> and so on and so on."); 

     jPanel1.add(jTextPane1); 
     jPanel1.add(jTextPane2); 

     jScrollPane1.setViewportView(jPanel1); 

     gridBagConstraints = new GridBagConstraints(); 
     gridBagConstraints.gridx = 0; 
     gridBagConstraints.gridy = 0; 
     gridBagConstraints.fill = GridBagConstraints.BOTH; 
     gridBagConstraints.weightx = 1.0; 
     gridBagConstraints.weighty = 1.0; 
     getContentPane().add(jScrollPane1, gridBagConstraints); 

     pack(); 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new EditorTest().setVisible(true); 
      } 
     }); 
    } 
} 
+0

Cher @GilbertLeBlanc, merci pour votre réponse rapide! J'ai étudié votre réponse de près et expérimenté avec elle. Malheureusement, je n'obtiens pas le comportement désiré. Le 'JTextPane' devrait être en haut et pas plus haut que nécessaire (c'est-à-dire le texte), car d'autres lignes peuvent être ajoutées dynamiquement. De plus, si c'est possible, j'aimerais utiliser un GirdBagLayout pour les JTextPanes. Je suis désolé si ma question n'était pas assez claire, je la mettrai à jour encore une fois! Pensez-vous que c'est possible? J'apprécie sincèrement votre aide et vos efforts. – Rolch2015

+0

Cher @GilbertLeBlanc, J'ai mis à jour la question avec une autre capture d'écran. Je vous remercie! – Rolch2015