java - 监听JTable的变化

标签 java swing jtable

我有一个名为 Model 的类,我想将其表示为 JTable,我设法通过子类化 AbstractTableModel 来实现这一点。 我的问题是如何监听数据的变化并更新我的模型,我研究了很多教程,发现他们实现了 TableModelListener 并使用 void tableChanged() 方法,但这不起作用,所以我怎么不能去进入 tableChanged() 方法并执行我想要的操作。 相反,进入 setValueAt() 方法并在其中实现我想要的逻辑,并且它有效 但我必须实现 TableModelListener 接口(interface),它的方法 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 的面板 包 View ;

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 类,它聚合模型类以添加读/写数据库或文件等功能 ** 注意:我正在使用 singleton 设计模式。

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

最佳答案

你应该考虑重构你的AbstractTableModel实现。它是Subject,他自己的Observer没有多大意义。您应该分开职责( 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 ,

关于java - 监听JTable的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17816381/

相关文章:

Java 通过单击按钮打开一个新窗口

Java JTextfield 固定文本,允许在文本开头附加文本

java - 如何将 true 转换为 Boolean.TRUE?

java - jTable 将所有内容排序为字符串

java - 水平滚动条不适用于 Java Swing 中的 JTable

java - 光栅化 Java 字体

java - android - 使 ListView 项目在浏览器中打开 URL?

java - 我是否应该使用一种修改后的单例设计模式,只允许对其实例进行一次引用?

java - HttpClient/BufferedReader 返回乱码

java - 我无法让我的图标显示在我的 JLabel swing 组件中