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

Posted

技术标签:

【中文标题】JTable:单击按钮时更改单元格背景【英文标题】:JTable: changing cell background when a button is clicked 【发布时间】:2011-09-23 04:26:39 【问题描述】:

我知道在 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;
  

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

谢谢。

【问题讨论】:

【参考方案1】:

如何给你的渲染器类一个布尔变量,比如 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;
   

另外关于:

显然我需要一些不同的逻辑来解决这个颜色记忆问题。任何关于这方面的想法都会很棒。

您所说的“颜色记忆问题”是什么?

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

【讨论】:

我读到 DefaultCellRenderer 的颜色记忆问题是,如果您没有在逻辑中的所有位置指定单元格背景的颜色,它将使用最后一次 setBackground 调用中定义的背景渲染所有单元格.我不知道这是否会被视为更多的“问题”或实施选择,但现在我称之为问题,因为它没有做我想要的:p 感谢您的回复。我会试试这个并回复。 这确实有效,但我现在正在寻找一种方法让单元格在取消选择后保持其设置的背景颜色。感谢您的回复。 这有帮助。感谢您输入。 大家好!如果我希望单元格永久具有这种颜色,我该怎么做,就像在 excel 中为单元格着色一样?

以上是关于JTable:单击按钮时更改单元格背景的主要内容,如果未能解决你的问题,请参考以下文章

定义单元格更改时的Java jTable颜色行

JTable 单元格更新不起作用

单击以打开 JComboBox 时,JTable 单元格失去价值

什么是JTable的任何单元格中的更改的正确事件?

当其他单元格值更改时禁用 JTable 单元格可编辑

Java - Jtable - 不同颜色的单元格