Java &引用;突出显示“;JTable中的特定行

Java &引用;突出显示“;JTable中的特定行,java,swing,jtable,highlight,jtabbedpane,Java,Swing,Jtable,Highlight,Jtabbedpane,每当单元格的内容和用户的输入匹配时,我想突出显示JTable中的特定行。以下代码是迄今为止我使用的代码: JTable table = new JTable(model) { public Component prepareRenderer( TableCellRenderer renderer, int row, int column) { Component c = super.prepareRenderer(rende

每当单元格的内容和用户的输入匹配时,我想突出显示JTable中的特定行。以下代码是迄今为止我使用的代码:

JTable table = new JTable(model) {
    public Component prepareRenderer(
            TableCellRenderer renderer, int row,
            int column) {
        Component c = super.prepareRenderer(renderer,
                row, column);
        if (!isRowSelected(row) ) {
            c.setBackground((hashMapcontainer
                    .containsKey(row)) ? Color.GREEN
                    : getBackground());
        }
        return c;
    }
    @Override
    public boolean isCellEditable(int row, int column) {
        return false;
    }
};
注意:
hashMapcontainer
是源文件中全局范围内的
hashmap

现在这在某种程度上起作用了,但是,我将这个
JTable
添加到
JTabbedPane
中,它位于
JFrame
中。JTables是在程序的整个运行时动态创建的。但是,
prepareRenderer
方法会突出显示所有创建的JTable中的所有特定单元格

我如何在所有jtable中保留单元格以保留它们自己特定的高亮显示单元格,而不是在每个jtable中都有相同的高亮显示单元格

提前谢谢

渲染器是“橡皮图章”。这基本上意味着它们将以前的设置带到下一个单元格

您需要做的是提供一个“默认”行为

虽然我个人认为在这种情况下,
prepareRenderer
可能是一个公平的解决方案,但您确实应该探索提供基线渲染器的可能性。这需要做大量的工作,但其优点是可移植(如果更改表实现)以及允许其他 人们有机会定义给定单元格的突出显示规则,而您基本上已经忽略了这些规则,IMHO


我还建议大家看看它内置的

一般来说,重写基本Swing类上的方法是个坏主意。建议的方法是创建一个实现
TableCellRenderer
Jcomponent
,并使用
setDefaultRenderer()
将其应用于表。请注意,默认情况下,JTable为对象、数字和布尔类型提供了其中的3种。通常,渲染器的外观如下所示:

public class MyRenderer extends JLable, implements TableCellRenderer{
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, 
         boolean isSelected, boolean hasFocus, int row, int column) {
    // Set up default state here 
    c.setBackground(Color.white);
    c.setForeground(Color.black);
    // ...
    if (!isRowSelected(row) ) {
        c.setBackground((hashMapcontainer
                .containsKey(row)) ? Color.GREEN
                : getBackground());
    }
    return c;
}
JTable t = new JTable();
// other typical table setup, t.setModel(...); etc
t.setDefaultRenderer(String.class, myRenderer);
t.putClientProperty("MySelectionProperty", new MyObject());
t.putClientProperty("MyHashContainer", new MyHashContainer());
这为您提供了一个可重用的组件,而不需要在您创建它的每个地方扩展JTable。对于所有表中选择的相同单元格,这是因为
isRowSelected
hashMapContainer
访问全局状态而不是每个实例状态。所有
JComponent
s都具有
getClientProperty
putClientProperty
。这些允许您将自己的状态对象附加到
JTable
。然后您的
isRowSelected
变为
isRowSelected(表,行)
,它只调用:

MyObject myObj = (MyObject)table.getClientProperty("MySelectionProperty");
myObj.isRowSelected(row);
与wise类似,也可以从表中检索
hashMapContainer

MyHashContainer myHash = (MyHash)table.getClientProperty("MyHashContainer");
更新:

对于动态生成的表,这几乎是相同的。表创建将如下所示:

public class MyRenderer extends JLable, implements TableCellRenderer{
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, 
         boolean isSelected, boolean hasFocus, int row, int column) {
    // Set up default state here 
    c.setBackground(Color.white);
    c.setForeground(Color.black);
    // ...
    if (!isRowSelected(row) ) {
        c.setBackground((hashMapcontainer
                .containsKey(row)) ? Color.GREEN
                : getBackground());
    }
    return c;
}
JTable t = new JTable();
// other typical table setup, t.setModel(...); etc
t.setDefaultRenderer(String.class, myRenderer);
t.putClientProperty("MySelectionProperty", new MyObject());
t.putClientProperty("MyHashContainer", new MyHashContainer());
值得注意的是,只要渲染器不携带任何状态,就不需要为每个表创建实例。我通常会创建一个,并将其用于所有表

下面是对上面的渲染器的更新,它不使用全局状态,而是查看表中的属性:

public class MyRenderer extends JLable, implements TableCellRenderer{
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, 
        boolean isSelected, boolean hasFocus, int row, int column) {

        // Pull hashMapContainer from the per-table client properties
        MyHashContainer hashMapcontainer = (MyHashContainer)table.getClientProperty("MyHashContainer");

        // Set defaults as above            

        if (!isRowSelected(table, row) ) {
            // Same as above
        }
        return c;
    }
    // Private method to check for row selection
    private boolean isRowSelected(JTable t, int row) {
        int[] selectedRows = table.getSelectedRows();
        for (int i = 0; i < selectedRows.length; i++) {
            if (selectedRows[i] == row) {
                return true;
            }
         }
         return false;
    }
}
公共类MyRenderer扩展了JLable,实现了TableCellRenderer{
@凌驾
公共组件GetTableCellRenderComponent(JTable表、对象值、,
布尔值(已选择,布尔值为焦点,整数行,整数列){
//从每个表的客户端属性中提取hashMapContainer
MyHashContainer hashMapcontainer=(MyHashContainer)table.getClientProperty(“MyHashContainer”);
//如上所述设置默认值
如果(!isRowSelected(表,行)){
//同上
}
返回c;
}
//检查行选择的私有方法
私有布尔值isRowSelected(JTable t,int行){
int[]selectedRows=table.getSelectedRows();
for(int i=0;i
如果我希望继续使用此代码,您提供的代码片段是否会在更改JTabbedPane的新JTables时保留先前JTables的突出显示行?好吧,鉴于每个表都是它自己的实例&您只会更改回“默认值”背景当一行未被选中时,我会说这是一个很好的机会。我认为您可能遇到的另一个问题是确定该行是否真正属于给定的表。基本上,根据我所能确定的,全局映射表示,在所有表中,高亮显示相同的行。这就是你想要实现的功能吗?是的,这就是我现在面临的问题。它高亮显示最后一个JTable高亮显示行的相同行。我只希望最后一个表进行更改,而之前的JTables保持不变。我会为每个表分离您的选择模型,以便它们有自己的列表RW,应该突出显示,或者(&我不喜欢这个想法),在您想要突出显示特定行的表的选择模型中放置一个引用,例如臭名昭著的DTCR颜色内存:如果我动态添加JTables和rows呢?