Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/45.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JTable根据模型而不是行保持颜色_Java_Swing_Jtable - Fatal编程技术网

Java JTable根据模型而不是行保持颜色

Java JTable根据模型而不是行保持颜色,java,swing,jtable,Java,Swing,Jtable,我左右为难。我正在编写一个程序,该程序将查看应用程序中的日志,并根据日志级别(例如,信息、调试、错误等)以特定颜色突出显示行。我还为用户提供了隐藏日志级别的功能。因此,如果单击“show info”,那么所有属于“info”的日志条目都将被隐藏。问题在于,当条目被隐藏时,它们高亮显示的颜色会被下推到它们下面的行 我正在寻找一种方法,当对象被隐藏时,颜色与条目保持一致,而不在下一个单元格中渲染颜色 以下是我迄今为止所做的工作: 我初始化渲染器并将其设置为默认值: tableRenderer = n

我左右为难。我正在编写一个程序,该程序将查看应用程序中的日志,并根据日志级别(例如,信息、调试、错误等)以特定颜色突出显示行。我还为用户提供了隐藏日志级别的功能。因此,如果单击“show info”,那么所有属于“info”的日志条目都将被隐藏。问题在于,当条目被隐藏时,它们高亮显示的颜色会被下推到它们下面的行

我正在寻找一种方法,当对象被隐藏时,颜色与条目保持一致,而不在下一个单元格中渲染颜色

以下是我迄今为止所做的工作:

我初始化渲染器并将其设置为默认值:

tableRenderer = new ModelTableRenderer();
table.setDefaultRenderer(Object.class, tableRenderer);
然后我创建我的分类器:

sorter = new TableRowSorter<DefaultTableModel>(model);
table.setRowSorter(sorter);
ModelTableRenderer类

这个类是我用来渲染行颜色的。它查看当前行并获取存在
LogLevel
的列值,具体取决于日志级别。当行未隐藏时,此操作可以正常工作

public class ModelTableRenderer extends DefaultTableCellRenderer {

  private static final long serialVersionUID = 425091150909034479L;

  public ModelTableRenderer() { }


  @Override
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

    if (!c.isVisible()) return c;

    Color color = Color.WHITE;

    LogLevel level = (LogLevel) table.getModel().getValueAt(row, LogModel.ERROR_COLUMN);
    switch (level) {
      case DEBUG:
        color = Color.GREEN;
        break;
      case ERROR:
        color = Color.ORANGE;
        break;
      case FATAL:
        color = Color.RED;
        break;
      case INFO:
        color = Color.WHITE;
        break;
      case TRACE:
        color = Color.GRAY;
        break;
      case WARN:
        color = Color.YELLOW;
        break;
      default:
        break;
    }

    if ((Boolean)table.getModel().getValueAt(row, LogModel.SUPPRESS_COLUMN)) {
      color = Color.BLACK;
    }

    c.setBackground(color);
    c.setForeground(Color.BLACK);
    table.repaint();
    return c;
  }
}
这是没有过滤器的结果。所有行都正确高亮显示

但当我点击关闭“显示跟踪”时,我们现在可以看到第一行高亮显示为灰色,而它仍然应该为绿色


这两个组件(突出显示和隐藏)都按预期独立工作,但将它们耦合在一起一直是一个挑战。任何帮助都会很好。

JTables的老问题。。。视图索引不是模型索引。不要使用视图索引在模型中查找,反之亦然

抬头看,然后


渲染器中接收的索引是视图索引。您正在使用收到的视图索引在模型中查找。在模型中查找之前,首先使用适当的“转换”方法转换为模型索引。

JTables的老问题。。。视图索引不是模型索引。不要使用视图索引在模型中查找,反之亦然

抬头看,然后


渲染器中接收的索引是视图索引。您正在使用收到的视图索引在模型中查找。在查找模型之前,首先使用适当的“转换”方法转换为模型索引。

由于TT的建议,我能够解决问题。我将渲染器更改为:

public class ModelTableRenderer extends DefaultTableCellRenderer {

  private static final long serialVersionUID = 425091150909034479L;

  public ModelTableRenderer() { }


  @Override
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

    int modelRow = table.convertRowIndexToModel(row);
    int modelCol = table.convertRowIndexToModel(column);

    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, modelRow, modelCol);

    Color color = Color.WHITE;

    LogLevel level = (LogLevel) table.getModel().getValueAt(modelRow, LogModel.ERROR_COLUMN);
    switch (level) {
      case DEBUG:
        color = Color.GREEN;
        break;
      case ERROR:
        color = Color.ORANGE;
        break;
      case FATAL:
        color = Color.RED;
        break;
      case INFO:
        color = Color.WHITE;
        break;
      case TRACE:
        color = Color.GRAY;
        break;
      case WARN:
        color = Color.YELLOW;
        break;
      default:
        break;
    }

    if ((Boolean)table.getModel().getValueAt(modelRow, LogModel.SUPPRESS_COLUMN)) {
      color = Color.BLACK;
    }

    c.setBackground(color);
    c.setForeground(Color.BLACK);
    return c;
  }
}
我还添加了一个
tableModelRenderer
,以便在用户单击复选框时呈现抑制效果。因为这是唯一更改的值,所以我们可以在该值上调用repaint

model.addTableModelListener(new TableModelListener() {

  @Override
  public void tableChanged(TableModelEvent e) {
    table.repaint();
  }
});

多亏了TT的建议,我才解决了这个问题。我将渲染器更改为:

public class ModelTableRenderer extends DefaultTableCellRenderer {

  private static final long serialVersionUID = 425091150909034479L;

  public ModelTableRenderer() { }


  @Override
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

    int modelRow = table.convertRowIndexToModel(row);
    int modelCol = table.convertRowIndexToModel(column);

    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, modelRow, modelCol);

    Color color = Color.WHITE;

    LogLevel level = (LogLevel) table.getModel().getValueAt(modelRow, LogModel.ERROR_COLUMN);
    switch (level) {
      case DEBUG:
        color = Color.GREEN;
        break;
      case ERROR:
        color = Color.ORANGE;
        break;
      case FATAL:
        color = Color.RED;
        break;
      case INFO:
        color = Color.WHITE;
        break;
      case TRACE:
        color = Color.GRAY;
        break;
      case WARN:
        color = Color.YELLOW;
        break;
      default:
        break;
    }

    if ((Boolean)table.getModel().getValueAt(modelRow, LogModel.SUPPRESS_COLUMN)) {
      color = Color.BLACK;
    }

    c.setBackground(color);
    c.setForeground(Color.BLACK);
    return c;
  }
}
我还添加了一个
tableModelRenderer
,以便在用户单击复选框时呈现抑制效果。因为这是唯一更改的值,所以我们可以在该值上调用repaint

model.addTableModelListener(new TableModelListener() {

  @Override
  public void tableChanged(TableModelEvent e) {
    table.repaint();
  }
});

1.不要在渲染器中调用repaint()。2.不知道为什么需要“isVisible()”检查。该表将仅呈现可见的行。3.你可能想退房。它允许您轻松地为整行着色,即使每列的数据类型不同。重新绘制是我能够在单击某行时使其变黑的唯一方法。这是错误的。想想看。你调用repaint(),它调用渲染器,它调用repaint(),它调用渲染器……我意识到了这一点,并试图想出一个更好的解决方案。有什么建议吗?当您单击按钮时,应该在表上调用repaint()。1。不要在渲染器中调用repaint()。2.不知道为什么需要“isVisible()”检查。该表将仅呈现可见的行。3.你可能想退房。它允许您轻松地为整行着色,即使每列的数据类型不同。重新绘制是我能够在单击某行时使其变黑的唯一方法。这是错误的。想想看。你调用repaint(),它调用渲染器,它调用repaint(),它调用渲染器……我意识到了这一点,并试图想出一个更好的解决方案。有什么建议吗?当您单击按钮时,您应该在表上调用repaint()。我还添加了一个tableModelRenderer来渲染-为什么?我理解你的逻辑,你点击一个按钮来过滤表格。重置RowFilter应该足以导致表自身重新绘制()。如果没有,那么您应该能够在复选框的ActionListener中调用repaint()。如果这不起作用,那么我建议您做一些非常奇怪的事情。这是针对表本身中的复选框。不是过滤器。它是用于抑制列以屏蔽行的。我还添加了一个tableModelRenderer来渲染-为什么?我理解你的逻辑,你点击一个按钮来过滤表格。重置RowFilter应该足以导致表自身重新绘制()。如果没有,那么您应该能够在复选框的ActionListener中调用repaint()。如果这不起作用,那么我建议您做一些非常奇怪的事情。这是针对表本身中的复选框。不是过滤器。它用于抑制列以遮住行。