JTable: изменение фона ячейки при нажатии кнопки - PullRequest
2 голосов
/ 27 июня 2011

Я знаю, что изменение фона ячеек в jtable осуществляется путем создания нового класса cellrenderer.Я сделал этоЯ читал о проблеме «цветовой памяти» DefaultTableRenderer, но я не могу понять, как обойти ее для моей конкретной цели.

Моя цель достаточно проста: при нажатии кнопки, изменить фонцвет всех выбранных ячеек в jtable.

У меня настроены адекватные вызовы методов для события, но я не могу заставить рендерер работать так, как я хочу.

Все выбранные ячейки хранятся в массиве таблиц TableCells (класс, содержащий строку, столбец и данные текстовой строки ячейки).Вот мой код для getTableCellRendererComponent внутри моего CustomCellRenderer.

public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
  {
     for(TableCell c: selectedCells)
     {
         if(c.row ==row && c.col == column)
         {
             this.setBackground(Color.black);
         }
         else
         {
             this.setBackground(Color.BLUE);
         }
     }
     return this;
  }

Этот код устанавливает синий цвет фона всех ячеек таблицы.Очевидно, мне нужна другая логика, чтобы обойти эту проблему цветовой памяти.Любые идеи по этому поводу были бы великолепны.

Спасибо.

1 Ответ

3 голосов
/ 27 июня 2011

Как насчет предоставления вашему рендереру класса логической переменной, скажем, btnClicked, которая инициализируется как false, но имеет значение true в ActionListener кнопки, слушателе, который также инструктирует таблицу перерисовывать себя.Затем в самом рендерере вы можете использовать выбранное свойство, чтобы увидеть, выбрана ли ячейка или нет.Возможно, что-то вроде:

   private boolean btnClicked = false;

   public void setBtnClicked(boolean btnClicked) {
      this.btnClicked = btnClicked;
   }

   public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
      if (btnClicked) {
         if (isSelected) {
            setBackground(Color.black);
         } else {
            setBackground(Color.blue);
         }
      } else {
         // if button not clicked
         setBackground(Color.lightGray);
      }
      return this;
   }

Также относительно:

Очевидно, мне нужна другая логика, чтобы обойти эту проблему цветовой памяти.Любые идеи по этому поводу были бы великолепны.

Что это за проблема с цветной памятью, о которой вы говорите?

Edit 1
Вот компилируемыйпример того, что я имел в виду. Я все еще не уверен, что вы имеете в виду под проблемой цветовой памяти, извините.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

@SuppressWarnings("serial")
public class DisplaySelectedTableCells extends JPanel {
   public static final Integer[][] DATA = {
      {1, 2, 3}, {4, 5, 6}, {7, 8, 9},
      {1, 2, 3}, {4, 5, 6}, {7, 8, 9},
      {1, 2, 3}, {4, 5, 6}, {7, 8, 9}
   };
   public static final String[] COLS = {"A", "B", "C"};
   private static final int PREF_WIDTH = 400;
   private static final int PREF_HEIGHT = 300;
   private DefaultTableModel model = new DefaultTableModel(DATA, COLS) {
      @Override
      public Class<?> getColumnClass(int columnIndex) {
         return Integer.class;
      }
   };
   private JTable table = new JTable(model);
   private JToggleButton toggleBtn = new JToggleButton("Show Selected Rows");
   private MyCellRenderer myCellRenderer = new MyCellRenderer();

   public DisplaySelectedTableCells() {
      table.setDefaultRenderer(Integer.class, myCellRenderer);
      JPanel btnPanel = new JPanel();
      btnPanel.add(toggleBtn);

      setLayout(new BorderLayout());
      add(new JScrollPane(table), BorderLayout.CENTER);
      add(btnPanel, BorderLayout.SOUTH);

      toggleBtn.addActionListener(new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent e) {
            myCellRenderer.setShowSelected(toggleBtn.isSelected());
            table.repaint();
         }
      });
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_WIDTH, PREF_HEIGHT);
   }

   private static class MyCellRenderer extends DefaultTableCellRenderer {
      private static final Color SELECTED_COLOR = Color.pink;
      private static final Color UNSELECTED_COLOR = Color.lightGray;
      private static final Color BASE_COLOR = null;
      private boolean showSelected = false;

      public void setShowSelected(boolean showSelected) {
         this.showSelected = showSelected;
      }

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

         if (showSelected) {
            if (isSelected) {
               superComponent.setBackground(SELECTED_COLOR);
            } else {
               superComponent.setBackground(UNSELECTED_COLOR);
            }
         } else {
            superComponent.setBackground(BASE_COLOR);
         }

         return superComponent;
      }
   }

   private static void createAndShowUI() {
      JFrame frame = new JFrame("DisplaySelectedTableCells");
      frame.getContentPane().add(new DisplaySelectedTableCells());
      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();
         }
      });
   }
}
...