View Full Version : [JAVA] JTable e file
Ciao a tutti ho un problema che non riesco a risolvere...
Sto creando una rubrica che scrive in un file.txt i vari dati e dovrei poi leggerli e inserirli in una JTable ma non riesco..qualcuno può aiutarmi??
Grazie
Una volta messi in un array di stringhe è un gioco da ragazzi: c'è un costruttore apposta. Se hai problemi posta uno spezzone di codice.
Cap_Snake8
18-05-2010, 12:39
è abbastanza semplice:
Una volta che leggi il file, dividi i vari campi dai quali crei una matrice di stringhe,
supponiamo tu abbia una cosa del genere:
nome: numero:
bianchi 1234567890
rossi 0987654321
Poi basta passare la matrice al costruttore di JTable:
JTable tabella=new JTable(matriceRubrica,campi);
matriceRubrica è la matrice che contiene i nomi e numeri ecc..
campi è un vettore che serve per dare i nomi alle colonne della tabella, sarà composto per esempio da:{"nome","numero","indirizzo",ecc...}
ho un problema.. per creare la matrice devo sapere il numero di righe e colonne, il numero delle colonne ce l'ho mentre per trovare il numero di righe uso questo:
input = new BufferedReader(new FileReader("agenda.txt"));
while(input.readLine() != null)
{
numRighe++;
}
Ovviamente dopo non riesco a inserire i dati nella matrice perché se faccio un nuovo readLine() mi arriva una stringa null. Avrei bisogno di tornare all'inizio del file e mi chiedo: esiste un metodo o devo chiudere e aprire di nuovo il file?
banryu79
18-05-2010, 16:02
input = new BufferedReader(new FileReader("agenda.txt"));
List<String> lines = new ArrayList<String>();
String line = null;
while((line=input.readLine()) != null)
{
// line contiene la riga letta
lines.add(line);
}
Al termine del ciclo hai in memoria la lista di tutte le righe lette dal file; una chiamata a lines.size() è sufficiente per sapere quante righe hai letto. Inoltre puoi trasformare la volo la List<String> nell'equivalente array di String con il metodo toArray().
Il problema è che devo dividere le singole voci che ho nella riga...
mi spiego meglio io salvo in un file le informazioni in questo modo:
pinco|pallino|3309099981|pincopallino@yahoo.it|
in modo tale che con StringTokenizer riesca a dividere i campi..
Come faccio con la List a fare questo?
Intanto posto come l'ho risolto io anche se il chiudere e il riaprire il file mi fa un pò schifo XD
private void leggiFile()
{
int numRighe = 0;
int i, j;
BufferedReader input = null;
String s;
try
{
input = new BufferedReader(new FileReader("agenda.txt"));
while(input.readLine() != null)
{
numRighe++;
}
riga = new String[numRighe][NUM_COLONNE];
input.close();
}catch(FileNotFoundException exc)
{
System.out.println("Problema apertura file");
System.exit(0);
}
catch(IOException e)
{
System.out.println("Errore lettura");
}
try
{
input = new BufferedReader(new FileReader("agenda.txt"));
for(i = 0; i < numRighe; i++)
{
s = input.readLine();
StringTokenizer str = new StringTokenizer(s, "|");
for(j = 0; j < NUM_COLONNE; j++)
{
riga[i][j] = str.nextToken();
}
}
input.close();
}catch(FileNotFoundException exc)
{
System.out.println("Problema apertura file");
System.exit(0);
}
catch(IOException e)
{
System.out.println("Errore lettura");
}
}
banryu79
18-05-2010, 17:07
Usa una lista di array di Stringhe.
- la lista, essendo dinamica ti permette di inserire un nuovo array di Stringhe per ogni riga letta dal file;
- il singolo array di Stringhe (la dimensione è nota dato che sai quale è il numo di colonne) rappresenta una riga appena letta e ridotta in token.
Così fai tutto in un ciclo.
Per strutturare il codice, potresti partire risolvendo il problema più piccolo: quello del parsing/token di una riga.
Lo fai definendo un metodo che prende in input una riga (String) e sputa in output la riga ridotta in token (String[]).
A quel punto risolvi l'altro problema:
quello della lettura delle singole righe da file.
Lo fai definendo un metodo che prende in input il nome di un file (String) e sputa in output tutte le rige lette e ridotte in tokens (List<String[]>).
DefaultTableModel model = new DefaultTableModel(0, numero di colonne);
String text = new Scanner(il file).useDelimiter("\\Z").next();
for(String line : text.split("\n")) {
model.addRow(line.split("\\|"));
}
JTable table = new JTable(model);
banryu79
18-05-2010, 17:19
DefaultTableModel model = new DefaultTableModel(0, numero di colonne);
String text = new Scanner(il file).useDelimiter("\\Z").next();
for(String line : text.split("\n")) {
model.addRow(line.split("\\|"));
}
JTable table = new JTable(model);
Così non vale: hai usato le regex :Prrr:
mmm farò con calma stasera e ti dirò :)
intanto grazie per l'aiuto ;)
Dopo un po di tempo a pensare ho deciso di salvare le righe in un vector, dopodiché le estraggo e le suddivido con il StringTokenizer e le inserisco nella matrice di String ecco il codice:
private void leggiFile()
{
int numRighe = 0;
Vector<String> s2 = new Vector<String>();
int i, j;
BufferedReader input = null;
String s = null;
try
{
input = new BufferedReader(new FileReader("agenda.txt"));
while((s = input.readLine()) != null)
{
s2.addElement(s);
}
numRighe = s2.size();
riga = new String[numRighe][NUM_COLONNE];
for(i = 0; i < numRighe; i++)
{
s = s2.elementAt(i);
StringTokenizer str = new StringTokenizer(s, "|");
for(j = 0; j < NUM_COLONNE; j++)
{
riga[i][j] = str.nextToken();
}
}
input.close();
}catch(FileNotFoundException exc)
{
System.out.println("Problema apertura file");
System.exit(0);
}
catch(IOException e)
{
System.out.println("Errore lettura");
}
}
banryu79
18-05-2010, 21:52
mmm farò con calma stasera e ti dirò :)
intanto grazie per l'aiuto ;)
Fai come vuoi, ma la soluzione postata da PGI è decisamente migliore e più sintetica (io stavo scherzando con lui, se non sai cosa sono le espressioni regolari portresti cogliere l'occasione per leggere qualcosa in merito perchè potrebbero tornarti utili in futuro).
Ho notato che è decisamente sintetico rispetto al mio devo ancora guardarlo perché non l'ho ma visto XD
Cmq mi servirebbe lo stesso un array per poi ordinare gli elementi e fare ricerche
banryu79
19-05-2010, 09:30
Ho notato che è decisamente sintetico rispetto al mio devo ancora guardarlo perché non l'ho ma visto XD
Cmq mi servirebbe lo stesso un array per poi ordinare gli elementi e fare ricerche
Bhe, visto che ti appoggi a Swing e usi una JTable puoi sfruttare i meccanismi di sorting (e filtering) che questo framework mette a disposizione.
In particolare si tratta della classe java.swing.table.TableRowSorter (http://java.sun.com/javase/6/docs/api/javax/swing/table/TableRowSorter.html), e qui trovi un toturial introduttivo (http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#sorting) di massima sull'uso della JTable, che spiega brevemente come realizzare un sorting.
Cavolo fanstatico..non l'avevo letta quella parte. Ora provo a implementare l'espressione regolare e l'ordinamento
L'espressione regolare funziona alla grande :D volevo chiedere però un chiarimento...
String text = new Scanner(new FileReader("agenda.txt")).useDelimiter("\\Z").next();
Cosa fa di preciso questra istruzione?
Ho capito che la stringa text prende il contenuto del file agenda.txt ma .useDelimiter e .next() cosa fanno?
wingman87
19-05-2010, 14:19
L'espressione regolare funziona alla grande :D volevo chiedere però un chiarimento...
String text = new Scanner(new FileReader("agenda.txt")).useDelimiter("\\Z").next();
Cosa fa di preciso questra istruzione?
Ho capito che la stringa text prende il contenuto del file agenda.txt ma .useDelimiter e .next() cosa fanno?
Con next() chiedi allo Scanner il prossimo token che, avendo scelto come delimitatore \\Z (un carattere speciale per definire la fine della stringa di input cui fa riferimento Scanner), corrisponde all'intero contenuto del file.
banryu79
19-05-2010, 14:19
L'espressione regolare funziona alla grande :D volevo chiedere però un chiarimento...
String text = new Scanner(new FileReader("agenda.txt")).useDelimiter("\\Z").next();
Cosa fa di preciso questra istruzione?
Ho capito che la stringa text prende il contenuto del file agenda.txt ma .useDelimiter e .next() cosa fanno?
Sono due metodi della classe Scanner (java.util.Scanner).
Il primo imposta il "delimiter" da usare come separatore dei token da usare per parserizzare la sorgente input a cui si è collegato le scanner, il secondo restituisce la prossima occorrenza.
In questo caso si è comandato allo scanner di usare come separatore dei token la fine della sorgente di input (immagino \Z stia per EOF) e di restituire il prossimo (l'unico) token.
I Javadoc spiegano tutto.
Tieni conto che la soluzione appare più sintetica per lo più perchè non gestisce le eccezioni. In "produzione" la cosa diventerebbe per lo meno:
Scanner in = null;
String text = null;
try {
text = (in = new Scanner(il file)).useDelimiter("\\Z").next();
} catch(IOException ex) {
ex.printStackTrace();
} finally {
if(in != null) {
in.close();
}
}
if(text != null) {
...eccetera
}
Questo ad evitare che il flusso resti aperto per più tempo dello stretto necessario.
Grazie ora mi è più chiaro :D
Il problema ora è che devo fare in modo che le righe siano già ordinate quando apro il frame però per ora riesco solo a ordinarle premendo l'intestazione di colonna.
Sono riuscito a ordinare tutto :)
Grazie a tutti voi per l'aiuto!
Se avrò bisogno ancora scriverò :p
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.