Попытка заменить логический рендерер / редактор CheckBox в JTable - PullRequest
0 голосов
/ 03 июля 2019

Я пытаюсь создать JTable, который позволяет добавлять элементы в избранное, но, к сожалению, правильные изображения не отображаются при первоначальном рендеринге, а затем не обновляются должным образом, пока они не потеряют фокус в ячейке.

Для этого я сделал столбец 1 строкой, а столбец 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();
    }

}

Демонстрация: я сначала нажимаю там, где вы видите галочку.В настоящее время правильные изображения не отображаются, но установлены флажки по умолчанию.enter image description here

Теперь я щелкаю по правому нижнему углу, чтобы эта ячейка теряла фокус, а затем закрашивала себя, заполняя правильное изображение.enter image description here

Наконец я нажимаю там, где вы видите галочку enter image description here

Дополнительное примечание: я добавил в повторную проверку() и repaint () сам, без него поведение в основном такое же, за исключением того, что он никогда не будет показывать галочки снова после первоначального рендеринга.Он по-прежнему не будет обновлять изображение, пока не потеряется фокус

1 Ответ

2 голосов
/ 04 июля 2019

Если у вас есть только один столбец логических значений, вы можете просто настроить значки, используемые редактором и средством визуализации флажков:

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

Если вам нужно несколько булевых средств визуализации / редакторов, тогда вам потребуетсясоздавать уникальные экземпляры каждого рендерера / редактора.

Создать редактор легко.Вы просто создаете DefaultCellEditor, используя свой собственный JCheckBox:

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

Создание рендерера более сложное.Вам нужно создать собственный рендер.Вот код рендерера по умолчанию для BooleanRenderer, найденный в источнике JTable:

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

В конструкторе вы должны установить иконки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...