难以理解如何一起使用表模型和可观察量
我有一些相当复杂的数据,目前驻留在哈希表中,这些数据指向也包含哈希表的其他类,因为我试图保留的数据中存在一对多关系。
在世界的另一边,我有一个工作得很好的表,只是它与我的数据模型没有任何连接。它有自己的表格模型。我以非常简单的方式创建它 -
Object[][] tableData = new Object[4][ tableHeaders.length ];
modelTablet = new TabletTableModel(tableData, tableHeaders );
我的平板电脑数据模型非常简单,
class TabletTableModel extends DefaultTableModel {
public TabletTableModel(Object rowData[][], Object columnNames[]) {
super(rowData, columnNames);
}
@Override
public Class getColumnClass(int col) {
if (col == 0) {
return String.class;
} else {
return Double.class;
}
}
@Override
public boolean isCellEditable(int row, int col)
{
if (col == 0 || col == activeColumn)
return true;
else
return false;
}
}
这适合我,因为我还必须执行添加和删除行之类的操作,使用这个简单的数据模型,大部分工作都为我完成了。
class AddRowActionListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
DefaultTableModel model = (DefaultTableModel)tableTablet.getModel();
model.addRow(new Object[3]);
System.out.println(Arrays.deepToString(tableData));
}
}
我还实现了一个鼠标侦听器和一个单元格渲染器,这样当我单击列标题时,它就会变为活动状态,并且相邻列中的单元格会以另一种颜色重新绘制,以表明它们不再可编辑。
到目前为止一切顺利,但对于我的界面,我有第二个表总结了第一个表的结果。它只有三行,没有标题。我想我可能已经做了比我制作它时需要的更多的工作。
modelSummary = new SummaryTableModel(1, tableHeaders.length);
tableSummary = new JTable(modelSummary);
class SummaryTableModel extends DefaultTableModel {
public SummaryTableModel(int rows, int columns) {
super(rows, columns);
}
@Override
public Class getColumnClass(int col) {
if (col == 0) {
return String.class;
} else {
return Double.class;
}
@Override
public boolean isCellEditable(int row, int col)
{
if (col == 1 && activeColumn == 2)
return true;
else
return false;
}
}
因此,这给了我一组很好的表格,它们像预期的那样重新着色,它们将数据限制为有效值并正确格式化(使用我没有列出的渲染器)。
但这是应该发生的事情 - 用户在表 1 的第 1 列中输入一个值,然后我需要对第 1 列中的所有值进行求和,得出表 2 的第 1 列中的该值,然后重新计算表 1 的第 2 列基于此新值。
相反,如果第 2 列是活动列,并且用户更改了表 1 第 2 列中的值,那么我需要获取表 2 中第 1 列的值,并使用它重新计算表 1 中第 1 列的所有值,还对第 2 列的值求和并将它们放入表 2 的第 2 列中。需要注意的是,用户无法输入新值,使得第 2 列中的数字总和超过 100。
表 2 还可以进行编辑,这需要计算表 1 中的所有值。
所以...对我来说,似乎我应该有一个可观察的值,并且我应该将我的表注册为观察者和可观察的控制器。所以我可以编写一个可观察的,但我仍然有两个表数据模型。我读了很多书,但我发现的所有示例都显示在可观察中,与一些简单的东西一起使用,例如文本字段或表模型,但不使用 Observable 类。另一个问题是,我不确定如何做大多数很酷的事情(例如添加行或检查类型),默认模型默认情况下很乐意为我做这些事情。
在我为我的项目添加全新的复杂性之前,有人能给我一些指示吗?将几乎没有行或列概念的数据模型与表数据模型以某种方式混合在一起是否很容易,而不需要重新编写所有默认的表模型操作?目前,整个过程对我来说似乎难以置信的复杂。我迫切需要一些关于它如何工作的清晰解释。
I have some fairly complicated data and at the moment resides in hash tables that point to other classes that also contain hash tables because there are one-many relationships within the data I am trying to preserve.
On the other side of the world, I have a table that works quite nicely, with the exception that it does not have any connection to my data model. It has it's own table model. I create it in a very simple manner-
Object[][] tableData = new Object[4][ tableHeaders.length ];
modelTablet = new TabletTableModel(tableData, tableHeaders );
my tablet data model is very simple,
class TabletTableModel extends DefaultTableModel {
public TabletTableModel(Object rowData[][], Object columnNames[]) {
super(rowData, columnNames);
}
@Override
public Class getColumnClass(int col) {
if (col == 0) {
return String.class;
} else {
return Double.class;
}
}
@Override
public boolean isCellEditable(int row, int col)
{
if (col == 0 || col == activeColumn)
return true;
else
return false;
}
}
which suites me, since I also have to do things like add and remove rows, which with this simple data model, most of the work is done for me.
class AddRowActionListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
DefaultTableModel model = (DefaultTableModel)tableTablet.getModel();
model.addRow(new Object[3]);
System.out.println(Arrays.deepToString(tableData));
}
}
I've also implemented a mouse listener and a cell renderer so that when I click on the header of a column it becomes active and the cells in the adjoining column are repainted in another color to indicate they are no longer editable.
So far so good, but for my interface, I have a second table that summarizes the results of the first table. It's just three rows, no header. I think I may have done more work than I needed to when I made it.
modelSummary = new SummaryTableModel(1, tableHeaders.length);
tableSummary = new JTable(modelSummary);
class SummaryTableModel extends DefaultTableModel {
public SummaryTableModel(int rows, int columns) {
super(rows, columns);
}
@Override
public Class getColumnClass(int col) {
if (col == 0) {
return String.class;
} else {
return Double.class;
}
@Override
public boolean isCellEditable(int row, int col)
{
if (col == 1 && activeColumn == 2)
return true;
else
return false;
}
}
So that gives me a nice set of tables, they recolor like they are supposed to, they limit data to valid values and format it properly (with my renderers I did not list).
But here is what is supposed to happen- the user enters a value in column 1 of table 1, I then need to sum over all the values in column 1, out that value in column 1 of table 2 and then recalculate all the values in column 2 of table 1 based on this new value.
Conversely, if column 2 is the active column and the user changes a value in column 2 of table 1, then I need to get the value of column 1 in table 2 and use it to recalculate all the values for column 1 in table 1 and also sum the values of column 2 and place them in column 2 of table 2. With a caveat that the user can't enter a new value such that the sum of the numbers in column 2 exceeds 100.
Table 2 can also be edited, which would require calculating all the values in table 1.
So... to me that seems like I should have an observable and I should register my tables as both observers and as controllers for the observable. So I can write an observable, but I also still have my two table data models. I have been reading a lot, but all the examples I have found show in an observable used with something simple, like a text field or table models, but not using the Observable class. The other problem is that I am not sure how to do most of the cool things (like adding rows or checking types) that the default model happily does for me by default.
Before I add a whole new dimension of complexity to my project- could someone give me some pointers? Is it easy to mix data models that pretty much have no conception of rows or columns with table data models in some way that doesn't require writing all the default table model operations over again? The whole process seems unbelievably complex to me at the moment. I desparatetly need some clear explanation of how this should work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
表模型已经是可观察的:您可以向其中添加一个 TableModelListener,这样每当表模型发生更改时就会被调用。因此,第二个模型可以是第一个模型的侦听器,反之亦然。
我通常不使用 DefaultTableModel,因为它要求我将所有域对象转换为数组。我通常只编写一个 AbstractTableModel 子类来包装域对象列表。获取单元格的值通常包括获取列表中给定行(索引)处的对象模型,然后根据列调用对象上适当的 getter。
设置值包括调用对象上适当的设置器,并触发事件。
请参阅 http://docs.oracle.com/javase/tutorial/ uiswing/components/table.html#data 有关表格模型的教程。
Table models are already observable: you may add a TableModelListener to them and thus be called whenever a change occurs in the table model. So, the second model could be a listener for the first one, and vice-versa.
I usually don't use a DefaultTableModel, because it requires me to transform all my domain objects into arrays. I usually just write an AbstractTableModel subclass that wraps a list of domain objects. Getting the value of a cell generally consists in getting the object model at the given row (index) in the list, and then call the appropriate getter on the object, depending on the column.
Setting a value consists in calling the appropriate setter on the object, and firing an event.
See http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data for a tutorial on table models.