2011-11-03 35 views
0

如果至少有一個值(RowFilter中的值==值,條目中的值)是小數,則會發生此情況。下面是一個失敗的測試:RowFilter.NumberFilter:無法處理「混合」具體數字類型

@Test 
public void testRowFilterNumberMixCore() { 
    TestEntry entry = new TestEntry(1.2f); 
    RowFilter filter = RowFilter.numberFilter(ComparisonType.AFTER, 1, 0); 
    assertTrue(entry + "must be included " + filter, filter.include(entry)); 
} 

輸出是:

 
junit.framework.AssertionFailedError: 
[entry: 1.2] must be included [RowFilter: ComparisonType = AFTER, comparableValue: 1, comparableClass: class java.lang.Integer] 

的原因是,NumberFilter回落至其number.longValue()比較的數字,如果他們不是同一類(通過那相媲美)

瞭解詳細信息,測試失敗並不驚人(在後視,將永遠不會認爲這是一個問題;-)一個層面的防禦是確保 - 在客戶端代碼 - 表示要比較的數字是同一班的。這並不總是可能的(想想f.i .:一個tableColumn與columnClass數字)所以我想知道是否/如何改善後備。喜歡的東西:

if (one instanceof Comparable && one.getClass() == other.getClass()) { 
    // same class, use comparator 
    return ((Comparable) one).compareTo(other); 
} 
if (areIntegers(one, other)) { 
    // all integers, use longValue 
    return longCompare(one, other); 
} 
if (areDecimals(one, other)) { 
    // anything to do here? 
} 
// at last resort convert to BigDecimal and compare those: 
BigDecimal bigOne = new BigDecimal(one.toString()); 
BigDecimal bigOther = new BigDecimal(other.toString()); 
return bigOne.compareTo(bigOther); 

這樣做,使得測試合格 - 我有點警惕隱藏(讀:未知我:)陷阱。任何警告/備選方案都非常受歡迎!

FYI:跨張貼到OTN's Swing forum

後續

實現正如上文所述,現在正在等待客戶抱怨 - 在這種情況下將手指點大家誰沒有提醒我這裏:-)

+0

我可以看到嗎? http://stackoverflow.com/questions/6187566/problem-formatting-fields-in-a-jtable-differences-between-integer-and-double ???或不是 – mKorbel

+0

@mKorbel - 感謝您的鏈接。看起來有點不相關,如果我正確地理解了這個問題:如果列類與getColumnClass中保證的類不同,格式化程序會發出聲音。我認爲這是非常值得期待的。這裏歸結爲純數比較,表只在後臺(自然是一個明顯的目標區域:-) – kleopatra

回答

2

只是把這個結束(目前,高高興興地將重新打開,如果其他的答案/評論調高:-) - 解決如問題概述。

感謝您的關注!

3

我沒有更好的答案,但下面的例子說明了效果。具體而言,基於double原語的RowFilterboxed,作爲Double,產生具有values > 1的預期畫面。相反,基於float的那個被裝箱爲Float。由於類文字不匹配,因此include()會比較long值,意外過濾所有分數values < 2

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.util.Arrays; 
import javax.swing.AbstractAction; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.JToggleButton; 
import javax.swing.RowFilter; 
import javax.swing.RowFilter.ComparisonType; 
import javax.swing.table.AbstractTableModel; 
import javax.swing.table.TableRowSorter; 

/** @see http://stackoverflow.com/questions/7993546 */ 
public class FilterTest { 

    private static TableRowSorter<TableModel> sorter; 
    private static RowFilter<TableModel, Integer> dFilter; 
    private static RowFilter<TableModel, Integer> fFilter; 
    private static boolean b; 

    public static void main(String[] args) { 
     TableModel model = new TableModel(); 
     JTable table = new JTable(model); 
     sorter = new TableRowSorter<TableModel>(model); 
     dFilter = RowFilter.numberFilter(ComparisonType.AFTER, 1d, 0); 
     fFilter = RowFilter.numberFilter(ComparisonType.AFTER, 1f, 0); 
     sorter.setRowFilter(dFilter); 
     table.setRowSorter(sorter); 
     JScrollPane scrollPane = new JScrollPane(table); 
     table.setPreferredScrollableViewportSize(new Dimension(320, 240)); 

     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(scrollPane, BorderLayout.CENTER); 
     f.add(new JToggleButton(new AbstractAction("Toggle") { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       b = !b; 
       if (b) { 
        sorter.setRowFilter(fFilter); 
       } else { 
        sorter.setRowFilter(dFilter); 
       } 
      } 
     }), BorderLayout.SOUTH); 

     f.pack(); 
     f.setVisible(true); 
    } 

    private static class TableModel extends AbstractTableModel { 

     private static final int ROWS = 16; 
     private static final int COLS = 4; 
     private Double[][] matrix = new Double[ROWS][COLS]; 

     public TableModel() { 
      double v = 0; 
      for (Object[] row : matrix) { 
       Arrays.fill(row, Double.valueOf(v += 0.25)); 
      } 
     } 

     @Override 
     public int getRowCount() { 
      return ROWS; 
     } 

     @Override 
     public int getColumnCount() { 
      return COLS; 
     } 

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

     @Override 
     public Class<?> getColumnClass(int col) { 
      return Number.class; 
     } 
    } 
} 
+0

發佈sscce +1 – mKorbel

+0

是的,這就是客戶端客戶端檢測到的效果順便說一句,不相關裝箱或不,只是爲了澄清。感謝sscce! – kleopatra

相關問題