PDA

Visualizza la versione completa : [JAVA] Immagini e testo in una JTextPane


KaZaA
01-03-2006, 17:24
Salve a tutti! Qualcuno sà come poter fare per salvare da qualche parte tutto il contenuto (testo e immagini) di una JTextPane (le immagini sono inserite con il metodo insertImage())? Ho provato in una stringa ma salva (giustamente) solo il testo...come posso fare? Grazie a tutti!

LeleFT
01-03-2006, 17:33
Non so quanto sia "conveniente", ma dovresti fare in modo che il JEditorPane (e tutti gli oggetti in esso contenuti) implementino Serializable.
A questo punto, tramite un ObjectOutputStream che punta ad un FileOutputStream, salvi il tutto su file.


Da notare che il JEditorPane, se non vado errato, dovrebbe dare anche la possibilità di poter salvare il Document in formato HTML.


Ciao. :ciauz:

KaZaA
01-03-2006, 17:43
Ciao! Grazie per la risposta! Forse mi sono spiegato male: non volevo salvare su file, ma buttare tutto quello ke leggo da una JTextPane in un oggetto java in grado di fare da "contenitore" temporaneo per testo e immagini...si può fare? Grazie!

KaZaA
01-03-2006, 18:09
Cioè...il problema a risolvere è questo:
Devo sostituire una certa sequenza di caratteri immessi in una JTextPane con una immagine, eliminando quella serie di caratteri, e fino ad ora nn ci sono riuscito...help!! :fagiano: :cry: :cry:

LeleFT
01-03-2006, 18:40
Ok... allora la cosa è, da un lato, più semplice, dall'altro più complicata. :)

Più semplice perchè non ti devi sobbarcare il peso di dover implementare Serializable per tutti gli oggetti contenuti.

Più complicata perchè devi affrontare il problema del reperimento delle informazioni dai JTextComponent.

A tal proposito dovresti dare un'occhiata alla documentazione relativa all'interfaccia Document (di javax.swing.text).
Il documento viene diviso in zone logiche, dette Paragrafi. Ciascun paragrafo, poi, viene diviso in altre zone logiche dette Righe. (Questo in soldoni).


Per quello che devi fare tu, non dovrebbero esserci grossi problemi. Dovresti prendere il Document (che sarà uno StyledDocument), reperire la parte che ti interessa (ciascun carattere o immagine ha una posizione di partenza e una di fine) e modificarla.


In alternativa, potresti fare questo lavoretto a priori: prima di inserire il testo nel JEditorPane, dovresti scandirlo e spezzettarlo. A questo punto inserisci sequenzialmente, testo e immagini in base a come l'hai spezzettato.


PS: per curiosità, stai tentando di costruire una specie di chat dove a ciascun "tag" corrisponde un'immagine? :)


Ciao. :ciauz:

KaZaA
01-03-2006, 18:55
Lol...mi hai smascherato! :zizi: Si...stò cercando di fare una chat per il collegamento simultaneo di più computer attraverso l'indirizzo IP o nome dell'host...in LAN può tornare bene, ma su internet devi conoscere l'indirizzo IP del computer a cui ti vuoi collegare...comunque grazie dell'aiuto...purtroppo mi hai confermato ciò che sospettavo...mi dovrò leggere e imparare il funzionamento dei Document e StyledDocument...vabbè...mi ci metterò sotto...grazie ancora!!! :D :zizi:

LeleFT
02-03-2006, 12:00
Immaginavo... perchè la stessa cosa l'ho fatta io. :)
Ti dò un aiuto.
Questa è la classe che gestisce la visualizzazione dei messaggi della chat che ho sviluppato io. Io uso un JTextPane e non un JEditorPane (è più semplice e non ho bisogno delle funzionalità del JEditorPane per quel che mi serve).
La parte che gestisce i messaggi da visualizzare è abbastanza commentata, ma in soldoni succede questo:

1) Arriva un Messaggio (puoi pensarlo come ad una stringa + altre informazioni di controllo)
2) Estraggo la stringa del messaggio
3) La spezzetto in token che mi dicono di cosa si tratta (testo o immagine)
4) Visualizzo tutti i token nell'ordine, secondo lo stile adatto.

Per semplicità ho fatto in modo che il token dell'immagine corrispondesse al nome del file GIF dell'immagine stessa. Ad esempio ': pizza :' --> pizza.gif [senza gli spazi]).


import java.io.*;
import java.awt.*;
import java.net.*;
import javax.swing.*;
import javax.swing.text.*;
import java.util.StringTokenizer;
import java.util.Vector;

public class ChatArea extends JPanel {

private JScrollPane jsp;
private JTextPane jtp;
private ElencoMessaggi messaggi;
private String [] immagini;

private final int MAX_NUM_MESSAGGI = 300; // Massimo numero messaggi visibili nell'area messaggi

public ChatArea(String [] immagini) {
setLayout(null);
messaggi = new ElencoMessaggi();
this.immagini = immagini;
jtp = new JTextPane();
jtp.setEditable(false);
jsp = new JScrollPane(jtp);
jsp.setBounds(0, 0, super.getWidth(), super.getHeight());
messaggi.addObserver( new ChatAreaListener(jtp, MAX_NUM_MESSAGGI) );
add(jsp);
creaStili(jtp.getStyledDocument());
creaEmotIcon(jtp.getStyledDocument());
}

public void paintComponent(Graphics g) {
jsp.setSize(getWidth(), getHeight());
jtp.setSize(getWidth(), getHeight());
}

public void aggiungiMessaggio(Messaggio msg) {
int msgId = msg.getMsgId();
String from = msg.getFrom() + ": ";
String to = msg.getTo();
String msgTesto = msg.getMsg();
StyledDocument doc = jtp.getStyledDocument();
int inizioMsg = doc.getLength();
int lunghezzaMsg = 0;
try {
if (!from.equals(": ")) {
doc.insertString(doc.getLength(), from, doc.getStyle("nome"));
}
if (msgId == Messaggio.PUBBLICO) { // Messaggio pubblico
if (from.equals(": ")) { // Messaggio del server

// Decodifico il messaggio secondo le regole del metodo 'decodifica'
String [][] tmpMsg = decodifica(msgTesto, "server");

// Scorro tutto l'array dei token del messaggio e li visualizzo secondo lo stile adottato
for (int i=0; i<tmpMsg.length; i++)
doc.insertString(doc.getLength(), tmpMsg[i][1], doc.getStyle(tmpMsg[i][0]));
} else { // Messaggio di un utente

// Decodifico il messaggio secondo le regole del metodo 'decodifica'
String [][] tmpMsg = decodifica(msgTesto, "normale");

// Scorro tutto l'array dei token del messaggio e li visualizzo secondo lo stile adatto
for (int i=0; i<tmpMsg.length; i++)
doc.insertString(doc.getLength(), tmpMsg[i][1], doc.getStyle(tmpMsg[i][0]));
}
} else { // Messaggio privato
if (from.equals(": ")) { // !!-- Messaggio privato del server --!!

// Decodifico il messaggio secondo le regole del metodo 'decodifica'
String [][] tmpMsg = decodifica(msgTesto, "pvt_server");

// Scorro tutto l'array dei token del messaggio e li visualizzo secondo lo stile adatto
for (int i=0; i<tmpMsg.length; i++)
doc.insertString(doc.getLength(), tmpMsg[i][1], doc.getStyle(tmpMsg[i][0]));
} else { // Messaggio privato di un utente

// Decodifico il messaggio secondo le regole del metodo 'decodifica'
String [][] tmpMsg = decodifica(msgTesto, "pvt_utente");

// Scorro tutto l'array dei token del messaggio e li visualizzo secondo lo stile adatto
for (int i=0; i<tmpMsg.length; i++)
doc.insertString(doc.getLength(), tmpMsg[i][1], doc.getStyle(tmpMsg[i][0]));
}
}

// Aggiungo 2 ritorni a capo per spaziare ciascun messaggio
doc.insertString(doc.getLength(), "\n\n", doc.getStyle("normale"));
jtp.setCaretPosition(doc.getLength());

// Aggiorno l'elenco dei messaggi presenti nella ChatArea
lunghezzaMsg = doc.getLength() - inizioMsg;
messaggi.aggiungi(lunghezzaMsg);
} catch (BadLocationException ble) { ble.printStackTrace(); }
}

/* Questo metodo decodifica un messaggio utente e lo spezzetta in un array di stringe:
|------|-------| TIPO: indica il tipo di token e può essere il tipo passato come secondo parametro
| TIPO | TOKEN | oppure il tipo che identifica l'immagine rappresentata dal token
|------|-------| TOKEN: è il contenuto del messaggio e può essere il testo da stampare oppure il nome
dell'immagine nel caso il token rappresenti un'immagine.

Esempio: testo="Ciao! :smile: Come va oggi?" tipo="normale" --> decodifica di questo messaggio:
|-----------|------------------|
| "normale" | "Ciao! " |
|-----------|------------------|
| "smile" | "smile" |
|-----------|------------------|
| "normale" | " Come va oggi?" |
|-----------|------------------|
*/
private String [][] decodifica(String testo, String tipo) {
StringTokenizer st = new StringTokenizer(testo, ":", true);
Vector v = new Vector();
String [] elemento = new String[2];
String tmpToken = "";
String tokenString = "";
String tmp_img = "";
int countStd = 0;
int countImg = 0;
boolean cambio = false;
boolean passo = false;

// Tokenizzo il testo e lo salvo nel vector
while (st.hasMoreTokens()) v.add(st.nextToken());

// Creo l'array dei tokens
String [] arrayToken = new String[v.size()];
for (int i=0; i<arrayToken.length; i++) arrayToken[i] = (String) v.elementAt(i);
v = new Vector();

for (int i=0; i<arrayToken.length; i++) {
tmpToken = arrayToken[i];
if (tmpToken.equals(":")) {
if (countImg == 2) {
tmp_img = immagine(arrayToken[i-1]);
if (tmp_img.equals("")) { // Non è un'immagine
countImg--;
countStd++;
tokenString += arrayToken[i-2] + arrayToken[i-1];
passo = true;
} else { // E' un'immagine
cambio = true;
}
}
if (countImg == 1 && !passo) { // Ho trovato "::"
tokenString += ":";
}
if (countImg == 0) {
countImg++;
}
passo = false;
} else {
if (countImg == 1) {
countImg++;
} else {
tokenString += tmpToken;
countStd++;
}
}
if (cambio) {
elemento[0] = tipo;
elemento[1] = tokenString;
v.add((String []) elemento.clone());
elemento[0] = tmp_img;
elemento[1] = arrayToken[i-1];
v.add((String []) elemento.clone());
countImg = countStd = 0;
elemento = new String[2];
tokenString = "";
tmp_img = "";
cambio = false;
}
}
if (countImg > 0) {
if (countImg > 1) {
tokenString += arrayToken[arrayToken.length-2] + arrayToken[arrayToken.length-1];
countImg = 0;
countStd++;
} else {
tokenString += arrayToken[arrayToken.length-1];
countImg = 0;
countStd++;
}
}
if (countStd > 0) {
elemento[0] = tipo;
elemento[1] = tokenString;
v.add((String []) elemento.clone());
countStd = 0;
}
// Recupero l'array di Stringhe nel Vector
String [][] result = new String[v.size()][2];
for (int i=0; i<v.size(); i++) {
elemento = (String []) v.elementAt(i);
result[i][0] = elemento[0];
result[i][1] = elemento[1];
}
return result;
}

private String immagine(String token) {
boolean trovato = false;
int i = 0;
String result = "";
while ((i<immagini.length) && !trovato) {
if (token.equals(immagini[i])) {
trovato = true;
result = immagini[i];
}
i++;
}
return result;
}

private void creaStili(StyledDocument doc) {
Style deflt = StyleContext.getDefaultStyleContext().getStyle(Sty leContext.DEFAULT_STYLE);

// Stile normale
Style normale = doc.addStyle("normale", deflt);
StyleConstants.setFontFamily(deflt, "Arial");
StyleConstants.setForeground(deflt, Color.black);
StyleConstants.setFontSize(deflt, 12);

// Stile server
Style s = doc.addStyle("server", normale);
StyleConstants.setItalic(s, true);
StyleConstants.setUnderline(s, true);
StyleConstants.setForeground(s, Color.gray);
StyleConstants.setFontSize(s, 11);

// Stile pvt_utente
s = doc.addStyle("pvt_utente", normale);
StyleConstants.setBold(s, true);
StyleConstants.setForeground(s, Color.blue);
StyleConstants.setFontSize(s, 14);

// Stile pvt_server
s = doc.addStyle("pvt_server", normale);
StyleConstants.setBold(s, true);
StyleConstants.setItalic(s, true);
StyleConstants.setUnderline(s, true);
StyleConstants.setForeground(s, Color.red);
StyleConstants.setFontSize(s, 14);

// Stile nome
s = doc.addStyle("nome", normale);
StyleConstants.setBold(s, true);
StyleConstants.setForeground(s, Color.black);
}

private void creaEmotIcon(StyledDocument doc) {
Style deflt = StyleContext.getDefaultStyleContext().getStyle(Sty leContext.DEFAULT_STYLE);
Style s = null;
ImageIcon img = null;
// Creazione delle immagini
for (int i=0; i<immagini.length; i++) {
s = doc.addStyle(immagini[i], deflt);
java.net.URL urlImg = ChatArea.class.getResource("immagini/" + immagini[i] + ".gif");
if (urlImg != null) {
img = new ImageIcon(urlImg, immagini[i]);
StyleConstants.setIcon(s, img);
} else {
System.out.println("Impossibile trovare l'immagine" + immagini[i]);
System.exit(0);
}
}
}
}
Buon lavoro! :)


Ciao. :ciauz:

Loading