繁体   English   中英

尝试替换JTable中的布尔CheckBox渲染器/编辑器

[英]Trying to Replace Boolean CheckBox renderer/editor in JTable

我正在尝试创建一个允许对项目进行收藏的JTable,但是不幸的是,正确的图像不会在初始渲染时显示,然后在它们失去单元格焦点之前不会正确更新。

为此,我将第1列设置为String,将第2列设置为布尔值。 然后,我根据此问题改写了布尔渲染器/编辑器:

Java Swing,尝试用图像图标复选框替换JTable中的布尔复选框

我目前有什么:

public class FavoritableCellEditor extends AbstractCellEditor implements TableCellEditor {

private final FavoriteCheckBox cellEditor;

public FavoritableCellEditor() {
    cellEditor = new FavoriteCheckBox();
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    if (value instanceof Boolean) {
        boolean selected = (boolean) value;
        cellEditor.setSelected(selected);
    }
    return cellEditor;
}

@Override
public Object getCellEditorValue() {
    return cellEditor.isSelected();
}

}


public class FavoritableCheckboxRenderer extends FavoriteCheckBox implements TableCellRenderer {


@Override
public void setSelected(boolean selected) {
    super.setSelected(selected);
    if (selected) {
        setIcon(selIcon);
    } else {
        setIcon(unselIcon);
    }
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    if (value instanceof Boolean) {
        boolean selected = (boolean) value;
        setSelected(selected);
    }
    return this;
}
}

public class FavoriteCheckBox extends JCheckBox {

    Icon selIcon;
    Icon unselIcon;

    public FavoriteCheckBox() {
        try {
            selIcon = new ImageIcon(ImageIO.read(getClass().getResource("/com/lmco/jsf/dqim/applications/TESTING/resources/baseline_star_black_18dp.png")));
            unselIcon = new ImageIcon(ImageIO.read(getClass().getResource("/com/lmco/jsf/dqim/applications/TESTING/resources/baseline_star_border_black_18dp.png")));
        } catch (IOException ex) {
            Logger.getLogger(FavoriteCheckBox.class.getName()).log(Level.SEVERE, null, ex);
        }
        setHorizontalAlignment(CENTER);
    }

    @Override
    public void setSelected(boolean selected) {
        super.setSelected(selected);
        if (selected) {
            setIcon(selIcon);
        } else {
            setIcon(unselIcon);
        }
        revalidate();
        repaint();
    }

}

演示:我首先单击您看到复选标记的位置。 当前没有显示正确的图像,而是默认的复选框图像。 在此处输入图片说明

现在,我单击右下角以使该单元格失去焦点,然后用正确的图像填充自身。 在此处输入图片说明

最后,我点击您看到复选标记的位置 在此处输入图片说明

补充说明:我自己添加了revalidate()和repaint(),没有它的行为基本上是相同的,除了它在初始渲染后不再显示复选标记。 直到失去焦点,它仍不会更新图像

如果只有一列布尔值,则可以仅自定义复选框编辑器和渲染器使用的图标:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
import java.text.*;

public class TableBasic extends JPanel
{
    public TableBasic()
    {
        setLayout( new BorderLayout() );

        String[] columnNames = {"Date", "String", "Integer", "Boolean"};

        Object[][] data =
        {
            {new Date(), "A", new Integer(1), Boolean.TRUE },
            {new Date(), "B", new Integer(2), Boolean.FALSE},
            {new Date(), "C", new Integer(12), Boolean.TRUE },
            {new Date(), "D", new Integer(5124), Boolean.FALSE}
        };

        DefaultTableModel model = new DefaultTableModel(data, columnNames)
        {
            //  Returning the Class of each column will allow different
            //  renderers and editors to be used based on Class

            @Override
            public Class getColumnClass(int column)
            {
                for (int row = 0; row < getRowCount(); row++)
                {
                    Object o = getValueAt(row, column);

                    if (o != null)
                        return o.getClass();
                }

                return Object.class;
            }
        };

        JTable table = new JTable(model);

        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane( table );
        add( scrollPane );

        // Customize the icons of the renderer/editor used for Boolean data

        Icon selectedIcon = new ImageIcon( "copy16.gif" );
        Icon icon = new ImageIcon( "about16.gif" );

        DefaultCellEditor dce = (DefaultCellEditor)table.getDefaultEditor(Boolean.class);
        JCheckBox cbe = (JCheckBox)dce.getComponent();
        cbe.setSelectedIcon( selectedIcon );
        cbe.setIcon( icon );

        TableCellRenderer tcr = table.getDefaultRenderer(Boolean.class);
        JCheckBox cbr = (JCheckBox)tcr;
        cbr.setSelectedIcon( selectedIcon );
        cbr.setIcon( icon );
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("TableBasic");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new TableBasic() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }

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

如果需要多个布尔渲染器/编辑器,则需要为每个渲染器/编辑器创建唯一的实例。

创建编辑器很容易。 您只需使用自定义JCheckBox创建DefaultCellEditor:

JCheckBox checkBox = new JCheckBox();
checkBox.setHorizontalAlignment(JCheckBox.CENTER);
checkBox.setSelectedIcon( selectedIcon );
checkBox.setIcon( icon );
DefaultCellEditor dce = new DefaultCellEditor( checkBox );
table.getColumnModel().getColumn(???).setCellEditor(dce);

创建渲染器更加困难。 您需要创建一个自定义渲染器。 这是在JTable源代码中找到的BooleanRenderer的默认渲染器代码:

static class BooleanRenderer extends JCheckBox implements TableCellRenderer, UIResource
{
    private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

    public BooleanRenderer() {
        super();
        setHorizontalAlignment(JLabel.CENTER);
        setBorderPainted(true);
    }

    public Component getTableCellRendererComponent(JTable table, Object value,
                                                   boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
            setForeground(table.getSelectionForeground());
            super.setBackground(table.getSelectionBackground());
        }
        else {
            setForeground(table.getForeground());
            setBackground(table.getBackground());
        }
        setSelected((value != null && ((Boolean)value).booleanValue()));

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

        return this;
    }
}

在构造函数中,您将设置图标。

暂无
暂无

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

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