java - JTable:单击按钮时更改单元格背景

标签 java jtable render background-color

我知道更改 jtable 中的单元格背景是通过创建新的 cellrenderer 类来完成的。我已经这么做了。我已经阅读过有关 DefaultTableRenderer“颜色内存”问题的信息,但我不知道如何针对我的特定目的解决它。

我的目标很简单:单击按钮时,更改 jtable 中所有选定单元格的背景颜色。

我为该事件设置了足够的方法调用,但我无法让渲染器按照我想要的方式工作。

我将所有选定的单元格存储在 TableCells 的数组列表中(包含行、列和单元格的文本字符串数据的类)。这是我的 CustomCellRenderer 内部的 getTableCellRendererComponent 代码。

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

此代码将所有表格单元格的背景设置为蓝色。显然我需要一些不同的逻辑来解决这个颜色内存问题。任何关于这方面的想法都会很棒。

谢谢。

最佳答案

如何为渲染器类提供一个 boolean 变量,例如 btnClicked,该变量初始化为 false,但在按钮的 ActionListener 中设置为 true,该监听器还指示表重新绘制自身。然后在渲染器本身中,您可以使用 selected 属性来查看单元格是否被选中。也许是这样的:

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

还涉及:

Obviously I need some different logic to work around this color memory issue. Any ideas on this would be great.

您所说的“颜色内存问题”是什么?

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

关于java - JTable:单击按钮时更改单元格背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6487763/

相关文章:

javascript - 如何在 ReactJS 中为 API 中的每个渲染元素显示函数返回的不同值?

java - 雨云和交替行颜色

java - 如何通过 JAVA 中的 SoapClient 运行命令

java - Android 中如何获取最后插入的记录?

java - 如何获取当前选项卡的Jtable或者jTable模型?

Java 发布资源

java - Jar Mismatch 在依赖列表中找到 2 个版本的 android-support-v4.jar

java - 用非常简单的术语来说,Groovy/Grails/Hibernate/JBoss/Jade 是什么?

java - 动态更改 JTable 中的列数

node.js - 获取渲染名称jade