JTable RowFilter не фильтрует первоначальный вызов

Без сомнения, это будет легко исправить, но, как обычно, я в тупике.

Я пытаюсь отфильтровать имена семейств шрифтов, которые не могут быть отображены в JTable, с помощью JCheckBox. JTable содержит имена установленных семейств шрифтов (столбец 0), образцы алфавита (столбец 1) и образцы цифр (столбец 2).

Столбцы один и два отображаются соответствующими шрифтами, и если текст в ячейке не может быть отрендеренным, текст заменяется на "неотображаемый" с использованием JTable.setValueAt(Object, int, int).

Затем я использую "неотображаемый" в качестве фильтра. Однако фильтруются только видимые строки. Когда я прокручиваю таблицу до конца и применяю фильтр, вся таблица фильтруется по желанию.

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

import java.awt.*;
import java.awt.event.*;

import java.util.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;

class run
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Viewer viewer = new Viewer();

                JFrame jframe = new JFrame();
                jframe.add(viewer);
                jframe.createBufferStrategy(1);
                jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                jframe.setLocation(50,50);
                jframe.pack();
                jframe.setVisible(true);
            }
        });
    }
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

class Viewer extends JPanel
{
    final static long serialVersionUID = 0;

    String string_alphabet = "abcdefghijklmnopqrstuvwxyz";
    String string_digits = "0123456789";
    String string_punctuation = "`!:\";\',.-/(){}[]<>?";
    String string_symbols = "~@#$%^&*_+=|\\";

    String string_installedFontsColumnNames[] = {"installed fonts","sample","sample"};
    String string_installedFonts[];

    DefaultTableModel defaultTableModel_installedFonts;
    JTable jtable_installedFonts;

    JSplitPane jsplitPane_horizontal;
    JSplitPane jsplitPane_vertical;

    JCheckBox jcheckBox_nonRenderable;

    TableRowSorter<TableModel> tableRowSorter;

    public Viewer()
    {
        this.setLayout(new BorderLayout());

        JPanel jpanel_installedFonts = new JPanel(new BorderLayout());

        GraphicsEnvironment graphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();

        string_installedFonts = graphicsEnvironment.getAvailableFontFamilyNames();

        Object object_tableData[][] = new Object[string_installedFonts.length][string_installedFontsColumnNames.length];

        for (int row = 0; row < object_tableData.length; row++)
        {
            Object object_columnData[] = new Object[string_installedFontsColumnNames.length];

            object_columnData[0] = string_installedFonts[row];
            object_columnData[1] = string_alphabet;
            object_columnData[2] = string_digits;

            object_tableData[row] = object_columnData;
        }

        defaultTableModel_installedFonts = new DefaultTableModel(object_tableData,string_installedFontsColumnNames);

        tableRowSorter = new TableRowSorter<TableModel>(defaultTableModel_installedFonts);

        jtable_installedFonts = new JTable(defaultTableModel_installedFonts);
        jtable_installedFonts.setRowSorter(tableRowSorter);

        jtable_installedFonts.getColumnModel().getColumn(0).setCellRenderer(new ColumnRenderer0());
        jtable_installedFonts.getColumnModel().getColumn(1).setCellRenderer(new ColumnRenderer1());
        jtable_installedFonts.getColumnModel().getColumn(2).setCellRenderer(new ColumnRenderer1());

        JScrollPane jscrollPane_installedFonts = new JScrollPane(jtable_installedFonts);

        jpanel_installedFonts.add(jscrollPane_installedFonts,BorderLayout.CENTER);

        JPanel jpanel_visibilityOptions = new JPanel(new GridLayout(1,2));
        jpanel_visibilityOptions.setBackground(Color.gray);

        JPanel jpanel_nonRenderable = new JPanel();
        jpanel_nonRenderable.setBackground(Color.lightGray);

        jcheckBox_nonRenderable = new JCheckBox("hide non-renderable fonts",false);
        jcheckBox_nonRenderable.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent actionEvent)
            {
                RowFilter<Object,Object> filter = null;

                if (jcheckBox_nonRenderable.isSelected())
                {
                    filter = RowFilter.notFilter(RowFilter.regexFilter("non-renderable"));
                }

                tableRowSorter.setRowFilter(filter);
            }
        });

        jpanel_nonRenderable.add(jcheckBox_nonRenderable,BorderLayout.CENTER);

        jpanel_visibilityOptions.add(new JPanel());
        jpanel_visibilityOptions.add(jpanel_nonRenderable);

        jpanel_installedFonts.add(jpanel_visibilityOptions,BorderLayout.SOUTH);

        jsplitPane_horizontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,jpanel_installedFonts,new JPanel());
        jsplitPane_horizontal.setBorder(new EmptyBorder(0,0,0,0));

        jsplitPane_vertical = new JSplitPane(JSplitPane.VERTICAL_SPLIT,jsplitPane_horizontal,new JPanel());
        jsplitPane_vertical.setBorder(new EmptyBorder(0,0,0,0));

        this.add(jsplitPane_vertical,BorderLayout.CENTER);
    }
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

class ColumnRenderer0 implements TableCellRenderer
{
    JLabel jlabel;

    Color color_background;
    Color color_foreground;

    String string_cellText;

    public ColumnRenderer0()
    {
        jlabel = new JLabel();
        jlabel.setBorder(new EmptyBorder(0,2,0,2));
        jlabel.setHorizontalAlignment(JLabel.LEFT);
        jlabel.setOpaque(true);
    }

    public Component getTableCellRendererComponent(JTable jtable, Object object, boolean selected, boolean focus, int row, int column)
    {
        string_cellText = (String)object;

        if (selected)
        {
            color_background = jtable.getSelectionBackground();
            color_foreground = jtable.getSelectionForeground();
        }
        else
        {
            color_background = jtable.getBackground();
            color_foreground = jtable.getForeground();
        }

        jlabel.setText(string_cellText);
        jlabel.setBackground(color_background);
        jlabel.setForeground(color_foreground);

        return jlabel;
    }
}

//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

class ColumnRenderer1 implements TableCellRenderer
{
    JLabel jlabel;

    Color color_background;
    Color color_foreground;

    String string_cellText;
    String string_fontFamily;

    Font font;
    Font font_jtable;

    public ColumnRenderer1()
    {
        jlabel = new JLabel();
        jlabel.setBorder(new EmptyBorder(0,5,0,5));
        jlabel.setHorizontalAlignment(JLabel.CENTER);
        jlabel.setOpaque(true);
    }

    public Component getTableCellRendererComponent(JTable jtable, Object object, boolean selected, boolean focus, int row, int column)
    {
        string_cellText = (String)object;

        if (selected)
        {
            color_background = jtable.getSelectionBackground();
            color_foreground = jtable.getSelectionForeground();
        }
        else
        {
            color_background = jtable.getBackground();
            color_foreground = jtable.getForeground();
        }

        string_fontFamily = (String)jtable.getValueAt(row,0);

        font_jtable = jtable.getFont();

        font = new Font(string_fontFamily,Font.PLAIN,font_jtable.getSize());

        if (font.canDisplayUpTo(string_cellText) != -1)
        {
            font = new Font(font_jtable.getFamily(),Font.BOLD,font_jtable.getSize());
            string_cellText = "non-renderable";
            jtable.setValueAt(string_cellText,row,column);
            color_foreground = Color.red;

        }

        jlabel.setFont(font);
        jlabel.setText(string_cellText);
        jlabel.setBackground(color_background);
        jlabel.setForeground(color_foreground);

        return jlabel;
    }
}

person johnny    schedule 25.09.2014    source источник
comment
Проблема в том, что до тех пор, пока ячейка не будет отображена, текст остается таким, каким вы его изначально установили, а невидимые ячейки не отображаются. Вы не должны изменять состояние модели из средства визуализации, а вместо этого должны предварительно определить, доступен ли шрифт для визуализации или нет, когда вы создаете табличную модель.   -  person MadProgrammer    schedule 25.09.2014
comment
@MadProgrammer, вы правы в отношении проверки перед визуализацией. это также устранило проблему с разделителем, не рисующим. я должен спросить, есть ли что-то, что вы не знаете?   -  person johnny    schedule 25.09.2014
comment
То, чего я не знаю, может заполнить вселенную по сравнению с тем, что я знаю, что не может заполнить даже каплю дождя ... Я знаю, я тоже совершал эти ошибки ;)   -  person MadProgrammer    schedule 25.09.2014
comment
@MadProgrammer, добавь еще скромности, спасибо. как пометить вопрос как закрытый?   -  person johnny    schedule 25.09.2014
comment
Я расширил свой комментарий как ответ, если он вас устраивает, и он отвечает на ваш вопрос, то вы можете отметить его как правильный. Если вам нужны подробности, дайте мне знать ;)   -  person MadProgrammer    schedule 25.09.2014


Ответы (1)


Проблема в том, что до тех пор, пока ячейка не будет отображена, текст остается таким, каким вы его изначально установили. Невидимые ячейки не визуализируются, поэтому модель не обновляется. Фильтрация происходит в разное время по разным причинам.

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

person MadProgrammer    schedule 25.09.2014