【问题标题】:Jtable cellRenderer change background of rowJtable cellRenderer 改变行的背景
【发布时间】:2013-04-09 17:00:30
【问题描述】:

我已经尝试了一段时间并在互联网上寻找解决方案,但是我失败了。 我要做的是动态更改 Jtable 的行背景。 我创建了 arrayList ,它保留了选定行的数量(每次用户按 alt+单击单元格时添加它们) 并在我自己的 tableCellRenderer 中添加了

for(Integer c: leftSelectedCells){
if(c.equals(row)){comp.setForeground(Color.red); }
else { comp.setForeground(Color.black);}
}

它正在工作,对于少数单元格,或者在选定的列恢复其原始颜色的一段时间后,我已经检查过,整数仍然在数组中,所以这不是问题,知道可能导致问题的原因吗?

【问题讨论】:

  • 您需要为能够提供所需功能的每种列类型提供 TableCellRenderes。查看How to use tables了解更多详情
  • 只是一般建议,但通常 CTRL(不是 ALT)是用于多选的修饰键。
  • 在这种情况下,最好使用 JTable.setDefaultCellRenderer 而不是按列设置渲染器。另外:您说您想更改行背景,但您的示例代码设置了前景。在我的回答中,我在设置前景方面遵循了您的建议,但如果确实是您想要的,您可以轻松修改它以设置背景。

标签: java swing jtable cellrenderer


【解决方案1】:

正如上面 cmets 中已经建议的那样,您需要为所有必需的列提供自定义渲染器。作为替代方案,您可以覆盖JTable.prepareRenderer 以根据受影响的行列表设置背景。 @camickr 的Table Row Rendering 解释了这种方法。下面是一个突出显示使用鼠标 + Alt 键单击的行的示例。为简单起见,突出显示的行列表保留为客户端属性。

import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class TableHighlight {
    TableHighlight() {
        JFrame frame = new JFrame("TableHighlight");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Object[][] data = { { "Column 1", "Column 2" },
                { "Column 1", "Column 2" }, { "Column 1", "Column 2" },
                { "Column 1", "Column 2" } };

        Object[] columnNames = { "Column 1", "Column 2" };

        DefaultTableModel model = new DefaultTableModel(data, columnNames);

        final JTable table = new JTable(model) {
            @Override
            public Component prepareRenderer(TableCellRenderer renderer,
                    int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                List<Integer> selectedRows = (List<Integer>) getClientProperty("highlightRows");
                c.setBackground(selectedRows.contains(row) ? Color.cyan : getBackground());
                return c;
            }
        };

        table.putClientProperty("highlightRows", new ArrayList<Integer>());

        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent evt) {
                if (!evt.isAltDown())
                    return;
                int row = table.rowAtPoint(evt.getPoint());
                if (row == -1)
                    return;
                List<Integer> selectedRows = (List<Integer>) table
                        .getClientProperty("highlightRows");
                int index = selectedRows.indexOf(row);
                if (index != -1)
                    selectedRows.remove(index);
                else
                    selectedRows.add(row);
                table.repaint();
            }
        });

        frame.add(new JScrollPane(table));
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TableHighlight();
            }
        });
    }
}

【讨论】:

    【解决方案2】:

    我建议使用 CTRL 代替 ALT 进行多选。一方面,任何想要多选的用户都已经知道怎么做,因为 CTRL 是多选事实上的标准修饰键。其次,您可以免费获得您想要的行为,而无需实现任何特殊的东西(也许您喜欢的配色方案除外)。

    package com.example.table.multiselect;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Component;
    
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellRenderer;
    
    public class MultiRowTableSelect extends JFrame {
    
        public MultiRowTableSelect() {
            DefaultTableModel model = new DefaultTableModel(0, 3);
            model.addRow(new Integer[]{1, 2, 3});
            model.addRow(new Integer[]{4, 5, 6});
            model.addRow(new Integer[]{7, 8, 9});
            model.addRow(new Integer[]{10, 11, 12});
    
            JTable tbl = new JTable(model);
            tbl.setRowSelectionAllowed(true); // when you click a cell, the entire row will be highlighted
    
            /* Assuming you want all cells to be rendered using the custom renderer
             * unless otherwise overridden, you can simply set the JTable's default
             * renderer.  The implementation is so simple here that I'm just
             * creating an anonymous subclass of DefaultTableCellRenderer.
             */
            tbl.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
                @Override
                public Component getTableCellRendererComponent(JTable table, Object value,
                        boolean isSelected, boolean hasFocus, int row, int column) {
    
                    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    
                    if (isSelected) {
                        c.setForeground(Color.RED); // you can set the foreground and/or background here
                    }
    
                    return c;
                }
            });
    
            add(new JScrollPane(tbl), BorderLayout.CENTER);
    
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setLocationByPlatform(true);
            pack();
            setSize(400, 200);
            setVisible(true);
        }
    
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            new MultiRowTableSelect();
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-23
      • 2012-07-15
      • 2011-04-21
      • 2013-09-03
      • 2015-10-24
      • 1970-01-01
      • 2014-09-10
      • 2012-01-02
      • 2015-10-13
      相关资源
      最近更新 更多