gpt4 book ai didi

java - 在 fireTableDataChanged() 之后突出显示 JTable 中的更改

转载 作者:行者123 更新时间:2023-12-01 23:42:39 24 4
gpt4 key购买 nike

我使用的 JTable 的 TableModel 通过 fireTableDataChanged() 定期更新。这些更改通常非常小,例如添加或修改的单行,但我无法预测它会在哪里发生。

有没有办法知道在 fireTableDataChanged() 上添加或修改了哪些行?我想突出显示这些行,以便用户也知道。

最佳答案

首先,您必须设置适合 Swing 的上下文:TableModel 必须对自身有足够的了解/控制才能完全遵守其通知契约。也就是说,每当发生此类更改时,它都必须触发 row-/cellUpdated 或 rowsInserted。

那么在 JTable 中突出显示更改(在特定时间内)的基本方法是

  • 实现一个自定义渲染器来装饰某些存储中的单元格
  • 使用自定义渲染器配置表格
  • 聆听模型的变化
  • 将changeEvents(或具有相关属性的自定义对象)添加到渲染器知道的存储中
  • 使用计时器在一段时间后删除更改标记

SwingX通过提供Highlighters和HighlightPredicates来简化(对我有偏见:-)渲染部分:当后者决定应该打开它们时,前者会进行自定义视觉装饰。上述方法调整为

  • 为表格配置荧光笔以进行视觉装饰
  • 聆听模型的变化
  • 将更改的单元格添加到自定义HighlightPredicate并使用它配置荧光笔
  • 使用计时器在一段时间后删除更改标记

下面是一些代码,定时器/谓词的管理被分解到一个名为 ChangeDecorator 的类中:它保留一个用于装饰更新单元格的荧光笔和一个用于装饰插入行的荧光笔(注意:这是一个示例,显然必须扩展逻辑覆盖更新的行:) 它由 modelListener 提供更改并根据需要更新谓词。

JXTable table = new JXTable(model);
final ChangeDecorator controller = new ChangeDecorator();
table.addHighlighter(controller.getChangeHighlighter());
TableModelListener l = new TableModelListener() {

@Override
public void tableChanged(TableModelEvent e) {
if (TableUtilities.isUpdate(e)) {
Change change = new Change(e.getFirstRow(), e.getColumn());
controller.addChange(change);
} else if (TableUtilities.isInsert(e)) {
Change change = new Change(e.getFirstRow());
controller.addChange(change);
}
}
};
model.addTableModelListener(l);



/**
* Manages the Highlighters for inserted rows/updated cells.
*/
public static class ChangeDecorator {

private List<Change> changes;
private AbstractHighlighter update;
private AbstractHighlighter insert;
private Highlighter compound;

public ChangeDecorator() {
changes = new ArrayList<>();
}

public Highlighter getChangeHighlighter() {
if (compound == null) {
update = new ColorHighlighter(new ChangePredicate(changes, true),
Color.YELLOW, null);
insert = new ColorHighlighter(new ChangePredicate(changes, false),
Color.GREEN, null);
compound = new CompoundHighlighter(update, insert);
}
return compound;
}

public void addChange(Change change) {
startTimer(change, change.isCell ? update : insert);
}

private void startTimer(final Change change, final AbstractHighlighter hl) {
changes.add(change);
hl.setHighlightPredicate(new ChangePredicate(changes, change.isCell));
ActionListener l = new ActionListener() {
boolean done;
@Override
public void actionPerformed(ActionEvent e) {
if (!done) {
done = true;
return;
}
((Timer) e.getSource()).stop();
changes.remove(change);
hl.setHighlightPredicate(new ChangePredicate(changes, change.isCell));
}

};
Timer timer = new Timer(2000, l);
timer.setInitialDelay(100);
timer.start();
}
}

/**
* A predicate enables highlighting a cell if it
* contains a change for that cell.
*/
public static class ChangePredicate implements HighlightPredicate {

private List<Change> changes;
private boolean matchCell;
public ChangePredicate(List<Change> changes, boolean matchCell) {
this.changes = new ArrayList(changes);
this.matchCell = matchCell;
}

@Override
public boolean isHighlighted(Component renderer,
ComponentAdapter adapter) {
return changes.contains(createChange(adapter));
}

private Change createChange(ComponentAdapter adapter) {
int modelRow = adapter.convertRowIndexToModel(adapter.row);
if (matchCell) {
int modelColumn =
adapter.convertColumnIndexToModel(adapter.column);;
return new Change(modelRow, modelColumn);
}
return new Change(modelRow);
}

}

/**
* A crude class encapsulating a cell change.
*
*/
public static class Change {
int row;
int column;
boolean isCell;

public Change(int row) {
this(row, -1, false);
}

public Change(int row, int col) {
this(row, col, true);
}

private Change(int row, int col, boolean update) {
this.row = row;
this.column = col;
this.isCell = update;
}

@Override
public boolean equals(Object obj) {
if (!(obj instanceof Change)) return false;
Change other = (Change) obj;
return row == other.row && column == other.column && isCell == other.isCell;
}

}

关于java - 在 fireTableDataChanged() 之后突出显示 JTable 中的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17672069/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com