我有一个名为Model的类,我想表示为JTable,我通过继承AbstractTableModel来做到这一点。 我的问题是如何监听数据的变化并更新我的模型,我查看了许多教程,我发现他们实现了TableModelListener并使用了void tableChanged()方法,但这不起作用,我不能去到tableChanged()方法并执行我想要的操作。 而是进入了setValueAt()方法并实现了我想要的逻辑并且它起作用 但我不得不实现TableModelListener接口和它的方法tableChanged()与空代码,我不明白为什么。 我认为我在理解tableListener的工作原理时遇到了问题。
package model;
import java.util.ArrayList;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
public class ModelsTable extends AbstractTableModel implements TableModelListener
{
private String[] columnNames = { "Model",
"mac start", "mac end",
"host start", "host end",
"dn start" , "dn end",
"sn start" , "sn end"};
private ModelsDictionary dictionary = ModelsDictionary.getModelsDictionary();
public ModelsTable()
{
this.addTableModelListener(this);
}
public void fireTableCellUpdated(int row, int col)
{
System.out.println(row + "" + col);
}
@Override
public int getColumnCount()
{
return columnNames.length;
}
@Override
public int getRowCount()
{
return dictionary.getAllModels().size();
}
public String getColumnName(int col)
{
return columnNames[col];
}
@Override
public void setValueAt(Object aValue, int row, int col)
{
System.out.println(row + " " + col);
Model model = dictionary.getAllModels().get(row);
Model newModel;
if(col == 0)
{
newModel = new Model((String)aValue,model.getMacStart(),model.getMacEnd(),model.getHostStart(),model.getHostEnd(),model.getDnStart(),model.getDnEnd(),model.getSnStart(),model.getSnEnd());
dictionary.updateModel(model,newModel);
}
else if(col == 1)
{
newModel = new Model(model.getNumber(),(String)aValue,model.getMacEnd(),model.getHostStart(),model.getHostEnd(),model.getDnStart(),model.getDnEnd(),model.getSnStart(),model.getSnEnd());
dictionary.updateModel(model,newModel);
}
else if(col == 2)
{
newModel = new Model(model.getNumber(),model.getMacStart(),(String)aValue,model.getHostStart(),model.getHostEnd(),model.getDnStart(),model.getDnEnd(),model.getSnStart(),model.getSnEnd());
dictionary.updateModel(model,newModel);
}
else if(col == 3)
{
newModel = new Model(model.getNumber(),model.getMacStart(),model.getMacEnd(),(String)aValue,model.getHostEnd(),model.getDnStart(),model.getDnEnd(),model.getSnStart(),model.getSnEnd());
dictionary.updateModel(model,newModel);
}
else if(col == 4)
{
newModel = new Model(model.getNumber(),model.getMacStart(),model.getMacEnd(),model.getHostStart(),(String)aValue,model.getDnStart(),model.getDnEnd(),model.getSnStart(),model.getSnEnd());
dictionary.updateModel(model,newModel);
}
else if(col == 5)
{
newModel = new Model(model.getNumber(),model.getMacStart(),model.getMacEnd(),model.getHostStart(),model.getHostEnd(),(String)aValue,model.getDnEnd(),model.getSnStart(),model.getSnEnd());
dictionary.updateModel(model,newModel);
}
else if(col == 6)
{
newModel = new Model(model.getNumber(),model.getMacStart(),model.getMacEnd(),model.getHostStart(),model.getHostEnd(),model.getDnStart(),(String)aValue,model.getSnStart(),model.getSnEnd());
dictionary.updateModel(model,newModel);
}
else if(col == 7)
{
newModel = new Model(model.getNumber(),model.getMacStart(),model.getMacEnd(),model.getHostStart(),model.getHostEnd(),model.getDnStart(),model.getDnEnd(),(String)aValue,model.getSnEnd());
dictionary.updateModel(model,newModel);
}
else if(col == 8)
{
newModel = new Model(model.getNumber(),model.getMacStart(),model.getMacEnd(),model.getHostStart(),model.getHostEnd(),model.getDnStart(),model.getDnEnd(),model.getSnStart(),(String)aValue);
dictionary.updateModel(model,newModel);
}
}
@Override
public Object getValueAt(int x, int y)
{
Model model = dictionary.getAllModels().get(x);
switch(y) {
case 0:
return model.getNumber();
case 1:
return model.getMacStart();
case 2:
return model.getMacEnd();
case 3:
return model.getHostStart();
case 4:
return model.getHostEnd();
case 5:
return model.getDnStart();
case 6:
return model.getDnEnd();
case 7:
return model.getSnStart();
case 8:
return model.getSnStart();
default:
return "unknown";
}
}
public boolean isCellEditable(int row, int col)
{
return true;
}
@Override
public void tableChanged(TableModelEvent event)
{
System.out.println("lol");
int row = event.getFirstRow();
int column = event.getColumn();
ModelsTable model = (ModelsTable)event.getSource();
String columnName = model.getColumnName(column);
Model data = (Model) model.getValueAt(row, column);
System.out.println(model);
}
}
这是我在其中展示JTable的面板 包视图;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import Control.InteractiveTableModelListener;
import model.Model;
import model.ModelsDictionary;
import model.ModelsTable;
import net.miginfocom.swing.MigLayout;
public class AllModelsPanel extends JPanel
{
private boolean DEBUG = false;
public AllModelsPanel()
{
super(new GridLayout(1, 0));
ArrayList<Model> models = ModelsDictionary.getModelsDictionary().getAllModels();
JTable table = new JTable();
table.setModel(new ModelsTable());
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
}
这是我的ModelsDictionary类,它聚合Model类来添加诸如读/写DB或Files之类的功能 **注意:我正在使用singelton设计模式。
package model;
import java.io.File;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class ModelsDictionary
{
private static ModelsDictionary myInstance;
private ArrayList<Model> models = new ArrayList<Model>();
private ArrayList<String> modelNumbers = new ArrayList<String>();
private ModelsDictionary()
{
readXMLfile();
}
public static ModelsDictionary getModelsDictionary()
{
if (myInstance == null )
{
synchronized(ModelsDictionary.class)
{
if( myInstance == null)
{
myInstance = new ModelsDictionary();
}
}
}
return myInstance;
}
public void addModel(Model model)
{
models.add(model);
modelNumbers.add(model.getNumber());
writeXMLfile();
}
public void deleteModel(Model model)
{
models.remove(model);
modelNumbers.remove(model.getNumber());
}
public void updateModel(Model oldModel, Model newModel)
{
int index = models.indexOf(oldModel);
System.out.println("index" + index);
models.set(index, newModel);
writeXMLfile();
}
public Model getModel(String modelNumber)
{
//System.out.println("getModels ,,,, models size: " +models.size());
for(Model model: models)
{
//System.out.println("in models");
if(model.getNumber().equals(modelNumber))
{
//System.out.println("model number matched");
return model;
}
}
return null;
}
public ArrayList<Model> getAllModels()
{
return models;
}
public ArrayList<String> getAllModelNumbers()
{
return modelNumbers;
}
public void readXMLfile()
{
models = new ArrayList<Model>();
try
{
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
File file = new File("models.xml");
if(file.exists())
{
Document doc = dBuilder.parse(file);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("Model");
for (int i = 0; i < nList.getLength(); i++)
{
Node nNode = nList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element)nNode;
String number = eElement.getElementsByTagName("Number").item(0).getTextContent();
String macStart = eElement.getElementsByTagName("MacStart").item(0).getTextContent();
String macEnd = eElement.getElementsByTagName("MacEnd").item(0).getTextContent();
String hostStart = eElement.getElementsByTagName("HostStart").item(0).getTextContent();
String hostEnd = eElement.getElementsByTagName("HostEnd").item(0).getTextContent();
String snStart = eElement.getElementsByTagName("SnStart").item(0).getTextContent();
String snEnd = eElement.getElementsByTagName("SnEnd").item(0).getTextContent();
String dnStart = eElement.getElementsByTagName("DnStart").item(0).getTextContent();
String dnEnd = eElement.getElementsByTagName("DnEnd").item(0).getTextContent();
Model model = new Model(number);
model.setMacPatt(macStart, macEnd);
model.setDnPatt(dnStart, dnEnd);
model.setSnPatt(snStart, snEnd);
model.setHostPatt(hostStart, hostEnd);
addModel(model);
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void writeXMLfile()
{
try
{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("Models");
doc.appendChild(rootElement);
for(Model model : models)
{
Element m = doc.createElement("Model");
rootElement.appendChild(m);
Element number = doc.createElement("Number");
number.setTextContent(model.getNumber());
m.appendChild(number);
Element macStart = doc.createElement("MacStart");
macStart.setTextContent(model.getMacStart());
m.appendChild(macStart);
Element macEnd = doc.createElement("MacEnd");
macEnd.setTextContent(model.getMacEnd());
m.appendChild(macEnd);
Element hostStart = doc.createElement("HostStart");
hostStart.setTextContent(model.getHostStart());
m.appendChild(hostStart);
Element hostEnd = doc.createElement("HostEnd");
hostEnd.setTextContent(model.getHostEnd());
m.appendChild(hostEnd);
Element dnStart = doc.createElement("DnStart");
dnStart.setTextContent(model.getDnStart());
m.appendChild(dnStart);
Element dnEnd = doc.createElement("DnEnd");
dnEnd.setTextContent(model.getDnEnd());
m.appendChild(dnEnd);
Element snStart = doc.createElement("SnStart");
snStart.setTextContent(model.getSnStart());
m.appendChild(snStart);
Element snEnd = doc.createElement("SnEnd");
snEnd.setTextContent(model.getSnEnd());
m.appendChild(snEnd);
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(doc);
File file = new File("models.xml");
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
问题是:我正在以正确的方式这样做,因为我打算添加更多功能,例如添加行和删除行。 因为似乎代码只是通过使用setValueAt()方法来编辑单元格而我不知道如何或为什么
答案 0 :(得分:1)
你应该考虑重构你的AbstractTableModel
实现。这是主题和他自己的观察者没有多大意义。您应该将责任分开(Single Responsability Principle)。
在您的代码中,当您编辑单元格setValueAt(Object value,int row,int col)
时,会调用它。
@Override
public void setValueAt(Object aValue, int row, int col)
{
//your default code here
and then you should call
fireTableRowsUpdated(row,row); // if you change the row
OR
fireTableCellUpdated(row,col); // if you change the cell
OR
fireTableDataChanged(); // if you change all the model
}
我有类似的问题here,