- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是的,我知道,这听起来很愚蠢。但在此之前,让我先说明一下我的问题。
我有一个带有大量 JTable 的 GUI。我有各种 DefaultTableModel,每个 JTable 一个。所以,1:1。对于每个 DefaultTableModel,我都创建了一个 TableModelListener。
为了在 GUI 中插入和删除元素,我只创建了两个方法:addVehicle 和 removeVehicle:
public void addVehicle(final DefaultTableModel model, final String s1, final String s2) {
Runnable addV = new Runnable() {
@Override
public void run() {
model.addRow(new Object[] { s1, s2 });
}
};
SwingUtilities.invokeLater(addV);
}
public void removeVehicle(final DefaultTableModel model, final int index) {
if (row!=null){
String s1= row.elementAt(0).toString();
Runnable removeV = new Runnable() {
@Override
public void run() {
model.removeRow(index);
}
};
SwingUtilities.invokeLater(removeV);
}
}
这些方法很完美,自动识别正确的表模型。
但我有一个必要性:因为我有很多 JTable(以及相应的 DefaultTableModel),并且考虑到当我从表中添加/删除一行时必须通知第三方软件,所以我创建了几个 TableModelListener。
例如监听器1:
TableModelListener listener1 = new TableModelListener() {
public void tableChanged(TableModelEvent e) {
DefaultTableModel m = (DefaultTableModel) e.getSource();
int row = e.getLastRow();
switch (e.getType()) {
case (TableModelEvent.INSERT): {
System.out.println("Insert! Key: "+m.getValueAt(row, 0));
// My agent, the third-party software:
shipperAgent.newTruck((String) m.getValueAt(row, 0));
} break;
case (TableModelEvent.DELETE): {
System.out.println("Delete! Key:"+m.getValueAt(row, 0));
// My agent, the third-party software:
shipperAgent.removeTruck((String)m.getValueAt(row, 0));
} break;
case (TableModelEvent.UPDATE): {
// ...
} break;
}
}
};
另一个例子是监听器 2(我只向您展示一个片段...):
case (TableModelEvent.INSERT): {
System.out.println("Activate! Key: "+m.getValueAt(row, 0));
// My agent, the third-party software:
shipperAgent.activateTruck((String) m.getValueAt(row, 0));
} break;
case (TableModelEvent.DELETE): {
System.out.println("Deactivate! Key:"+m.getValueAt(row, 0));
// My agent, the third-party software:
shipperAgent.deactivateTruck((String)m.getValueAt(row, 0));
} break;
这就是问题所在:插入可以,但删除不行。我知道为什么:当我从 GUI 中删除一行时,该行将被删除,并在开关(案例 TableModelEvent.DELETE)中处理另一行(紧接在我删除的行之后)。此外,如果这一行是最后一行(因为之后没有更多行),我会得到一个 NullPointerException。
如何在监听器中在实际删除行之前使用该行? (或者其他绝妙的方法?)
最佳答案
...when I add/delete a row from a table a third-party software MUST BE INFORMED, I have created several TableModelListener.
如果您看到 TableModelEvent API 无法从事件本身获取数据,您拥有的只是 TableModel这是事件的来源。话虽如此,当表模型事件被触发时,模型中的更改已经完成,您对此无能为力,因此您无法仅仅因为这些赢得了删除的行值而获得删除的行值不再在那里了。
但是,如果您关心的是通知此第三方软件以保持一致性,我想,那么您应该考虑在从表模型中删除行之前这样做.
public void removeVehicle(final DefaultTableModel model, final int index) {
String value = (String)model.getValueAt(index, 0);
shipperAgent.deactivateTruck(value);
// If everything went ok, then remove the row from the table model.
// Of course, do it in the Event Dispatch Thread.
model.removeRow(index);
}
通过这种方式,您甚至可以协调第三方软件和您的应用程序:如果无法停用该行代表的卡车,则不要删除表模型中的该行,而是显示一些错误消息。
<小时/>But I wanted to centralize communication with the agent (third party software) and separate it from the rest of the code, and not disseminate it.
嗯,这是完全有道理的,我确信有不止一种方法可以实现这一点,但恕我直言,您的设计需要另一种转变才能满足这些要求:
我在想接近 Mediator pattern 的东西(不完全是这个模式,而是一些接近的模式)可能会帮助您封装协调逻辑并解耦同一事务中涉及的第三方代理和表模型。例如,考虑这个原型(prototype)类:
public abstract class Coordinator {
/*
* protected class members so subclasses can access these directly
*/
protected ShipperAgent shipperAgent;
protected DefaultTableModel tableModel;
public Coordinator(ShipperAgent sa, DefaultTableModel tm) {
shipperAgent = sa;
tableModel = tm;
}
public abstract void notifyAndAddRow(Object[] rowData);
public abstract void notifyAndDeleteRow(int rowIndex);
}
由于您在调用 addVehicle(...)
和 removeVehicle(...)
方法时已成功识别正确的表模型,因此您可能会可以执行相同的操作来识别正确的协调器并委托(delegate)通知第三方代理和更新表模型的任务。例如:
ShipperAgent sa = new ShipperAgent(...);
DefaultTableModel model1 = new DefaultTableModel(...);
DefaultTableModel model2 = new DefaultTableModel(...);
Coordinator coordinator1 = new Coordinator(sa, model1) {
@Override
public void notifyAndAddRow(Object[] rowData) {
this.shipperAgent.newTruck((String) rowData[0]);
this.tableModel.addRow(rowData); // do this in the EDT
}
@Override
public void notifyAndDeleteRow(int rowIndex) {
String truck = (String)this.tableModel.getValueAt(rowIndex, 0);
this.shipperAgent.removeTruck(truck);
this.tableModel.removeRow(rowIndex); // do this in the EDT
}
};
Coordinator coordinator2 = new Coordinator(sa, model2) {
@Override
public void notifyAndAddRow(Object[] rowData) {
this.shipperAgent.activateTruck((String) rowData[0]);
this.tableModel.addRow(rowData); // do this in the EDT
}
@Override
public void notifyAndDeleteRow(int rowIndex) {
String truck = (String)this.tableModel.getValueAt(rowIndex, 0);
this.shipperAgent.removeTruck(truck);
this.tableModel.removeRow(rowIndex); // do this in the EDT
}
};
那么您的 addVehicle(...)
和 removeVehicle(...)
方法可能如下所示:
public void addVehicle(Coordinator coordinator, String s1, String s2) {
coordinator.notifyAndAddRow(new Object[]{s1, s2});
}
public void removeVehicle(Coordinator coordinator, int index) {
coordinator.notifyAndDeleteRow(index);
}
当然,正如我所说,在调用 addVehicle(...)
和 时,您必须设法识别正确的
方法,但我认为您现在已经拥有解决问题所需的抽象。Coordinator
实例。 removeVehicle(...)
关于java - 从 DefaultTableModel 中删除后使用该行的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25529869/
我有一个 jTable,显示一个简单的两列 SQL 表的数据并允许用户维护该列表。这是我的第一个java程序。使其正常工作,以便用户可以编辑数据列表并按“保存”进行更新。我从这行代码获取 jTable
由于某种奇怪的原因,每次我在任何单元格中编辑数据并确认它时一旦我进入下一个,它就会从之前编辑的单元格复制数据 有什么想法吗? public class CheckoutTableModel exten
我有3个类(class) 首先从数据库获取数据 第二个为共同作品 其他用于展示表。 public class TableContent { private final Vector headers;
我的 DefaultTableModel 有问题,它不会向我显示表中的列,有一部分代码: JTable table = new JTable() { public boolean is
我有这个测试文件 text_file我的 TableView 是 enter image description here我想将每一行与每一列相匹配(第一行-第一列,第二行-第二列,等等。)错误在哪里
如何在 DefaultTableModel dtm = new DefaultTableModel(); 上添加标题和数据而不放置 new DefaultTableModel(在此内部)?我尝试使用
我的 Java GUI 中显示了一个表,用户可以通过单击“添加”按钮向其中添加行。添加到表格的行中的单元格默认都是可编辑的,用户可以根据需要选择每一行/单元格。 我现在想要添加从表中删除行的功能,但我
我有数据关系 Person-Attends-Course Person ------- id: integer primary key name: string prename: string age
我正在制作一个 GUI 简单的日历程序。我使用 DefaultTableModel 和 DefaultTableCellRenderer 显示日历的月 View 。我的日历设置为突出显示今天的日期。我
新数据输入数据库后,我的 JTable 没有刷新。我需要终止并再次执行才能看到结果。我包括了 DefaultTableModel 和 fireTableDataChanged。我还错过了什么?谢谢!
http://codepaste.net/ujhdq2 private Connection Econn; private DefaultTableModel examTable =
我使用 SwingWorker 根据数据库中的更改更改 DefaultTableModel。我的问题是:在 doInBackground() 中向 DefaultTableModel 添加 ListS
更新了问题,具体问题是数据没有显示,因为没有列: run: [java] Aug 04, 2014 8:17:00 PM net.bounceme.dur.client.gui.Applic
我一直在尝试将一些数据从 Editable JComboBox 发送到 JXTable。它的代码如下: private void selectTestActionPerformed(java.awt.
我有一个用 Object[][] 数组填充的 DefaultTableModel。 现在我想添加一个带有复选框的列并相应地执行操作。 当我将复选框添加到 Object[][] 数组并查看它时,我会显示
这个类与我的数据库通信检索数据并将它们投影到 JTable。我使用了 DefaultTableModel 但列名不会出现。我在另一个类中实例化这个类,我通过 检索包含数据的表获取表格()。 packa
我正在使用 Java Swingx 框架。我的 DefaultTableModel 对象中有 4 列。我只想显示其中 3 列。但是,我需要全部四个来进行计算。 实际数据模型 S.No. |身份证 |
我在 NetBeans 中使用 DefaultTableModel 来显示 MySQL 数据库中的记录。我的数据能够显示,但我想要的是在表格末尾显示一个复选框列。 我知道它需要被覆盖,但我不知道如何以
List myProducts = getMyProducts();//create an arraylist; Vector dataVector = new Vector(myProducts);
是的,我知道,这听起来很愚蠢。但在此之前,让我先说明一下我的问题。 我有一个带有大量 JTable 的 GUI。我有各种 DefaultTableModel,每个 JTable 一个。所以,1:1。对
我是一名优秀的程序员,十分优秀!