Note that there are some explanatory texts on larger screens.

plurals
  1. POListening to JTable changes
    text
    copied!<p>I have a class called Model that I wanted to represent as JTable, I manged to do that through subclassing AbstractTableModel. my problem is how to listen to changes in data and update my model, I looked into many tutorials and I found out that they implement TableModelListener and use void tableChanged() method but that didn't work for, som how I couldn't go into tableChanged() method and do the manipulation that I wanted. Instead went into setValueAt() method and implemented the logic i want inside it and it worked but i had to implement TableModelListener interface and it's method tableChanged() with empty code which i don't understand why. I think I have a problem understanding how tableListener works.</p> <pre><code> 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); } } </code></pre> <p>and this is the panel that im showing the JTable in it package view;</p> <pre><code>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&lt;Model&gt; 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); } } </code></pre> <p>and this is my ModelsDictionary class which aggregate Model class to add fuctionalties like reading/writing to DB or Files ** note: i'm using singelton design pattern.</p> <pre><code>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&lt;Model&gt; models = new ArrayList&lt;Model&gt;(); private ArrayList&lt;String&gt; modelNumbers = new ArrayList&lt;String&gt;(); 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&lt;Model&gt; getAllModels() { return models; } public ArrayList&lt;String&gt; getAllModelNumbers() { return modelNumbers; } public void readXMLfile() { models = new ArrayList&lt;Model&gt;(); 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 &lt; 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(); } } } </code></pre> <p>the question is: i'm I doing this the right way because i intend to add more functionalties like add row and remove row. because it seems the code is working to edit cells by just using the setValueAt() method only and i don't how or why</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload