JTable Cell Renderer - PullRequest
       15

JTable Cell Renderer

8 голосов
/ 11 июля 2011

Я следую некоторому коду, который я нашел, (Да, я понимаю, как это работает) Это отсюда: Кодовая ссылка

Что я пытаюсь сделать, это установить ячейки переднего планацвет, если для ячеек установлено значение «желтый»

Вот мой код:

public class Board extends JPanel{

private static final long serialVersionUID = 1L;

int boardHeight = 20;
int boardWidth = 10;

JTable table;

public Board() {
    table = new JTable(this.boardHeight, this.boardWidth);
    table.setDefaultRenderer(String.class, new BoardTableCellRenderer());
    table.setFocusable(false);
    table.setShowGrid(false);
    table.setRowMargin(0);
    table.setIntercellSpacing(new Dimension(0,0));
    table.setRowSelectionAllowed(false);
    table.setVisible(true);
    this.add(table);
    this.setPreferredSize(new Dimension(table.getPreferredSize().width, (table.getPreferredSize().height + 85)));
}

public void paint(Graphics g) {
    table.setRowHeight(20);
    for (int x = 0; x < this.table.getColumnCount(); ++x) {
        TableColumn col = this.table.getColumnModel().getColumn(x);
        col.setPreferredWidth(20);
    }
}
}

И средство визуализации ячеек

public class BoardTableCellRenderer extends DefaultTableCellRenderer {

private static final long serialVersionUID = 1L;

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

    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
    String s = table.getModel().getValueAt(row, col).toString();

    if (s.equalsIgnoreCase("yellow")) {
        c.setForeground(Color.YELLOW);
    }
    else {
        c.setForeground(Color.WHITE);
    }

    return c;
}
}

Проблема заключается в том,т, если я установлю любое значение ячейки в «желтый»

Заранее спасибо!

Ответы [ 3 ]

10 голосов
/ 11 июля 2011

Ваш рендерер вообще когда-либо использовался?Вы делаете его средством визуализации по умолчанию для ячеек, содержащих String, но не перегружены ли вы методом getColumnClass вашей модели, чтобы он знал, что некоторые ячейки содержат строки?

Итак, сначала я бы использовал операторы println, чтобы увидеть, вызывается ли даже средство визуализации, и если нет, то я переопределил бы метод моей модели, как отмечено выше.1007 *
Также, если ваши результаты будут странными.В части if вы меняете передний план, а в другом - фон - не имеет смысла.Вы, вероятно, должны делать дополнительные изменения состояния в блоках if и else, а не ортогональные изменения.

Редактировать 2
Например:

import java.awt.*;
import java.util.Random;

import javax.swing.*;
import javax.swing.table.*;

public class Board extends JPanel {

   private static final long serialVersionUID = 1L;

   int boardHeight = 20;
   int boardWidth = 10;

   JTable table;
   Random random = new Random();

   public Board() {
      setLayout(new BorderLayout()); // !!
      DefaultTableModel model = new DefaultTableModel(boardHeight, boardWidth) {
         @Override
         public Class<?> getColumnClass(int columnIndex) {
            return String.class;
         }
      };
      // !! table = new JTable(this.boardHeight, this.boardWidth);
      table = new JTable(model);
      for (int row = 0; row < model.getRowCount(); row++) {
         for (int col = 0; col < model.getColumnCount(); col++) {
            String s = random.nextBoolean() ? "red" : "yellow";
            model.setValueAt(s, row, col);
         }
      }
      table.setDefaultRenderer(String.class, new BoardTableCellRenderer());

      table.setFocusable(false);
      table.setShowGrid(false);
      table.setRowMargin(0);
      table.setIntercellSpacing(new Dimension(0, 0));
      table.setRowSelectionAllowed(false);
      table.setVisible(true);
      this.add(table);
      this.setPreferredSize(new Dimension(table.getPreferredSize().width,
               (table.getPreferredSize().height + 85)));
   }

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Board");
      frame.getContentPane().add(new Board());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

class BoardTableCellRenderer extends DefaultTableCellRenderer {

   private static final long serialVersionUID = 1L;

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

      Component c = super.getTableCellRendererComponent(table, value,
               isSelected, hasFocus, row, col);
      Object valueAt = table.getModel().getValueAt(row, col);
      String s = "";
      if (valueAt != null) {
         s = valueAt.toString();
      }

      if (s.equalsIgnoreCase("yellow")) {
         c.setForeground(Color.YELLOW);
         c.setBackground(Color.gray);
      } else {
         c.setForeground(Color.black);
         c.setBackground(Color.WHITE);
      }

      return c;
   }
}
4 голосов
/ 11 июля 2011

Добавить эту строку:

c.setOpaque(true);

Компонент, возвращаемый getTableCellRendererComponent, должен быть непрозрачным, чтобы видеть изменения цвета фона и переднего плана. Проблема здесь также другая: вы расширяете DefaultTableCellRenderer (то есть JComponent), но вы возвращаете компонент, у которого нет метода setOpaque. Я бы изменил ваш код следующим образом:

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

    String s = table.getModel().getValueAt(row, col).toString();
    this.setOpaque(true);
    if (s.equalsIgnoreCase("yellow")) {
        this.setForeground(Color.YELLOW);
    }
    else {
        this.setBackground(Color.WHITE);
    }

    return this;
}
1 голос
/ 13 октября 2013

Вот простое решение, используйте TabaleCellRendere в качестве внутреннего класса.

    myTable.setDefaultRenderer(Object.class, new TableCellRenderer()
    {
        JLabel comp = new JLabel();
        String val;

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
        {
            comp.setOpaque(true);
            comp.setForeground(Color.BLACK); // text color

            if (value != null)
            {
                val = value.toString();
                comp.setText(val);

                if (val.equalsIgnoreCase("red"))
                {
                    comp.setBackground(Color.RED);
                }
                else if (val.equalsIgnoreCase("yellow"))
                {
                    comp.setBackground(Color.YELLOW);
                }
                else if (val.equalsIgnoreCase("green"))
                {
                    comp.setBackground(Color.GREEN);
                }
                else
                {
                    comp.setBackground(Color.WHITE);
                }
            }
            return comp;
        }
    });
...