2014-09-25 63 views
0

毫无疑问,这将是一个简单的修复,但像往常一样,我很难过。

我试图过滤使用JCheckBox在JTable中不可呈现的字体系列名称。 JTable包含已安装的字体系列名称(第0列),样本字母表(第1列)和样本数字(第2列)。

第1列和第2列以相应的字体呈现,如果单元格中的文本不能渲染,则使用JTable.setValueAt(Object,int,int)将文本替换为“不可渲染”。

然后我使用“non-renderable”作为过滤器。但是,只有可见的行才会被过滤。当我滚动到表格底部并应用过滤器时,整个表格都会根据需要进行过滤。

我还注意到,当我移动水平分隔线时,分隔线不会在重新改变的单元格上移动时重新绘制。任何帮助也将不胜感激。

JTable RowFilter不过滤初始调用

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 = ""; 
    String string_punctuation = "`!:\";\',.-/(){}[]<>?"; 
    String string_symbols = "[email protected]#$%^&*_+=|\\"; 

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

问题是,在单元格呈现之前,文本仍然是您最初设置的内容,而不可见的单元格不会呈现。您不应该在渲染器中修改模型的状态,而应该在您创建表格模型 – MadProgrammer 2014-09-25 10:05:02

+0

@MadProgrammer时预先确定该字体是否可渲染,您在渲染前检查时是否正确。它也修复了分隔线而不是绘画问题。我不得不问,你有什么不知道的吗? – johnny 2014-09-25 10:25:27

+0

我不知道可以填补宇宙相比,我知道哪些甚至不能填补雨滴...我知道,我也犯过这些错误;) – MadProgrammer 2014-09-25 10:28:43

回答

1

的问题是,直到电池被渲染,文本仍然是你最初设置它。不可见的单元格不会呈现,因此模型未更新。出于不同的原因,过滤发生在不同的时间。

您不应该在渲染器内修改模型的状态,而应该在构建表模型时相应地预先确定字体是否可渲染,并相应地设置单元格值...