2011-06-20 16 views
7

如何是可能的,如果含有相同的JTextField /文件字符串值與TableCell到synchonize鍵入到JTextField文本(然後通過DocumentListener傳遞StringRowFilter亮點SUBSTRING在TableCell的(一個或多個),其被使用的JTable filetering

然後亮點(表示FE改變文字Color.Red)對於相同的文本在同步TableCell(s)

我知道通過一些黑客的使用是通過使用

1 /通過利用getTableCellRendererComponent

2 /通過使用prepareRenderer

有另一種,也許正確的方式(一個或多個)

點點改性從JTable的教程代碼

import java.awt.*; 
import java.util.regex.PatternSyntaxException; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.table.*; 

public class TableFilterSorter extends JPanel { 

    private boolean DEBUG = false; 
    private static final long serialVersionUID = 1L; 

    public TableFilterSorter() { 
     super(new BorderLayout(5, 5)); 
     final JTextField filterCpText = new JTextField(); 
     filterCpText.setFont(new Font("Serif", Font.BOLD, 28)); 
     filterCpText.setForeground(Color.BLUE); 
     filterCpText.setBackground(Color.LIGHT_GRAY); 
     JPanel filterCpPanel = new JPanel(); 
     filterCpPanel.setLayout(new BorderLayout(5, 5)); 
     filterCpPanel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1)); 
     filterCpPanel.setBackground(Color.LIGHT_GRAY); 
     filterCpPanel.setPreferredSize(new Dimension(300, 30)); 
     filterCpPanel.add(filterCpText, BorderLayout.CENTER); 
     add(filterCpPanel, BorderLayout.NORTH); 
     final JTable table = new JTable(new MyTableModel()); 
     table.setPreferredScrollableViewportSize(new Dimension(500, 160)); 
     table.setFillsViewportHeight(true); 
     JScrollPane scrollPane = new JScrollPane(table); 
     add(scrollPane, BorderLayout.CENTER); 
     TableModel myTableModel = table.getModel(); 
     final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(myTableModel); 
     table.setRowSorter(sorter); 
     filterCpText.getDocument().addDocumentListener(new DocumentListener() { 

      private void searchFieldChangedUpdate(DocumentEvent evt) { 
       String text = filterCpText.getText(); 
       if (text.length() == 0) { 
        sorter.setRowFilter(null); 
        table.clearSelection(); 
       } else { 
        try { 
         sorter.setRowFilter(RowFilter.regexFilter("(?i)" + text, 4)); 
         table.clearSelection(); 
        } catch (PatternSyntaxException pse) { 
         JOptionPane.showMessageDialog(null, "Bad regex pattern", 
           "Bad regex pattern", JOptionPane.ERROR_MESSAGE); 
        } 
       } 
      } 

      @Override 
      public void insertUpdate(DocumentEvent evt) { 
       searchFieldChangedUpdate(evt); 
      } 

      @Override 
      public void removeUpdate(DocumentEvent evt) { 
       searchFieldChangedUpdate(evt); 
      } 

      @Override 
      public void changedUpdate(DocumentEvent evt) { 
       searchFieldChangedUpdate(evt); 
      } 
     }); 
    } 

    private class MyTableModel extends AbstractTableModel { 

     private static final long serialVersionUID = 1L; 
     private String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"}; 
     private Object[][] data = { 
      {"Mary", "Campione", "Snowboarding", new Integer(5), false}, 
      {"Alison", "Huml", "Rowing", new Integer(3), true}, 
      {"Kathy", "Walrath", "Knitting", new Integer(2), false}, 
      {"Sharon", "Zakhour", "Speed reading", new Integer(20), true}, 
      {"Philip", "Milne", "Pool", new Integer(10), false}, 
      {"Mary", "Campione", "Snowboarding", new Integer(5), false}, 
      {"Alison", "Huml", "Rowing", new Integer(3), true}, 
      {"Kathy", "Walrath", "Knitting", new Integer(2), false}, 
      {"Sharon", "Zakhour", "Speed reading", new Integer(20), true}, 
      {"Philip", "Milne", "Pool", new Integer(10), false},}; 

     @Override 
     public int getColumnCount() { 
      return columnNames.length; 
     } 

     @Override 
     public int getRowCount() { 
      return data.length; 
     } 

     @Override 
     public String getColumnName(int col) { 
      return columnNames[col]; 
     } 

     @Override 
     public Object getValueAt(int row, int col) { 
      return data[row][col]; 
     } 

     @Override 
     public Class<?> getColumnClass(int c) { 
      return getValueAt(0, c).getClass(); 
     } 

     @Override 
     public boolean isCellEditable(int row, int col) { 
      if (col < 2) { 
       return false; 
      } else { 
       return true; 
      } 
     } 

     @Override 
     public void setValueAt(Object value, int row, int col) { 
      if (DEBUG) { 
       System.out.println("Setting value at " + row + "," + col 
         + " to " + value + " (an instance of " + value.getClass() + ")"); 
      } 
      data[row][col] = value; 
      fireTableCellUpdated(row, col); 
      if (DEBUG) { 
       System.out.println("New value of data:"); 
       printDebugData(); 
      } 
     } 

     private void printDebugData() { 
      int numRows = getRowCount(); 
      int numCols = getColumnCount(); 
      for (int i = 0; i < numRows; i++) { 
       System.out.print(" row " + i + ":"); 
       for (int j = 0; j < numCols; j++) { 
        System.out.print(" " + data[i][j]); 
       } 
       System.out.println(); 
      } 
      System.out.println("--------------------------"); 
     } 
    } 

    private static void createAndShowGUI() { 
     JFrame frame = new JFrame("TableDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     TableFilterSorter newContentPane = new TableFilterSorter(); 
     newContentPane.setOpaque(true); 
     frame.setContentPane(newContentPane); 
     frame.setLocation(150, 150); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

回答

7

JXTable可以做所以通過一個熒光筆 - 看一個示例(搜索演示中的MatchingTextHighlighter)的swinglabs演示 - 那裏畫家應用背景高光。

您可以在渲染器的某處手動執行此類操作。如果使用JLabel作爲renderingComponent,則基本上必須找到需要背景突出顯示的部分文本併爲該區域繪製背景(下面是查找演示示例的代碼片段)。或者你可以考慮使用一個JTextField渲染的組件:進階是熒光筆(從javax.swing.text中)是內置的disadv與文字譜曲作爲渲染;-)

/** 
* Finds the rectangles that contain rendered characters that match the 
* pattern. 
* 
* @param object an optional configuration parameter. This may be null. 
* @param width width of the area to paint. 
* @param height height of the area to paint. 
* @return a <code>List</code> of <code>Rectangle</code>s marking characters 
*   to highlight 
*/ 
protected List<Rectangle> findHighlightAreas(JLabel object, int width, 
     int height) { 
    String text = object.getText(); 

    insets = object.getInsets(insets); 

    viewR.x = 0 + insets.left; 
    viewR.y = 0 + insets.bottom; 
    viewR.width = width - insets.right; 
    viewR.height = height - insets.top; 

    // Reset the text and view rectangle x any y coordinates. 
    // These are not set to 0 in SwingUtilities.layoutCompoundLabel 
    iconR.x = iconR.y = 0; 
    textR.x = textR.y = 0; 

    FontMetrics fm = object.getFontMetrics(object.getFont()); 
    String clippedText = SwingUtilities.layoutCompoundLabel(object, fm, 
      text, object.getIcon(), object.getVerticalAlignment(), object 
        .getHorizontalAlignment(), object 
        .getVerticalTextPosition(), object 
        .getHorizontalTextPosition(), viewR, iconR, textR, 
      object.getIconTextGap()); 

    int xOffset = calculateXOffset(object, viewR, textR); 

    String textToSearch = clippedText; 
    // Check to see if the text will be clipped 
    if (!object.getText().equals(clippedText)) { 
     // TODO There has to be a better way that assuming ellipses 
     // are the last characters of the text 
     textToSearch = clippedText.substring(0, clippedText.length() - 3); 
    } 

    return createHighlightAreas(textToSearch, fm, xOffset, height); 
} 

/** 
* Creates the rectangles that contain matched characters in the given text. 
* 
* @param text the text to search 
* @param fm the font metrics of the rendered font 
* @param xOffset the x offset at which text rendering starts 
* @param height the height of painted highlights 
* @return a <code>List</code> of highlight areas to paint 
*/ 
protected List<Rectangle> createHighlightAreas(String text, FontMetrics fm, 
     int xOffset, int height) { 
    SearchPredicate predicate = (SearchPredicate) getHighlightPredicate(); 
    Matcher matcher = predicate.getPattern().matcher(text); 

    List<Rectangle> highlightAreas = null; 
    int startFrom = 0; 
    while (startFrom < text.length() && matcher.find(startFrom)) { 
     if (highlightAreas == null) { 
      highlightAreas = new ArrayList<Rectangle>(); 
     } 

     int start = matcher.start(); 
     int end = matcher.end(); 

     if (start == end) { 
      // empty matcher will cause infinite loop 
      break; 
     } 

     startFrom = end; 

     int highlightx; 
     int highlightWidth; 

     if (start == 0) { 
      // start highlight from the start of the field 
      highlightx = textR.x + xOffset; 
     } else { 
      // Calculate the width of the unhighlighted text to 
      // get the start of the highlighted region. 
      String strToStart = text.substring(0, start); 
      highlightx = textR.x + fm.stringWidth(strToStart) + xOffset; 
     } 

     // Get the width of the highlighted region 
     String highlightText = text.substring(start, end); 
     highlightWidth = fm.stringWidth(highlightText); 

     highlightAreas.add(new Rectangle(highlightx, 0, highlightWidth, 
       height)); 
    } 

    if (highlightAreas == null) { 
     highlightAreas = Collections.emptyList(); 
    } else { 
     coalesceHighlightAreas(highlightAreas); 
    } 
    return highlightAreas; 
} 

/** 
* Joins highlight rectangles that mark adjacent horizontal areas into 
* single rectangles. This is useful to renderers that vary horizontally, 
* such a horizontal gradient - the gradient will not restart when there are 
* two adjacent highlight areas. 
* 
* @param highlightAreas a <code>List</code> of <code>Rectangle</code>s. 
*/ 
protected void coalesceHighlightAreas(List<Rectangle> highlightAreas) { 
    Collections.sort(highlightAreas, X_AXIS_RECTANGLE_COMPARATOR); 

    int i = 0; 
    while (i < highlightAreas.size() - 1) { 
     Rectangle r1 = highlightAreas.get(i); 
     Rectangle r2 = highlightAreas.get(i + 1); 

     if (r1.x + r1.width == r2.x) { 
      r1.width += r2.width; 
      highlightAreas.remove(i + 1); 
     } else { 
      i++; 
     } 
    } 
} 

/** 
* Calculates the x offset of highlights based on component orientation and 
* text direction. 
* 
* @param component the renderer component 
* @param viewR the view rectangle of the renderer component 
* @param textR the text rectangle of the renderer component 
* @return the number of pixels to offset the highlight from the left edge 
*   of the component 
*/ 
protected int calculateXOffset(JLabel component, Rectangle viewR, 
     Rectangle textR) { 
    int horizAlignment = component.getHorizontalAlignment(); 
    boolean leftToRight = component.getComponentOrientation() 
      .isLeftToRight(); 

    if (horizAlignment == SwingConstants.LEFT 
      || (horizAlignment == SwingConstants.LEADING && leftToRight) 
      || (horizAlignment == SwingConstants.TRAILING && !leftToRight)) { 
     return 0; 
    } else if (horizAlignment == SwingConstants.RIGHT 
      || (horizAlignment == SwingConstants.TRAILING && !leftToRight) 
      || (horizAlignment == SwingConstants.LEADING && leftToRight)) { 
     return viewR.width - textR.width; 
    } else if (horizAlignment == SwingConstants.CENTER) { 
     return (viewR.width - textR.width)/2; 
    } 
    throw new AssertionError("Unknown horizonal alignment " 
      + horizAlignment); 
} 
+0

必須是標準的Java6 API的可能,真的感謝 – mKorbel

3

通常的問題通過克列奧帕特拉」回覆的啓發,我什麼都試過什麼是可能的,或者知道,現在的結果是,她的例子調用我Pattern

enter image description here

貌似模式是quickiest,超過我的預期,這個代碼錯過了一些關於RowSorter的,它想知道如何做到這一點,快速輸出到GUI,

import java.awt.*; 
import java.util.Vector; 
import java.util.regex.Pattern; 
import javax.swing.*; 
import javax.swing.table.*; 

public class HiglightNumberValueInTableCell { 

    private String testS; 
    private JFrame frame = new JFrame("frameTitle"); 
    private JScrollPane tblS = new JScrollPane(); 
    private JTable tbl; 
    private Vector<String> rOrH; 
    private long t1 = 0L; 
    private long t2 = 0L; 

    public HiglightNumberValueInTableCell() { 
     t1 = System.currentTimeMillis(); 
     int regLenght = 25000; 
     int chars = 0; 
     AlphaChars aChars = new AlphaChars(); 
     testS = aChars.getNext(regLenght); 
     rOrH = new Vector<String>(); 
     Vector<Vector<String>> rowD = new Vector<Vector<String>>(); 
     for (int e = 0; e < regLenght;) { 
      chars++; 
      //if (chars > 50) { //one char in table cell 
      if (chars > 20) { 
       chars = 1; 
       rowD.add(rOrH); 
       rOrH = new Vector<String>(); 
      } 
      //String str = (testS.substring(e, (e + 1))).toString();//one char in table cell 
      String str = (testS.substring(e, (e + 5))).toString(); 
      if (str != null) { 
       rOrH.add(str); 
      } else { 
       rOrH.add(""); 
      } 
      //e++;//one char in table cell 
      e += 5; 
     } 
     rOrH = new Vector<String>(); 
     //for (int i = 0; i < 50; i++) {//one char in table cell 
     for (int i = 0; i < 20; i++) { 
      rOrH.add(String.valueOf(i + 1)); 
     } 
     tbl = new JTable(rowD, rOrH); 
     tblS = new JScrollPane(tbl, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, 
       ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
     tblS.setPreferredSize(new Dimension(1000, 403)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(tblS, BorderLayout.CENTER); 
     frame.setLocation(50, 50); 
     frame.pack(); 
     addColumnRenderes(); 
    } 

    private void addColumnRenderes() { 
     for (int i = 0; i < tbl.getColumnCount(); i++) { 
      RowColorRenderer rowRenderer = new RowColorRenderer(i); 
      TableColumn column = tbl.getColumnModel().getColumn(i); 
      column.setCellRenderer(rowRenderer); 
     } 
     Runnable doRun = new Runnable() { 

      @Override 
      public void run() { 
       showFrame(); 
      } 
     }; 
     SwingUtilities.invokeLater(doRun); 
    } 

    private void showFrame() { 
     Runnable doRun = new Runnable() { 

      @Override 
      public void run() { 
       frame.setVisible(true); 
       t2 = System.currentTimeMillis(); 
       System.out.println("miliSec:" + (t2 - t1)); //aver. 45 miliSec. 
      } 
     }; 
     SwingUtilities.invokeLater(doRun); 
    } 

    private class RowColorRenderer extends DefaultTableCellRenderer { 

     private static final long serialVersionUID = 1L; 
     private int colNo = 0; 

     RowColorRenderer(int col) { 
      colNo = col; 
     } 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, 
       boolean isSelected, boolean hasFocus, int row, int column) { 
      Component comp = super.getTableCellRendererComponent(table, value, 
        isSelected, hasFocus, row, column); 
      JComponent jc = (JComponent) comp; 
      if (!isSelected) { 
       if (table.getValueAt(row, colNo) != null) { 
        String str = table.getValueAt(row, colNo).toString(); 
        if (!str.isEmpty()) { 
         if (Pattern.compile("\\d").matcher(str).find()) { 
          if (((Pattern.compile("[02468]").matcher(str).find())) 
            && (!(Pattern.compile("[13579]").matcher(str).find()))) { 
           setForeground(Color.magenta); 
           setBackground(Color.orange); 
          } else if ((!(Pattern.compile("[02468]").matcher(str).find())) 
            && ((Pattern.compile("[13579]").matcher(str).find()))) { 
           setForeground(Color.blue); 
           setBackground(Color.yellow); 
          } else if (((Pattern.compile("[02468]").matcher(str).find())) 
            && ((Pattern.compile("[13579]").matcher(str).find()))) { 
           setForeground(Color.red); 
           setBackground(Color.cyan); 
          } 
          setFont(new Font("Serif", Font.BOLD, 12)); 
          setHorizontalAlignment(CENTER); 
         } else { 
          setBackground(table.getBackground()); 
          setForeground(table.getForeground()); 
          setFont(new Font("Serif", Font.PLAIN, 8)); 
          setHorizontalAlignment(CENTER); 
         } 
        } 
       } 
      } 
      return this; 
     } 
    } 

    private class AlphaChars { 

     public static final int MIN_LENGTH = 2000; 
     private java.util.Random rand = new java.util.Random(); 
     private char[] AlphaChars = { 
      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 
      'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 
      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 
      'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
      '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '+', '-', '*', '/', '<', '>', '&', 
      '#', '@', '{', '}', '?', ':', '_', '"', '!', ')', '('}; 

     public String getNext() { 
      StringBuilder strbuf = new StringBuilder(); 
      for (int i = 0; i < MIN_LENGTH; i++) { 
       strbuf.append(getAlphaChars()[getRand().nextInt(getAlphaChars().length)]); 
      } 
      return strbuf.toString(); 
     } 

     public String getNext(int reqLenght) { 
      StringBuilder strbuf = new StringBuilder(); 
      for (int i = 0; i < reqLenght; i++) { 
       strbuf.append(getAlphaChars()[getRand().nextInt(getAlphaChars().length)]); 
      } 
      return strbuf.toString(); 
     } 

     public java.util.Random getRand() { 
      return rand; 
     } 

     public void setRand(java.util.Random aRand) { 
      rand = aRand; 
     } 

     public char[] getAlphaChars() { 
      return AlphaChars; 
     } 

     public void setAlphaChars(char[] aAlphaChars) { 
      AlphaChars = aAlphaChars; 
     } 
    } 

    public static void main(String args[]) { 
     HiglightNumberValueInTableCell hnvit = new HiglightNumberValueInTableCell(); 
    } 
} 
+0

+1這個例子強調'JTable'渲染器,它使用[輕量級模式]的速度優勢(http://en.wikipedia.org/維基/ Flyweight_pattern)。 – trashgod

相關問題