比较两个或更多JTable和'突出'差异

时间:2012-09-19 23:00:00

标签: java swing jtable comparator renderer

我正在构建一个swing应用程序,它左边是项目列表,右边是表格。右侧显示的表格数量取决于左侧选择的项目。我希望能够“突出显示”(setBackground)所有正在显示的表中相同的行。

我读过有关覆盖prepareRenderer或getTableCellRendererComponent的内容。然后条件呈现逻辑在Overridden方法中。

DefaultTableCellRenderer getTableCellRendererComponent never gets called http://tips4java.wordpress.com/2010/01/24/table-row-rendering/ http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#renderer

但是从我能说的和我理解的内容(如果我错了请纠正我)这两个选项都不允许你在这个被覆盖的方法中同时比较两个不同的JTable。 prepareRenderer在扩展JTable的类中被重写,因此它在特定的表上实例化。然后,重写的方法仅影响表的特定实例。

public class CustomRenderer extends JTable {
@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component c = super.prepareRenderer(renderer, row, column);
    //  add custom rendering here
    return c;
}};

...
CustomRenderer currTable = new CustomRenderer();

getTableCellRendererComponent是通过特定JTable的columnModel中特定列的setCellRenderer设置的。

public class CustomRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        if (isSelected) {
            l.setBackground(Color.gray);
        }
        else {
            l.setBackground(Color.white);
        }
    return l;
    }};

...
CustomRenderer cr = new CustomRenderer();
currTable.getcolumnModel().getColumn(1).setCellRenderer(cr);

那么我该如何做

之类的事情
if(tableOne.getValueAt(1, 1).equals(tableTwo.getValueAt(1, 1) 
//set Cell 1,1 background(Color.blue)
else
//set Cell 1,1 background(Color.red)

现在我有一个非常丑陋的黑客使用多个表格单元格选择和getTableCellRendererComponent方法,该方法测试isSelected布尔值并相应地更改背景。这已经足够了(因为我是唯一一个使用这个程序的人)但是必须有一种更好的方法能够根据不同表的条件或值同时比较和更改一个表的呈现。 / p>

或者我可以解决这个问题吗?

提前感谢您阅读/回复

3 个答案:

答案 0 :(得分:4)

  

我读过有关覆盖prepareRenderer或getTableCellRendererComponent的内容。然后条件呈现逻辑在Overridden方法中。但是从我能说的和我理解的东西(如果我错了请纠正我)这两个选项都不允许你在这个被覆盖的方法中同时比较两个不同的JTable。

为什么这么说以及你有什么数据支持这个陈述,因为它是错误的。

  

prepareRenderer扩展了JTable

方法不能扩展类,所以这没有意义。

  

所以它的重写方法只能访问JTable的特定实例,而getTableCellRendererComponent是通过特定JTable的columnModel中特定列的setCellRenderer设置的。

方法可以访问程序员可以访问的任何内容。关键在于传递参考文献。

答案 1 :(得分:3)

我可能会使用某种“突出显示模型”,它能够确定哪些表应该突出显示哪些行(以及如何突出显示)。

然后,您可以直接将其提供给单元格渲染器,也可以直接在单元格渲染器中从表格中提取它(但是,假设该表格的类型正确并打开了一整套蠕虫)。

所以基本上你最终会得到类似......

的东西
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    // Seed the component with the default values
    super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    // You may need to change the value of the component to reflect what
    // you want to display here

    // It should be noted, that this method will override the selection
    // highlighting, you may want to check isSelected and make
    // your own decisions over what needs to be done.
    HighlightModel model = getHighlightModel();
    // You should check for null
    Color color = model.getHighlightBackgroundFor(table, row);
    if (color != null) {
        setOpaque(true);
        setBackground(color);
    }

    return this; // Assuming you've used a component as a base renderer ;)

}

答案 2 :(得分:3)

使用SwingX基础设施,就像

一样简单
  • 实现一个HighlightPredicate,它决定是否应该突出显示一个单元格
  • 实例化荧光笔(f.i.通过设置背景颜色进行装饰的ColorHighlighter)并将其添加到两个表中
  • 实现/注册一些监听器,根据状态
  • 将谓词设置为荧光笔

下面是一个简短的代码段,它使用配置了列表中所选项目的EqualsHighlightPredicate来突出显示具有相同内容的所有单元格。享受!

final JXList list = new JXList(AncientSwingTeam.createNamedColorListModel());
JXTable table = new JXTable(new AncientSwingTeam());
final ColorHighlighter highlighter = new ColorHighlighter(
        HighlightPredicate.NEVER, Color.YELLOW, null);
list.addHighlighter(highlighter);
table.addHighlighter(highlighter);
ListSelectionListener l = new ListSelectionListener() {

    @Override
    public void valueChanged(ListSelectionEvent e) {
        if (e.getValueIsAdjusting()) return;
        highlighter.setHighlightPredicate(
                createPredicate(list.getSelectedValue()));
    }

    private HighlightPredicate createPredicate(Object selectedValue) {
        if (selectedValue == null) return HighlightPredicate.NEVER;
        return new HighlightPredicate.EqualsHighlightPredicate(selectedValue);
    }
};
list.getSelectionModel().addListSelectionListener(l);