简体   繁体   English

JTable RowFilter不过滤初始调用

[英]JTable RowFilter not filtering initial invocation

No doubt this will be an easy fix, but as usual, I'm stumped. 毫无疑问,这将是一个简单的解决方法,但是像往常一样,我很沮丧。

I'm trying to filter out font family names that are non-renderable in a JTable using a JCheckBox. 我正在尝试使用JCheckBox过滤掉​​JTable中不可渲染的字体系列名称。 The JTable contains installed font family names (column 0), sample alphabet(column 1) and sample digits(column 2). JTable包含已安装的字体系列名称(第0列),示例字母(第1列)和示例数字(第2列)。

Columns one and two are rendered in their corresponding fonts and if the text in a cell cannot be renderered, the text is replaced with "non-renderable" using JTable.setValueAt(Object, int, int). 第一和第二列以其相应的字体呈现,如果无法呈现单元格中的文本,则使用JTable.setValueAt(Object,int,int)将文本替换为“ non-renderable”。

I then use then use "non-renderable" as the filter. 然后,我使用“不可渲染”作为过滤器。 However, only rows which are visible are filtered. 但是,仅过滤可见行。 When I scroll to the bottom of the table and apply the filter, the entire table is filtered as desired. 当我滚动到表格的底部并应用过滤器时,整个表格都会根据需要进行过滤。

I also noticed, that when i move the horizontal divider, the divider doesnt repaint itself when it moves over the altered cells. 我还注意到,当我移动水平分隔线时,分隔线在更改的单元格上方移动时不会重绘自身。 Any help on this would also be appreciated. 任何帮助,也将不胜感激。

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

The problem is, until the cell is rendered, the text remains what you initially set it to. 问题是,在渲染单元之前,文本将保留您最初设置的位置。 Cells that are not visible are not rendered, therefore the model is not been updated. 不可见的单元格不会呈现,因此不会更新模型。 Filtering occurs at different times for different reasons. 出于不同的原因,过滤在不同的时间发生。

You should not be modifying the state of the model from within the renderer, but instead, should pre-determine if the font is renderedable or not when you built the table model and set the cell value accordingly... 您不应该在渲染器内部修改模型的状态,而应该在构建表格模型并相应地设置单元格值时预先确定字体是否可渲染。

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

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