在选择时突出显示细线十字图案中的相关单元格

Highlight related cells in hairline cross pattern on selection

我想为 JXTable 添加细线交叉高亮。但是我可以突出显示当前行或当前列;从来没有。

我目前有的是红色部分,黄色部分是我要添加的。

低于 SSCCE1.

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;

import org.jdesktop.swingx.JXTable;

public class Application
{

  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      @Override
      public void run()
      {
        JFrame frame = new JFrame();
        JXTable table = new JXTable(new CustomTableModel());

        boolean highlightRow = false;
        table.setRowSelectionAllowed(highlightRow);
        table.setColumnSelectionAllowed(!highlightRow);

        table.setDefaultRenderer(Object.class, new CustomTableCellRenderer());

        frame.add(new JScrollPane(table));
        frame.setVisible(true);
        frame.pack();
      }
    });
  }

  public static class CustomTableCellRenderer extends DefaultTableCellRenderer
  {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
      Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
      if (row == table.getSelectedRow()) { component.setBackground(Color.YELLOW); }
      if (column == table.getSelectedColumn()) { component.setBackground(Color.RED); }
      return component;
    }
  }

  static class CustomTableModel extends AbstractTableModel
  {
    private final List<Object[]> data = new ArrayList<>();

    public CustomTableModel()
    {
      data.add(new Object[] {1, 2, 3, "A", "Collection", "of", "Random", "Strings", 9, 10});
      data.add(new Object[] {1, 2, 3, "A", "Collection", "of", "Random", "Strings", 9, 10});
      data.add(new Object[] {1, 2, 3, "A", "Collection", "of", "Random", "Strings", 9, 10});
      data.add(new Object[] {1, 2, 3, "A", "Collection", "of", "Random", "Strings", 9, 10});
    }

    @Override
    public int getRowCount() { return data.size(); }

    @Override
    public int getColumnCount() { return 10; }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) { return data.get(rowIndex)[columnIndex]; }
  }

}

更新

使用@camickr 提供的代码和建议可以得到:

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

import org.jdesktop.swingx.JXTable;

public class Application
{

  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      @Override
      public void run()
      {
        JFrame frame = new JFrame();

        DefaultTableModel model = new DefaultTableModel(5, 10);
        JXTable table = new JXTable(model)
        {
            @Override
            public Component prepareRenderer(
                TableCellRenderer renderer, int row, int column)
            {
                Component c = super.prepareRenderer(renderer, row, column);

                if (column == getSelectedColumn()) { c.setBackground(Color.RED); }
                else if (row == getSelectedRow()) { c.setBackground(Color.YELLOW); }
                else c.setBackground(getBackground());

                return c;
            }
        };

        frame.add(new JScrollPane(table));
        frame.setVisible(true);
        frame.pack();
      }
    });
  }

}

但不幸的是,我现在遇到了工件问题。类似于下图(取自仅红色版本)


我在 Windows 10.0.16299 Build 16299 上使用 Java 1.8.0_74。JXTable 来自

        <dependency>
            <groupId>org.swinglabs.swingx</groupId>
            <artifactId>swingx-all</artifactId>
            <version>1.6.5-1</version>
        </dependency>

它似乎在使用 JTable 时有效(尽管如果您希望该列具有优先级,则需要更改 if 语句的顺序)。因此,似乎 JXTable 做了一些导致问题的额外渲染。

所以这是一种基于 Table Row Rendering 的替代方法,它似乎适用于 JXTable:

JXTable table = new JXTable(new CustomTableModel())
{
    public Component prepareRenderer(
        TableCellRenderer renderer, int row, int column)
    {
        Component c = super.prepareRenderer(renderer, row, column);

        if (column == getSelectedColumn()) { c.setBackground(Color.RED); }
        else if (row == getSelectedRow()) { c.setBackground(Color.YELLOW); }
        else c.setBackground(getBackground());

        return c;
    }
};

以上代码替换自定义渲染器:

//table.setDefaultRenderer(Object.class, new CustomTableCellRenderer());

注意:在您的 "MCVE" 我的建议中,您删除了:

boolean highlightRow = false;
table.setRowSelectionAllowed(highlightRow);
table.setColumnSelectionAllowed(!highlightRow);

为什么?我只给了你以上2个改动。

这就是为什么您需要 post 一个合适的 "MCVE" 以便我们可以确保您正确实施了建议。