Salvare i dati di una JTable
Tutti gli esempi di JFileChooser che ho postato fino adesso prendevavno i dati da una textarea.
Le jtable hanno una struttura diversa e per non incappare in errori si deve usare un codice un pò diverso.
Il codice è praticamente identico agli altri due esempi; anche qui è compreso il controllo sull'esistenza del file.
L'unica cosa che cambia è la scrittura del file.
import javax.swing.*;
import java.io.*;
import java.text.MessageFormat;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
public class SalvaTabella {
public static void salva() {
JFileChooser fc = new JFileChooser();
FileFilter csvFilter = new FileNameExtensionFilter("File CSV", "csv");
FileFilter txtFilter = new FileNameExtensionFilter("File TXT", "txt");
fc.addChoosableFileFilter(csvFilter);
fc.addChoosableFileFilter(txtFilter);
int returnVal = fc.showSaveDialog(fc);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File f = fc.getSelectedFile();
FileFilter selectedFilter = fc.getFileFilter();
if (f.getName().indexOf('.') == -1) {
if (selectedFilter == csvFilter) {
f = new File(f.getPath() + ".csv");
} else if (selectedFilter == txtFilter) {
f = new File(f.getPath() + ".txt");
}
}
if (f.exists()) {
String msg = MessageFormat.format("The entry ''{0}'' already exists.\nDo you want to replace it?", new Object[]{f});
int r = JOptionPane.showConfirmDialog(null, msg, "Confirm", JOptionPane.YES_NO_OPTION);
if (r == JOptionPane.NO_OPTION) {
// Returns without approve the selection.
return;
}
}
try {
FileWriter file = new FileWriter(f, false);
PrintWriter out = new PrintWriter(file);
String temp;
for (int row = 0; row < FrameTabella.getJtabella().getRowCount(); row++) {
temp = "";
for (int column = 0; column < FrameTabella.getJtabella().getColumnCount(); column++) {
String sep = ", "; // separatore di colonna
temp = temp.concat((String) (FrameTabella.getJtabella().getValueAt(row, column))) + sep;
}
out.println(temp);
}
out.close();
} catch (IOException e) {
JOptionPane.showMessageDialog(fc, e, "ERRORE", JOptionPane.ERROR_MESSAGE);
}
}
}
}
Non lo analizzo tutto; per una spiegazione più esauriente guardate gli altri due articoli sui filechooser.
Prendiamo in considerazione questa parte:
try {
FileWriter file = new FileWriter(f, false);
PrintWriter out = new PrintWriter(file);
String temp;
for (int row = 0; row < JTable().getRowCount(); row++) {
temp = "";
for (int column = 0; column < JTable().getColumnCount(); column++) {
String sep = ", "; // separatore di colonna
temp = temp.concat((String) (FrameTabella.getJtabella().getValueAt(row, column))) + sep;
}
out.println(temp);
}
out.close();
} catch (IOException e) {
JOptionPane.showMessageDialog(fc, e, "ERRORE", JOptionPane.ERROR_MESSAGE);
}
Come vedete ho dovuto usare due variabili (temp e sep) e due cicli for (uno per le righe e l'altro per le colonne).
La variabile sep funge solo come separatore per ordinare meglio i dati nel file; non è obbligatoria ma conviene impostarla.
La variabile importante è temp.
E' dichiarata fuori dai cicli e inizializzata vuota dentro al primo ciclo.
Poi viene riempita con i valori di row e col che rappresentano le righe e le colonne della jtable.
In questo modo i dati vengono salvati ordinati e senza ripetizioni come accade se si utilizza lo stesso codice per la textarea.
EDIT
Ho avuto un problema con il salvataggio dei dati nel caso in cui alcune cella fossero vuote.
Per ovviare al problema ho modificato questa riga
temp = temp.concat((String) (FrameTabella.getJtabella().getValueAt(row, column))) + sep;
così:
temp += (String)(Main.getTable().getValueAt(row, column)) + sep;
In pratica ho sostituito concat col classico +.
jtable filechooser.java textarea
Commentami!