Newsgroup: it.comp.java
Titolo: Problemi con TextArea

Scusate se invado ancora il NG con una mia richiesta (abbiate pietà).
Il problema è quello che vi vado ad esporre:
ho creato una area di testo dove andare a creare una specie di tabella.
Il problema è che i caratteri dei Font non hanno tutti la stessa dimesione
per cui il risultato è ad esempio:
casa           23
roma            25
mia            18
a             7
ecc. ecc.
C'è un modo per allineare i dati oppure devo ricorrere a qualche altra
componente (e in questo caso quale)?
Grazie 1000,
             Enoch.

componente (e in questo caso quale)?
Se tutto il problema sta nell'allineare ogni colonna a sinistra, potresti
avere molteplici TextArea, giustapposte, una per colonna (bisogna poi
vedere se il look é soddisfacente).  Ma di nuovo questo non ti aiuta se
vuoi qualche colonna allineata a destra.  Forse la cosa piú semplice
é derivare da Canvas un componente tutto tuo, che accetta delle
"dimensioni di colonna", e dei testi con l'indicazione di che colonna
e riga deve occupare un certo testo, e registra un vettore, o altra
sequenza, di "atomi" testo-coord.X-coord.Y (calcolando le coord.
stesse con la FontMetrics); e naturalmente fa override del paint
per fare gli opportuni drawChars.  É probabile che tutto questo te lo
possa trovare giá impacchettato (senza dubbio anche con molte
altra funzionalitá supplementari) in molteplici componenti esistenti,
sia gratis che commerciali, ma in java.awt mi pare che non ci sia, e
non so se vuoi metterti alla caccia di quello che fa al caso tuo -- in
effetti rischi di far prima a scrivertelo che non a trovarlo giá fatto.
Alex

é derivare da Canvas un componente tutto tuo, che accetta delle
Ecco una versione molto rudimentale e preliminare di
questo componente, che, essendo una "tavola" molto
ma molto piccola, ho chiamato "Tavoletta".  Anzitutto
un minuscolo HTML di prova, prova.html:
<html>
<head>
<title>Prova tavoletta</title>
</head>
<body>
Vediamo un poco:
<applet code="prova.class" width=200 height=150>
</applet>
</body>
</html>
ed ecco l'applet di prova che usa le funzioni della
classe Tavoletta:
import java.applet.Applet;
import Tavoletta;
public class prova extends Applet {
    Tavoletta tt;
    public void init() {
        // il parametro del costruttore di
        // Tavoletta é il massimo numero
        // di "caselle" che ci interessano:
        tt = new Tavoletta(20);
        // setSize ereditata da Component
        tt.setSize(getSize());
        tt.addText("casa", 0, 2, false);
        tt.addText("23", 0, 198, true);
        tt.addText("roma", 1, 2, false);
        tt.addText("25", 1, 198, true);
        tt.addText("mia", 2, 2, false);
        tt.addText("18", 2, 198, true);
        add(tt);
        validate();
    }
}
Praticamente c'é solo il metodo addText, che prende
una stringa, un numero di riga, una coordinata x di
riferimento, e un boolean che, se true, indica che a
quella coordinata x deve allinearsi il bordo _destro_
della scritta (se no, quello sinistro).
Ed ecco finalmente il file Tavoletta.java in tutta la
sua (?) "gloria"...:
import java.awt.*;
// piccola "classe" (struct...!) ausiliaria
class testo {
    // testo da disegnare
    char[] chars;
    // coordinate ove disegnarlo
    int x; int y;
    // costruttore: estrae i chars
    // come array dalla String passata
    testo(String s) {
        int n = s.length();
        chars = new char[n];
        s.getChars(0, n, chars, 0);
        // NB: le coordinate vengono poi
        // calcolate dopo dalla classe
        // primaria "Tavoletta"
    }
    // unico scopo del testo: disegnarsi
    void disegnati(Graphics g) {
        g.drawChars(chars, 0, chars.length, x, y);
    }
}
// il nostro nuovo componente...:
public class Tavoletta extends Canvas {
    // l'array dei testi
    int nTesti;         // # di testi presenti
    testo[] testi;      // l'array vero e proprio
    // costruttore: alloca l'array
    public Tavoletta(int maxTesti) {
        testi = new testo[maxTesti];
    }
    // aggiunge un testo (stringa) ad una certa
    // riga, allineato a sinistra o destra a una
    // certa coordinata x di riferimento
    public boolean addText(String s, int riga,
            int refX, boolean rightAligned)
    {
        // se i testi sono troppi...:
        if(nTesti >= testi.length) return false;
        // OK, un testo nuovo:
        testi[nTesti] = new testo(s);
        // per le misure dei testi serve un FontMetrics
        FontMetrics fm = getFontMetrics(getFont());
        // la coordinata x:
        if(rightAligned) {
            refX -= fm.charsWidth(testi[nTesti].chars,
                0, testi[nTesti].chars.length);
        }
        testi[nTesti].x = refX;
        // la coordinata y:
        testi[nTesti].y = (riga+1) * fm.getHeight();
        ++nTesti;
        return true;
    }
    public void paint(Graphics g) {
        for(int i=0; i<nTesti; ++i) {
            testi[i].disegnati(g);
        }
    }
}
Ecco tutto... un piccolo esercizio divertente.
Naturalmente é MOLTO rudimentale e andrebbe
migliorata in mille modi (un esempio di minima:
accettare la programmazione di "tab stops", e
i flag di allineamento _per colonna_, ed espandere
una singola stringa-riga in n "testi", uno per colonna,
a seconda dei tab che contiene; poi ancora: gestire
il cambiamento di font, facoltativamente tracciare
righe orizzontali e verticali a demarcare le righe
e/o le colonne, permettere l'editing e altre gestioni
intelligenti di eventi, e poi, chi piú ne ha, piú ne
metta...:-).  Ma intanto, almeno, é una base da cui
partire, e giá cosí mi pare che faccia al caso tuo
piú di una TextArea...
Alex


Grazie ancora per i consigli sempre molto rapidi e utilissimi.
Non so cosa farei senza di te. Sei un grande.
Ciao,
             Enoch.

Non so cosa farei senza di te. Sei un grande.
Per caritá, troppo buono.  Altri, naturalmente, anche
su questo stesso gruppo, non la pensano come te...
Alex