Выделите связанные ячейки в линии пересечения волос при выделении - PullRequest
0 голосов
/ 16 мая 2018

Я хочу добавить выделение линии роста волос к JXTable. Но я могу выделить текущую строку или текущий столбец; никогда оба.

В настоящее время у меня есть красная часть, желтая часть - это то, что я хочу добавить.

enter image description here

ниже SSCCE 1 .

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();
      }
    });
  }

}

Но, к сожалению, у меня сейчас проблемы с артефактами. Аналогично картинке ниже (взято из версии, которая окрашена только в красный цвет).

enter image description here


Я использую Java 1.8.0_74 в Windows 10.0.16299, сборка 16299. JXTable от

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

1 Ответ

0 голосов
/ 23 мая 2018

Кажется, это работает при использовании JTable (хотя порядок операторов if необходимо изменить, если вы хотите, чтобы столбец имел приоритет).Похоже, что JXTable выполняет дополнительный рендеринг, который вызывает проблему.

Итак, вот альтернативный подход, основанный на рендеринге табличных строк , который работает для 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 вышеуказанных изменения.

Вот почему вам нужно опубликовать правильный "MCVE", чтобы мы могли быть уверены, что вы правильно выполнили это предложение.

...