0

我有一个名为 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 类以添加读取/写入数据库或文件等功能 ** 注意:我使用的是单格顿设计模式。

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() 方法来编辑单元格,我不知道如何或为什么

4

1 回答 1

1

你应该在重构你的AbstractTableModel实现时考虑一下。它是 Subject 和他自己的 Observer 没有多大意义。你应该分开责任(单一责任原则)。

在您的代码中,当您编辑一个单元格时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  

     }

我这里有类似的问题,

于 2013-07-23T17:23:08.157 回答