Изменить цвет строк в Java JTable - PullRequest
0 голосов
/ 07 марта 2019

Я пытаюсь изменить цвет строк в Java JTable, но у меня возникли некоторые проблемы. Это сценарий: у меня есть таблица с некоторыми данными для обработки, и я хотел бы, чтобы в конце обработки (запущенной с помощью кнопки) таблица обновлялась путем окрашивания линий в зеленый, желтый или красный в зависимости от результата операций. Каждый обработанный объект имеет переменную «исход», которая устанавливается после обработки. Таблица создается графическим редактором Netbeans (поэтому невозможно изменить автоматически сгенерированный код). Я использовал эту TableModel:

public class QuotationsTableModel extends AbstractTableModel {

    private List<Quotation> quotationsList;

    public QuotationsTableModel(List<Quotation> quotationsList) {
        this.quotationsList= quotationsList;
    }

    @Override
    public int getRowCount() {
        if (quotationsList== null) {
            return 0;
        }
        return this.quotationsList.size();
    }

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

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        if (quotationsList== null) {
            return null;
        }
        Quotation quotation = quotationsList.get(rowIndex);
        if (columnIndex == 0) {
            return quotation.getQuotationNumber();
        }
        if (columnIndex == 1) {
            return quotation.getBillingType();
        }
        if (columnIndex == 2) {
            return quotation.getAdvance();
        }
        if (columnIndex == 3) {
            return quotation.getOutcome();
        }
        return null;
    }

    @Override
    public String getColumnName(int column) {
        if (column == 0) {
            return "Number";
        } else if (column == 1) {
            return "Billing type";
        } else if (column == 2) {
            return "Advance";
        } else if (column == 3) {
            return "Outcome";
        }
        return null;
    }

    public void updateTable() {
        this.fireTableDataChanged();
    }

и я попытался достичь цели, создав класс:

public class CustomTableRenderer extends DefaultTableCellRenderer {

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

        Component original = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        Color background = table.getBackground();
        //Color grid = Color.YELLOW;

        Color fg = null;
        Color bg = null;


        if (isSelected) {
            super.setForeground(fg == null ? table.getSelectionForeground()
                                           : fg);
            super.setBackground(bg == null ? table.getSelectionBackground()
                                           : bg);
        } else {
            if (column == 3) {
                String outcome = String.valueOf(value);
                if (outcome .equalsIgnoreCase("COMPLETED")){
                  background = Color.GREEN;
                } else if (outcome .equalsIgnoreCase("PARTIAL")) {
                    background = Color.YELLOW;
                } else if (outcome .equalsIgnoreCase("ERROR")) {
                    background = Color.RED;
                }
            }
        }
    original.setBackground(background);

    return original;
    }

и затем звоните:

QuotationsTableModel quotationsTableModel= new QuotationsTableModel(quotationsList);
this.quotationsTable.setModel(quotationsTableModel);
this.quotationsTable.setDefaultRenderer(Object.class, new CustomTableRenderer());

но результат окрашивается только при выборе строки и, более того, после выбора линии все значения исчезают, кроме результата. Можете ли вы помочь мне, пожалуйста?

Я нашел рабочее решение, может быть оно пригодится тем, кто придет:

import java.awt.Color;
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class CustomTableCellRenderer extends DefaultTableCellRenderer {


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


        Component original = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        Color background = table.getBackground();

        if (isSelected) {            
            original.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.selectionBackground"));
            original.setForeground(javax.swing.UIManager.getDefaults().getColor("TextField.selectionForeground"));
            table.setRowSelectionInterval(row, row);            
        } else {
            original.setBackground(javax.swing.UIManager.getDefaults().getColor("TextField.highlight"));
            original.setForeground(Color.BLACK);        
            if (column == 3) {
                String outcome = String.valueOf(value);
                if (outcome.equalsIgnoreCase("COMPLETED")){
                  background = Color.GREEN;
                } else if (outcome.equalsIgnoreCase("PARTIAL")) {
                    background = Color.YELLOW;
                } else if (outcome.equalsIgnoreCase("ERROR")) {
                    background = Color.RED;
                }
                original.setBackground(background);
            }
        }

    return original;
    }
}

Спасибо.

1 Ответ

0 голосов
/ 08 марта 2019

Я создал образец программы ниже, используя ваши классы QuotationsTableModel и CustomTableRenderer.Единственная проблема, с которой я столкнулся, заключается в методе CustomTableRenderer.getTableCellRendererComponent().

Вы меняли цвет столбца «Результат», только когда строка не выбрана.Из-за этого раскраска не работала при выделении строки.Чтобы исправить эту проблему, я удалил if (isSelected) { часть кода.Запустите приведенный ниже пример и посмотрите.

(Когда вы будете публиковать вопросы в будущем, опубликуйте минимальную исполняемую программу, как, например, в примере ниже. Тогда другим будет проще запустить сценарий и увидеть проблему.)

import javax.swing.*;
import javax.swing.table.*;
import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import java.util.List;

public class ColorTable {

  public static void main(String[] args) {
    List<Quotation> quotationsList = new ArrayList<>();
    quotationsList.add(new Quotation(111, "AA", 2500, "COMPLETED"));
    quotationsList.add(new Quotation(222, "BB", 4000, "PARTIAL"));
    quotationsList.add(new Quotation(333, "CC", 5000, "COMPLETED"));
    quotationsList.add(new Quotation(444, "DD", 1500, "SOME_OTHER_OUTCOME"));
    quotationsList.add(new Quotation(555, "EE", 3500, "ERROR"));
    QuotationsTableModel quotationsTableModel= new QuotationsTableModel(quotationsList);

    JTable quotationsTable = new JTable();
    quotationsTable.setModel(quotationsTableModel);
    quotationsTable.setDefaultRenderer(Object.class, new CustomTableRenderer());

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new JScrollPane(quotationsTable));
    frame.pack();
    frame.setVisible(true);
  }
}

class QuotationsTableModel extends AbstractTableModel {

  private List<Quotation> quotationsList;

  public QuotationsTableModel(List<Quotation> quotationsList) {
    this.quotationsList= quotationsList;
  }

  @Override
  public int getRowCount() {
    if (quotationsList== null) {
      return 0;
    }
    return this.quotationsList.size();
  }

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

  @Override
  public Object getValueAt(int rowIndex, int columnIndex) {
    if (quotationsList== null) {
      return null;
    }
    Quotation quotation = quotationsList.get(rowIndex);
    if (columnIndex == 0) {
      return quotation.getQuotationNumber();
    }
    if (columnIndex == 1) {
      return quotation.getBillingType();
    }
    if (columnIndex == 2) {
      return quotation.getAdvance();
    }
    if (columnIndex == 3) {
      return quotation.getOutcome();
    }
    return null;
  }

  @Override
  public String getColumnName(int column) {
    if (column == 0) {
      return "Number";
    } else if (column == 1) {
      return "Billing type";
    } else if (column == 2) {
      return "Advance";
    } else if (column == 3) {
      return "Outcome";
    }
    return null;
  }

  public void updateTable() {
    this.fireTableDataChanged();
  }
}

class CustomTableRenderer extends DefaultTableCellRenderer {

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

    Component original = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    Color background = table.getBackground();
    //Color grid = Color.YELLOW;

    if (column == 3) {
      String outcome = String.valueOf(value);
      if (outcome .equalsIgnoreCase("COMPLETED")){
        background = Color.GREEN;
      } else if (outcome .equalsIgnoreCase("PARTIAL")) {
        background = Color.YELLOW;
      } else if (outcome .equalsIgnoreCase("ERROR")) {
        background = Color.RED;
      }
    }
    original.setBackground(background);

    return original;
  }
}

class Quotation {
  private int quotationNumber;
  private String billingType;
  private int advance;
  private String outcome;

  Quotation(int quotationNumber, String billingType, int advance, String outcome) {
    this.quotationNumber = quotationNumber;
    this.billingType = billingType;
    this.advance = advance;
    this.outcome = outcome;
  }

  int getQuotationNumber() {
    return quotationNumber;
  }

  String getBillingType() {
    return billingType;
  }

  int getAdvance() {
    return advance;
  }

  String getOutcome() {
    return outcome;
  }
}

Выход:

enter image description here

...