简体   繁体   中英

In a JTable, how do I render a checkbox column with a dirty marker?

I'm trying to show a marker on checkbox columns in a JTable to indicate that the value is dirty.

I'm having trouble coming up with a way to render the marker. I've tried setting an icon on the JCheckbox but this just renders the icon instead of the checkbox. I've tried using a Panel but it messes up the layout.

Does anyone have an idea what is the best way to do this?

Thanks

This is the sort of thing I've tried so far:

import java.awt.Component;

import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer;

public class DirtyCheckboxRenderer extends JCheckBox implements TableCellRenderer {

    private final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);


    public DirtyCheckboxRenderer() {
        setHorizontalAlignment(SwingConstants.CENTER);
        setBorderPainted(true);
    }


    @Override
    public Component getTableCellRendererComponent(JTable table, 
                                                   Object value, 
                                                   boolean isSelected, 
                                                   boolean hasFocus, 
                                                   int row, 
                                                   int column) {

        setForegroundColor(table, isSelected);
        setBackgroundColor(table, isSelected);
        setCheckboxState(value);
        setBorder(hasFocus);
        setDirtyMarkerIcon();

        return this;

    }


    private void setCheckboxState(Object value) {
        boolean checked = value != null && ((Boolean) value).booleanValue();
        setSelected(checked);
    }


    private void setBorder(boolean hasFocus) {
        if (hasFocus) {
            setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
        } else {
            setBorder(this.noFocusBorder);
        }
    }


    private void setForegroundColor(JTable table, boolean isSelected) {
        if (isSelected) {
            setForeground(table.getSelectionForeground());
        } else {
            setForeground(table.getForeground());
        }
    }


    private void setBackgroundColor(JTable table, boolean isSelected) {

        if (isSelected) { 
            setBackground(table.getSelectionBackground());
        } else {
            setBackground(table.getBackground());
        }

    }

    private void setDirtyMarkerIcon() {
        boolean columnIsDirty = true; //TODO 

        if (columnIsDirty) {
            Icon icon = getDirtyMarkerIcon();
            setHorizontalTextPosition(SwingConstants.TRAILING);
            setIcon(icon);
        } else {
            setIcon(null);
        }

    }


    private Icon getDirtyMarkerIcon() {

        //TODO
        return null; //
    }


} 

If you insist on having the 'dirty icon' show up trailing the checkbox, then you will have to use a panel.

To keep your column from having a broken layout, you should always render the icon, even if it is a transparent placeholder icon.

One convenient approach is to have DirtyCheckboxRenderer implement the Icon interface and do setIcon(this) in the constructor. The paintIcon() method gives you a reference to the component, and the x and y coordinates will correctly reflect your text position settings.

如果您在TableModel的getColumnClass方法中返回Boolean,则JTable应该自动呈现一个Checkbox。

好吧,一种简单的方法是更改​​复选框的文本,并在其前面加上星号。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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