简体   繁体   English

Jtable cellRenderer更改行的背景

[英]Jtable cellRenderer change background of row

I have been tryng for some time and looking over the internet to find the solution however I have failed. 我已经尝试了一段时间,并在互联网上寻找解决方案,但是我失败了。 What I'm trying to do is to change row background of Jtable dynamically. 我正在尝试做的是动态更改Jtable的行背景。 I have created arrayList which keeps numbers of selected rows (Adding them everytime user press alt+click on a cell) and in my own tableCellRenderer I have added 我创建了arrayList,它保留了选定行的数量(每次用户按alt +单击一个单元格时都会添加它们),并在我自己的tableCellRenderer中添加了

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

It is working, for few cells, or some time after which selected columns are back to their oryginal color, I have checked, the ints are still in Array so thats not the problem, any idea what might cause the issue? 我已经检查过,选中的列恢复为原始颜色后,它在少数几个单元格中工作了,或者过了一段时间,我检查了这些整数是否仍在Array中,所以这不是问题,不知道是什么原因引起的?

As already suggested in comments above, you need to provide a custom renderer for all required columns. 正如上面的注释中已经建议的那样,您需要为所有必需的列提供一个自定义渲染器。 As an alternative, you can override JTable.prepareRenderer to set the background according to the list of affected rows. 或者,您可以重写JTable.prepareRenderer以根据受影响的行的列表设置背景。 Table Row Rendering by @camickr explains this approach. @camickr进行的表行渲染说明了这种方法。 Below is an example that highlights rows clicked with mouse + Alt key. 下面的示例突出显示了用鼠标+ Alt键单击的行。 For simplicity, the list of highlighted rows is kept as client property. 为简单起见,突出显示的行的列表保留为客户端属性。

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

I'd recommend using CTRL for multi-select instead of ALT. 我建议使用CTRL代替ALT进行多选。 For one, any users who want to multi-select will already know how to do it because CTRL is the de-facto standard modifier key for multi-select. 首先,任何想要进行多重选择的用户都已经知道该怎么做,因为CTRL是多重选择的事实上的标准修饰键。 Second, you get the behavior you want for free, without having to implement anything special (except, perhaps, your preferred color scheme). 其次,您可以免费获得所需的行为,而无需实施任何特殊操作(也许,除了您偏爱的配色方案外)。

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM