View Full Version : [java] Modifica Jtable
bobby1112
20-02-2010, 10:49
salve ragazzi o questo problema ho una Jtable quando clicco su una cella mi compare una JList con degli elementi quando effettuo doppio click su uno degli elementi della jlist mi deve cambiare il valore della cella in JTable mi date qualche consiglio:muro:
Devi creare un tuo TableCellEditor e assegnarlo alla tabella per le celle che vuoi cambiare con quell'editor.
Ho sottomano un esempio in Scala ma è praticamente identico a quello che faresti in Java (le librerie son quelle, _ vale null, var e val sono campi, def sono metodi, il tipo è scritto a destra dopo i : anzichè a sinistra prima del nome, with = implements):
import javax.swing._
import javax.swing.table._
import java.awt._
import java.awt.event._
object Main {
def main(args:Array[String]) {
EventQueue.invokeLater(new Runnable {
def run = start()
});
}
def start() {
val model = new DefaultTableModel()
model.addColumn("Nomi")
model.addColumn("Capitali")
model.addRow(Array[Object]("", ""))
model.addRow(Array[Object]("", ""))
val listEditor = new ListEditor()
val table = new JTable(model) {
override def getCellEditor(row: Int, col: Int) = {
if(col == 1) listEditor else super.getCellEditor(row, col)
}
}
table.setRowHeight(Math.round(table.getRowHeight() * 1.5f))
val frame = new JFrame("Test")
frame.add(new JScrollPane(table))
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
frame.pack()
frame.setVisible(true)
}
}
class ListEditor extends AbstractCellEditor with TableCellEditor {
private val list : JList = new JList(Array[Object]("Roma", "Atene", "Berlino"))
private val component ; JScrollPane = new JScrollPane(list)
private var oldValue : Object = _
private var editorValue : Object = _
list.addMouseListener(new MouseAdapter {
override def mousePressed(e: MouseEvent) {
/** Doppio click col sinistro */
if(SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 2) {
val index = list.locationToIndex(e.getPoint())
if(index >= 0) {
editorValue = list.getModel().getElementAt(index)
fireEditingStopped()
}
}
}
})
def getTableCellEditorComponent(table: JTable, value: Object, isSelected: Boolean, row: Int, column: Int) : Component = {
oldValue = value
editorValue = value
list.setSelectedValue(oldValue, true)
return component
}
def getCellEditorValue() : Object = {
return editorValue
}
override def cancelCellEditing() : Unit {
editorValue = oldValue
fireEditingCanceled()
}
override def stopCellEditing() : Boolean = {
val selection = Option(list.getSelectedValue)
selection.foreach(v => editorValue = v)
fireEditingStopped()
return true
}
}
Esteticamente viene meglio se usi una JComboBox al posto della JList. Il principio non cambia.
bobby1112
20-02-2010, 15:27
ciao grazie dell' aito ma è da poco che ho a che fare con le Jtable e o qualche difficoltà
if(col == 1) listEditor else super.getCellEditor(row, col)
qui per esempio non ho capito cosa fare con listEditor
poi
def getTableCellEditorComponent(table: JTable, value: Object, isSelected: Boolean, row: Int, column: Int) : Component = {
oldValue = value
editorValue = value
list.setSelectedValue(oldValue, true)
return component
}
mi puoi spiegare un pò questa
list.setSelectedValue(oldValue, true)
ti ringrazio
La prima è nella sovrascrittura del metodo getCellEditor. Per ogni cella una JTable ha un certo editor - che sarebbe il componente che si occupa di modificare il contenuto di quella cella. JTable ha un paio di modi per personalizzare il tipo di editor che si vuole usare per certe celle. Uno è appunto la sovrascrittura di getCellEditor.
Quel
if(col == 1) listEditor else super.getCellEditor(row, col)
che sarebbe un:
if(col == 1) {
return listEditor;
} else {
return super.getCellEditor(row, col)
}
dice che se la cella di cui si vuole cambiare il contenuto si trova nella seconda colonna allora l'editor da usare è il nostro, altrimenti deve usare quello predefinito. L'ho messo giusto per fare vedere, è ben possibile che tu abbia necessità diverse (magari più di una colonna oppore tutte le colonne o solo alcune righe, vedi tu, quel metodo ti permette di fare come preferisci).
Il secondo pezzo serve per far apparire il valore attualmente contenuto nella cella anche nell'editor.
Quando l'utente esprime la volontà di cambiare il contenuto di una cella - attraverso cliccamenti vari o che altro - la tabella prende il valore della cella e lo passa al metodo getTableCellEditorComponent - nel parametro value.
Nello stesso metodo l'editor si prepara a consentire la modifica della cella.
Non è obbligatorio ma comune che l'editor appaia usando come valore corrente della modifica il valore che la cella ha.
Così il nostro editor in quel metodo dice:
quando la tabella mi comunica che devo entrare in gioco, assumo come mio valore quello della cella che devo modificare e poi appaio.
IL true serve per far sì che la lista (inserita in un JScrollPane) scorra fino a visualizzare il valore scelto
bobby1112
20-02-2010, 15:56
il modello della mia tabella è questo
private class TableModelDatabase extends AbstractTableModel{
private static final long serialVersionUID = 1L;
private SourceEntity entity = null;
public void setEntity(SourceEntity entity){
this.entity = entity;
}
public int getColumnCount() {
return 1;
}
@Override
/*
public boolean isCellEditable(int rowIndex, int columnIndex) {
if (columnIndex == 0){
return true;
}
return false;
}
*/
public int getRowCount() {
if (entity != null){
return entity.getAttributes().size();
}else{
return 1;
}
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (entity != null){
Attribute attribute = entity.getAttributes().get(rowIndex);
if (columnIndex == 0)
return attribute.getOriginalType();
}
return null;
}
public String getColumnName(int column) {
return "<html><h4>"+entity.getOriginalName()+"</h4><html>";
}
//Selezionare il tipo con menu a tendina
@Override
public void setValueAt(Object arg0, int arg1, int arg2) {
super.setValueAt(arg0, arg1, arg2);
if (arg2 == 2){
entity.getAttributes().get(arg1).setImportedType(arg0);
}
}
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
}
quindi non so come gestire la riscrittura di
override def getCellEditor(row: Int, col: Int) = {
il metodo da sovrascrivere è di JTable, non del suo modello. Da qualche parte avrai una cosa tipo:
JTable table = new JTable(ilModello);
Basta cambiarlo in:
JTable table = new JTable(ilModello) {
private final ListEditor editor = new ListEditor();
@Override
public TableCellEditor getCellEditor(int row, int col) {
...se la riga o la colonna della tabella identificano
...una cella che vuoi cambiare col tuo editor, restituisci editor
...altrimenti super.getCellEditor(row, col);
}
}
bobby1112
20-02-2010, 16:49
non riesco bene a capire il funzionamento
questa è lamia Jdialog contenente la tabella
public CheckDialog(JFrame owner,String [][] datatype,SourceEntity typdatatype,String database)
{
super(owner);
this.setTitle("Check DataType");
this.owner=owner;
dataTypeDb=datatype;
dataTypeTyp=typdatatype;
databaseName=database;
model.setEntity(dataTypeTyp);
model2.setEntity(dataTypeDb,typdatatype.getName());
tableTypeDatabase=new JTable(model2) {
private static final long serialVersionUID = 1L;
private final ListEditor editor = new ListEditor();
@Override
public TableCellEditor getCellEditor(int row, int col) {
if(col==0)
{
System.out.println("RITORNO MIO EDITOR");
return editor;
}
else
super.getCellEditor(row, col);
return editor;
}
};
tableTypeTyp=new JTable(model);
this.setSize(500,300);
if (owner != null){
int x = (owner.getWidth() - this.getWidth()) / 2;
int y = (owner.getHeight() - this.getHeight()) / 2;;
this.setLocation(x, y);
}
Box top=Box.createVerticalBox();
Box boxLabel=Box.createHorizontalBox();
top.add(boxLabel);
boxLabel.add(label1);
boxLabel.add(Box.createHorizontalStrut(190));
boxLabel.add(label2);
top.add(Box.createVerticalStrut(30));
Box table1=Box.createHorizontalBox();
top.add(table1);
table1.add(new JScrollPane(tableTypeDatabase));
table1.add(Box.createHorizontalStrut(30));
table1.add(new JScrollPane(tableTypeTyp));
settingTableDimension();
addFeatures();
addListener();
JPanel panel = new JPanel();
panel.add(top);
getContentPane().add(panel);
this.setVisible(true);
}
e questa e la classe per l' editor
public class ListEditor extends AbstractCellEditor implements TableCellEditor{
String oldValue;
String editorValue;
Component component;
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean arg2, int arg3, int arg4) {
oldValue = (String)value;
editorValue =(String) value;
typeDialog.getjListType().setSelectedValue(oldValue, true); //type dialog e un' altra jDialog contenente la lista dove ho aggiunto il mouselistener per il doppio click
return component;
}
@Override
public Object getCellEditorValue() {
return editorValue;
}
:confused: :confused: :confused: :confused:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.