2

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

我已经阅读了有关覆盖 prepareRenderer 或 getTableCellRendererComponent 的信息。然后,条件渲染逻辑位于 Overridden 方法中。

DefaultTableCellRenderer getTableCellRendererComponent 永远不会被调用 http://tips4java.wordpress.com/2010/01/24/table-row-rendering/ http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#renderer

但是从我所知道的和我所理解的(如果我错了,请纠正我),这两个选项都不允许您在这个被覆盖的方法中同时比较两个不同的 JTable。prepareRenderer 在扩展 JTable 的类中被覆盖,因此它在特定表上被实例化。然后,被覆盖的方法只会影响 Table 的特定实例。

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)

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

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

提前感谢您的阅读/回复

4

3 回答 3

4

我已经阅读了有关覆盖 prepareRenderer 或 getTableCellRendererComponent 的信息。然后,条件渲染逻辑位于 Overridden 方法中。但是从我所知道的和我所理解的(如果我错了,请纠正我),这两个选项都不允许您在这个被覆盖的方法中同时比较两个不同的 JTable。

你为什么这么说,你有什么数据来支持这个说法,因为它是错误的。

prepareRenderer 扩展了 JTable

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

所以它被覆盖的方法只能访问 JTable 的特定实例,并且 getTableCellRendererComponent 是通过特定 JTable 的 columnModel 中的特定列的 setCellRenderer 设置的。

方法可以访问程序员允许他们访问的任何内容。关键在于传递引用。

于 2012-09-19T23:25:12.593 回答
3

使用SwingX基础设施,就像

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

下面是一个简短的片段,它使用配置了列表中所选项目的 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);
于 2012-09-20T09:55:18.717 回答
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 ;)

}
于 2012-09-19T23:25:19.287 回答