IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants Java Discussion :

jTextPane et append


Sujet :

Composants Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13
    Par défaut jTextPane et append
    Bonjour,

    Alors voila,j'ai realisé un chat avec interface graphique. J'ai d'abord utilisé un simple jTextArea pour afficher les lignes de discussion. Tout marche bien,sauf que le style n'y est pas trop,et j'aimerai enrichir un peu tout ca.

    J'ai donc choisis de tenter un jTextPane.Le but etant de pouvoir formater le texte en utilisant les balises html.
    Sauf que,j'ai decouvert que jTextPane ne dispose pas de la methode append.Donc pour rajouter du texte a celui existant,c'est la galere...

    J'ai essayé de nombreuses methodes.
    Celle consistant a utiliser les insertString etc. Ca marche bien pour rajouter le texte aprés celui existant,sauf qu'il ne prends plus en compte le formatage apparement,donc aucun interet pour moi.

    J'ai egalement essayé de recuperer ce qui est deja ecrit dans le jTextPane,puis de rajouter le nouveau texte a la fin,et enfin,de faire un setText de tout ca. Seulement,quand il commence a y avoir plus d'une page de texte,ca clignote lamentablement a chaque refresh pour tout remettre et c'est fatiguant....mais ca prends bien en compte le balisage html...

    Bref,je ne sais plus trop quoi faire,ca fait des heures que je suis dessus,et rien de rien...quelqu'un aurait une idée?

    Merci

  2. #2
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Fait voir ton code avec les "insertString" sur le "Document".
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	public static void append(String s) {
    		try {
    			Document doc = jTextPane1.getDocument();
    			doc.insertString(doc.getLength(), s + "\n", jTextPane1
    					.getStyle("default"));
     
    		} catch (BadLocationException e) {
    			e.printStackTrace();
    		}
    	}

    Voila,j'ai eu beau tenter de mettre jTextPane1.setContentType( "text/html" ); un peu partout,rien n'y fait.

  4. #4
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Voila un code qui fonctionne. Je l'ai fait très rapidement, donc la méthode pour construire une chaîne avec plusieurs styles n'est pas facilement utilisable en l'état, mais je te laisse le soin d'améliorer tout ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    import java.awt.Color;
     
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextPane;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.SimpleAttributeSet;
    import javax.swing.text.StyleConstants;
    import javax.swing.text.StyleContext;
     
    public class TextPaneAppend extends JTextPane
    {
    	private static final long	serialVersionUID	= 1L;
     
    	public void append( AttributeSet attr, String chaine )
    	{
    		setCaretPosition( getDocument().getLength() );
    		setCharacterAttributes( attr, true );
    		replaceSelection( chaine );
    		setCaretPosition( getDocument().getLength() );
    	}
     
    	public AttributeSet appendAttributeSet( AttributeSet old, Object name, Object value )
    	{
    		return StyleContext.getDefaultStyleContext().addAttribute( old, name, value );
    	}
     
    	public void append( Object attributeName, Object attributeValue, String chaine )
    	{
    		append( 
    				StyleContext.getDefaultStyleContext().addAttribute( 
    						SimpleAttributeSet.EMPTY, attributeName, attributeValue ), 
    				chaine );
    	}
     
    	public static void main( String argv[] )
    	{
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
     
    		TextPaneAppend pane = new TextPaneAppend();
    		pane.append( StyleConstants.Bold, Boolean.TRUE, "coucou\n" );
    		pane.append( StyleConstants.Italic, Boolean.TRUE, "hello\n" );
    		pane.append( 
    				pane.appendAttributeSet( 
    						pane.appendAttributeSet( SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.WHITE ), 
    						StyleConstants.Background, Color.RED ), 
    				"et alors ?\n" );
    		pane.append( StyleConstants.Foreground, Color.RED, "salut\n" );
     
    		frame.setContentPane( new JScrollPane( pane ) );
    		frame.setSize( 640, 480 );
    		frame.setVisible( true );
    	}
    }
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  5. #5
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Les setText() multiple sont à éviter... Cela nécessite de régénérer tout le formatage à chaque fois


    La solution est bien de passer par le document comme l'indique dinobogan, mais par défaut il faut spécifier tous les styles un à un pour chaque bout de texte... Bref il faudrait parser l'HTML !


    En fait il faut cumuler à cela un EditorKit (et plus précisément un HTMLEditorKit) qui permet de gérer les conversions et d'utiliser pleinement l'HTMLDocument, comme par exemple insertBeforeEnd() qui permet d'interpréter du code HTML et de l'insérer juste avant la fin d'un tag...

    Il suffirait donc d'une méthode "append()" comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	/**
             * Ajout de code HTML à la fin du BODY d'un HTMLDocument
             */
    	public static void append(HTMLDocument doc, String htmlText) {
    		try {
    			Element body = getBody(doc);
    			doc.insertBeforeEnd(body, htmlText);
    		} catch (Exception e) { // BadLocationException ou IOException
    			// Ceci ne devrait pas arriver :
    			throw new IllegalStateException(e);
    		}
    	}
    getBody() correspond à ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    	/**
             * Recherche de l'élément BODY d'un HTMLDocument
             */
    	public static Element getBody(HTMLDocument doc) {
    		final Element html = doc.getDefaultRootElement();
    		final int count = html.getElementCount();
    		for (int i=0; i<count; i++) {
    			Element elem = html.getElement(i);
    			if ("body".equals(elem.getName())) {
    				return elem;
    			}
    		}
    		throw new IllegalStateException("No body !");
    	}
    Le tout à utiliser avec un HTMLDocument créé à partir d'un HTMLFactory (afin qu'ils soient liés). Cela se fait simplement en définissant l'EditorKit du JTextPane :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    text.setEditorKit(new HTMLEditorKit());

    Exemple rapide :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    		// Le JTextPane avec son HTMLEditorKit :
    		final JTextPane text = new JTextPane();
    		text.setEditorKit(new HTMLEditorKit());
    		text.setEditable(false);
     
    		// Le JTextField de saisie :
    		final JTextField input = new JTextField();
     
    		// Le listener qui valide les saisies :
    		input.addActionListener(new ActionListener() {
    			private int count = 0;
    			@Override
    			public void actionPerformed(ActionEvent e) {
     
    				// On Génère le code HTML qui sera utilisé :
    				String html = String.format("<div><b>%tT</b> : <i style='color:%s'>%s</i></div>",
    						new Date(),
    						count%2==0 ? "red" : "blue",
    						e.getActionCommand()
    				);
    				count++;
     
    				// on efface l'input :
    				input.setText(null);
     
    				// On ajoute le code HTML dans le document :
    				HTMLDocument doc = (HTMLDocument) text.getDocument();
    				append(doc, html);
     
    				// Et on demande le scroll vers la fin du document :
    				try {
    					text.scrollRectToVisible(text.modelToView(doc.getLength()));
    				} catch (BadLocationException e1) {
    					throw new RuntimeException(e1);
    				}
    			}
    		});
     
     
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setSize(400, 400);
    		frame.setLocationRelativeTo(null);
     
    		frame.getContentPane().add(new JScrollPane(text));
    		frame.getContentPane().add(input, BorderLayout.SOUTH);
     
    		frame.setVisible(true);

    a++

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13
    Par défaut
    Merci beaucoup.
    J'avais reussi a le faire grace a l'editorkit.Pas de la meme facon que toi,mais ca a l'air de marcher egalement (j'utilise finalement un jEditorPane).

    Je mets rapidement mon code en vrac au cas ou ca interesserait du monde.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    HTMLEditorKit kit = new HTMLEditorKit();
    HTMLDocument doc = new HTMLDocument();
    jEditorPane1.setEditorKit(kit);
    jEditorPane1.setDocument(doc);
     
    kit.insertHTML(doc, doc.getLength(), "<br>rajouter ca a la fin du document",0, 0, HTML.Tag.BR);
    Bon le "probleme" c'est qu'il faut absolument que le texte a rajouter soit precedé de <br>,mais au final,pour un chat ca ne pose pas de probleme puisqu'il faut un saut de ligne a chaque nouveau message.
    C'est pas organisé etc,mais c'etait simplement pour tester et trouver ce qui semble correspondre le mieux.
    Je vais mettre le sujet en résolu.Ceci etant,j'ai maintenant un nouveau probleme que je vais exposer dans un nouveau sujet histoire de bien separer.
    Merci encore

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JTextPane] Extraire un mot
    Par doudine dans le forum Composants
    Réponses: 3
    Dernier message: 21/04/2012, 22h11
  2. [Swing] Centré un texte dans un JTextPane
    Par titi_22 dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 24/06/2011, 16h09
  3. [Lien hypertexte]Mettre un lien dans un JTextPane
    Par Pill_S dans le forum Composants
    Réponses: 8
    Dernier message: 23/05/2004, 19h20
  4. [JTextPane] saut de ligne...
    Par neric dans le forum Composants
    Réponses: 2
    Dernier message: 21/01/2004, 15h01
  5. Scroll automatique dans un JTextPane
    Par regbegpower dans le forum Composants
    Réponses: 9
    Dernier message: 11/11/2003, 09h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo