PDA

View Full Version : TableModel


spv42
01-12-2006, 16:52
Ma con il TableModel è possibile creare una tabella vuota, cioè visualizzare solo celle vuote? (Ad esempio 5 righe vuote)

Io facendo cosi:
mytablemodel.addcolumn("Colonna1");
mytablemodel.addcolumn("Colonna2");

creo una tabella vuota, senza neanche una riga.

:muro:

PGI-Bis
01-12-2006, 17:05
C'è addRow. Se usi "null" come argomento, crea una riga vuota. Non puoi dirgli direttamente "null" perchè "null" è compatibile con ogni riferimento, di addRow ce ne sono due e il compilatore ti dirà "che cavolo stai dicendo, willis!" (signore fa che non sia così vecchio da essere il solo a ricordarmi di Arnold :D).

Hai un DefaultTableModel myTableModel, ottenuto dal costruttore senza argomenti.

Due colonne, come hai perfettamente già fatto:

myTableModel.addColumn("Colonna1");
myTableModel.addColumn("Colonna2");

e cinque righe, vuote:

Object[] NO_DATA = null;
myTableModel.addRow(NO_DATA);
myTableModel.addRow(NO_DATA);
myTableModel.addRow(NO_DATA);
myTableModel.addRow(NO_DATA);
myTableModel.addRow(NO_DATA);

et voilà.

spv42
01-12-2006, 17:09
C'è addRow. Se usi "null" come argomento, crea una riga vuota. Non puoi dirgli direttamente "null" perchè "null" è compatibile con ogni riferimento, di addRow ce ne sono due e il compilatore ti dirà "che cavolo stai dicendo, willis!" (signore fa che non sia così vecchio da essere il solo a ricordarmi di Arnold :D).

Hai un DefaultTableModel myTableModel, ottenuto dal costruttore senza argomenti.

Due colonne, come hai perfettamente già fatto:

myTableModel.addColumn("Colonna1");
myTableModel.addColumn("Colonna2");

e cinque righe, vuote:

Object[] NO_DATA = null;
myTableModel.addRow(NO_DATA);
myTableModel.addRow(NO_DATA);
myTableModel.addRow(NO_DATA);
myTableModel.addRow(NO_DATA);
myTableModel.addRow(NO_DATA);

et voilà.

Non Sei l'unco "Vecchio da ricordare Arnold" :D

Sei Sempre puntuale come un orologio svizzero!

Grazie!

spv42
01-12-2006, 17:12
Ma in questo modo posso fare:

table.setRowSelectionInterval (0, 0);
table.setColumnSelectionInterval (0, 0);


table.editCellAt (0, 0);
table.setRowSelectionAllowed (true);
table.setColumnSelectionAllowed (true);
table.setSelectionMode (ListSelectionModel.SINGLE_SELECTION);

In modo da editare una cella alla volta, stile Excel???

PGI-Bis
01-12-2006, 17:55
Se vuoi selezionare la cella e non la riga, cioè la cella assume il bordo "selezione" ma la riga a cui appartiene non viene illuminata, penso basti:

jtable.setRowSelectionAllowed(false);

i due metodi "interval" servono per la selezione programmatica di una cella. Tipo "clicco sul pulsante x e la cella abc della tabella viene selezionata".

spv42
01-12-2006, 18:12
E' proprio quello che voglio, solo una cella che mi si "illumini" e mi dia la possibilità di inserirci dei valori al suo interno! :)

spv42
04-12-2006, 08:44
Ok, Il Mio TableModel Funziona, ora riesco a non far inserire nella colonna che volevo!

Ora però vorrei che le celle di quella colonna non mi si "illuminassero".

Come posso fare?

PGI-Bis
04-12-2006, 13:28
In che senso "far inserire nella colonna che volevo"?

In una JTable per inserire i dati l'utente fa doppio click su una cella, digita e preme invio oppure digita e preme invio. Nel secondo caso l'inserimento avviene nella cella attualmente selezionata.

In entrambi i casi è l'utente che sceglie la colonna – quella a cui appartiene la cella selezionata.

Mi sembra che tu stia cercando una terza via che è più che lecito ma forse mi sfugge quale sia. Cosa vuoi fare a questa tabella? E non dire Excel, perchè io uso OpenOffice :D.

L'illuminazione delle celle appartenenti ad una colonna può essere disattivata con jtable.setColumnSelectionAllowed(false).

L'illuminazione delle celle appartenti ad una colonna ha un effetto "tipico" solo se la corrispondente illuminazione delle celle appartenenti ad un riga sia disattivata.

Comunque, poichè sono tutti colori applicati dal proiettore delle celle, che cosa capiti controllando quei due valori dipende dal TableCellRenderer.

spv42
04-12-2006, 13:42
In che senso "far inserire nella colonna che volevo"?

In una JTable per inserire i dati l'utente fa doppio click su una cella, digita e preme invio oppure digita e preme invio. Nel secondo caso l'inserimento avviene nella cella attualmente selezionata.

Io su alcune colonne volevo disattivare L'editing!!! E grazie al tuo aiuto ci sono riuscito!

L'illuminazione delle celle appartenenti ad una colonna può essere disattivata con jtable.setColumnSelectionAllowed(false).


Però cosi facendo viene applicato a tutte le colonne del Jtable!, io lo voglio applicare solo sulla prima colonna!

PGI-Bis
04-12-2006, 14:24
Cioè una cosa di questo tipo?

http://www.tukano.it/jtableguess.png

spv42
04-12-2006, 14:45
Esatta la terza immagine!!!

Sulla 1° colonna non si può editare e non deve essere illuminata.

Quindi se sono sulla cella B0 e premo Tab non devo andare sulla A1 ma sulla B1!!

PGI-Bis
04-12-2006, 15:00
Ahhhhhhhhh!

Pensavo a tutt'altro (anche quando ho fatto gli screenshot).

Usa due tabelle per lo stesso tablemodel. La prima immutabile, la seconda modificabile. La prima proietta il contenuto della prima colonna del modello. La seconda proietta il contenuto delle colonne seguenti la prima. Le affianchi e sei a cavallo.

spv42
04-12-2006, 15:09
:confused:

Mica ti ho capito!!!

PGI-Bis
04-12-2006, 16:03
Insomma, ci capiamo alla perferzione :D.

Diciamo che quello che vuoi fare è questo:

http://www.tukano.it/jtablemaybe.png

Le immagini si riferisco a ciò che succede quanto l'utente preme "tab". Si può fare in tanti modi ma quello che mi pare più semplice è questo.

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.util.*;

public class Main implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Main());
}

private JFrame frame;

public Main() {
Object[] no = null;
/** Questo è il modello reale */
DefaultTableModel model = new DefaultTableModel();
model.addColumn("A");
model.addColumn("B");
model.addColumn("C");
model.addRow(no);
model.addRow(no);
model.addRow(no);
model.addRow(no);
model.addRow(no);

/** Questo è un modello associato alla prima colonna
del modello reale */
LeftModel leftModel = new LeftModel(model);

/** Questo è un modello associato alle colonne successive
del modello reale */
RightModel rightModel = new RightModel(model);

/** Questa è la tabella della parte sinistra (colonna 0) */
JTable leftTable = new JTable(leftModel);
/** Che non è interattiva */
leftTable.setEnabled(false);

/** Questa è la tabella della parte destra (colonne da 1
in poi) */
JTable rightTable = new JTable(rightModel);

/** In cui la selezione illumina la sola cella selezionata */
rightTable.setColumnSelectionAllowed(true);
rightTable.setRowSelectionAllowed(true);

/** Questo è il contenitore delle due tabelle, che le
fa sembrare una tabella unica */
JPanel tableContainer = new JPanel(new BorderLayout());
tableContainer.add(leftTable, BorderLayout.WEST);
tableContainer.add(rightTable, BorderLayout.CENTER);

/** Questo è il contenitore delle intestazioni delle due tabelle
che fa apparire l'intestazione unica */
JPanel tableHeaderContainer = new JPanel(new BorderLayout());
tableHeaderContainer.add(leftTable.getTableHeader(), BorderLayout.WEST);
tableHeaderContainer.add(rightTable.getTableHeader(), BorderLayout.CENTER);

/** Infila nello scroller il contenitore delle due tabelle */
JScrollPane scroller = new JScrollPane(tableContainer);

/** Visualizza le intestazioni delle tabelle */
scroller.setColumnHeaderView(tableHeaderContainer);
JFrame window = new JFrame("Window");
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.add(scroller);
frame = window;
}

public void run() {
frame.pack();
frame.setVisible(true);
System.out.println(frame.getSize());
}
}

/** Modello per la tabella di destra (colonna zero) */
class RightModel implements TableModel {
/* Modello che contiene i dati della tabella */
private TableModel model;

public RightModel(TableModel model) {
this.model = model;
}

public void addTableModelListener(TableModelListener l) {
model.addTableModelListener(l);
}

public Class<?> getColumnClass(int columnIndex) {
return model.getColumnClass(columnIndex + 1);
}

public int getColumnCount() {
return model.getColumnCount() - 1;
}

public String getColumnName(int columnIndex) {
return model.getColumnName(columnIndex + 1);
}

public int getRowCount() {
return model.getRowCount();
}

public Object getValueAt(int row, int col) {
return model.getValueAt(row, col + 1);
}

public boolean isCellEditable(int row, int col) {
return model.isCellEditable(row, col + 1);
}

public void removeTableModelListener(TableModelListener l) {
model.removeTableModelListener(l);
}

public void setValueAt(Object v, int row, int col) {
model.setValueAt(v, row, col + 1);
}
}

/** Modello per la tabella di destra (colonne da 1 a columnCount - 1)*/
class LeftModel implements TableModel {
private TableModel model;

public LeftModel(TableModel model) {
this.model = model;
}

public void addTableModelListener(TableModelListener l) {
model.addTableModelListener(l);
}

public Class<?> getColumnClass(int columnIndex) {
return model.getColumnClass(columnIndex);
}

public int getColumnCount() {
return 1;
}

public String getColumnName(int columnIndex) {
return model.getColumnName(columnIndex);
}

public int getRowCount() {
return model.getRowCount();
}

public Object getValueAt(int row, int col) {
return model.getValueAt(row, col);
}

public boolean isCellEditable(int row, int col) {
return model.isCellEditable(row, col);
}

public void removeTableModelListener(TableModelListener l) {
model.removeTableModelListener(l);
}

public void setValueAt(Object v, int row, int col) {
model.setValueAt(v, row, col);
}
}

Anzichè una tabella per un modello crei due tabelle per due modelli dove i due modelli propongono alla tabella due parti diverse dell'unico modello reale.

spv42
04-12-2006, 17:25
Grazie, era prioprio quello che volevo!

Sei Proprio un Fenomeno! :D

Visto che siamo entrati così in "sintonia",....

Ora avrei bisogno che se mi trovo nella cella C4, premendo tab, il tabelModel mi aggiunga una riga vuota e naturalmente si posizionasse sulla cella B5!!

Devo associare un Action alla colonna C??? Come si fà?

P.S. Ma c'è un totorial più avanzato sulle Jtable, di quello della SUn?

Tu dove hai studiato?

spv42
05-12-2006, 13:46
Up!

PGI-Bis
05-12-2006, 14:41
Aggiungi un KeyListener alla tabella. Nel suo KeyPressed, quando il codice del tasto è KeyEvent.VK_TAB e la riga/colonna corrente corriponde alla cella che vuoi tu, aggiungi al modello della tabella una riga (il modello "vero").

Supponendo che "table" sia la tabella e "dataModel" il DefaultTableModel che contiene i dati, il KeyListener potrebbe essere:

private KeyListener tabHandler = new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_TAB) {
int row = table.getSelectedRow();
int col = table.getSelectedColumn();
if(row == 4 && col == 1) {
Object[] NULL = null;
dataModel.addRow(NULL);
}
}
}
};

E' un po' bizzarro che sia propio la C4 a scatenare questo evento ma avrai le tue ottime ragioni per farlo.

spv42
05-12-2006, 17:55
E' un po' bizzarro che sia propio la C4 a scatenare questo evento ma avrai le tue ottime ragioni per farlo.


No, perchè ti sembra fantasioso?
Devo aggiungere delle righe solo se riempio le prime 5 righe!!

Grazie Ancora!

Conosci un sito per un buon tutorial sulle JTable?

PGI-Bis
06-12-2006, 14:43
Non fantasioso, strano. Strano per due ragioni, frutto di una delle incomprensione a cui siamo ormai abituati :D

Non la cella C4 in sè attiva l'inserimento di una nuova riga ma più generalmente l'ultima cella dell'ultima riga.

La seconda, più rilevante, è che l'associazione di più funzioni ad un unico controllo può rendere equivoca l'interazione utente nella misura in cui vari il contesto che determina la produzione dell'uno o dell'altro effetto.

Abbiamo hai un tasto tab che sulla stessa tabella fa due cose: scorre il focus tra le celle e determina una mutazione della struttura della tabella.

L'utente si impappinerà? E possibile che vada tutto liscio. Principalmente perchè se la cella "sensibile" è sempre l'ultima allora la condizione che determina la mutazione di risultato ha un'identità visuale diretta e primitiva (ciò che corrisponde ai concetti di posizione a destra di, a sinistra di, in fondo a, in cima a, rispetto ad un entità interamente visibile).

Certo in linea di principio la sovrapposizione andrebbe evitata ma comprendo (o fraintendo :D) la necessità di simulare una tabella dotata di un numero indeterminato di righe.

Non conosco siti che trattino le JTable oltre i concetti di base e non ho esperienza diretta di libri che lo facciano ma ho sentito di un tomo il cui titolo potrebbe suonare "Advanced Swing" o simili che si concentra sulle tabella. Devo dire però che col tempo ho imparato a diffidare di ciò che taluni autori intendono per "Advanced" :D.