2011-01-31 9 views
6

Próbuję przesłonić kolor podświetlania tabeli JX w oparciu o wartość niektórych elementów wiersza. Oto przykład, w którym wyróżnienie jest zielone, jeśli wartość pozycji wiersza ma wartość getNumber() % 2 == 0.Swing: renderowanie komórki tabeli nie działa poprawnie w JXTable?

Działa poprawnie dla JTable, ale dla JXTable wygląda na to, że renderer komórki tabeli nie działa, chyba że wybrane są wiersze. Dlaczego zachowuje się w ten sposób i jak mogę to naprawić?

enter image description hereenter image description here

import java.awt.Color; 
import java.awt.Component; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.DefaultTableCellRenderer; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableColumnModel; 
import org.jdesktop.swingx.JXTable; 
import ca.odell.glazedlists.BasicEventList; 
import ca.odell.glazedlists.EventList; 
import ca.odell.glazedlists.SortedList; 
import ca.odell.glazedlists.gui.TableFormat; 
import ca.odell.glazedlists.swing.EventTableModel; 

public class TableRendererExample { 
    static public enum ItemKey { 
     NAME("name") { 
      @Override public String getStringFromItem(Item item) { 
       return item.getName(); 
      } 
     }, 
     NUMBER("#") { 
      @Override public String getStringFromItem(Item item) { 
       return Integer.toString(item.getNumber()); 
      } 
     }, 
     PARENT("parent") { 
      @Override public String getStringFromItem(Item item) { 
       Item p = item.getParent(); 
       return (p == null) ? null : p.getName(); 
      }   
     }; 

     final private String name; 
     ItemKey(String name) { this.name = name; } 
     public String getName() { return this.name; } 
     abstract public String getStringFromItem(Item item); 

     static private ItemKey[] columns = { NAME, NUMBER, PARENT }; 
     static public ItemKey[] getColumns() { return columns; } 
    } 
    static public class ItemTableFormat implements TableFormat<Item> { 
     @Override public int getColumnCount() { 
      return ItemKey.getColumns().length; 
     } 
     @Override public String getColumnName(int col) { 
      return ItemKey.getColumns()[col].getName(); 
     } 
     @Override public Object getColumnValue(Item item, int col) { 
      return ItemKey.getColumns()[col].getStringFromItem(item); 
     }  
    } 

    static class Item { 
     final private String name; 
     final private int number; 
     final private Item parent; 

     private Item(String name, int number, Item parent) { 
      this.name=name; this.number=number; this.parent=parent; 
     } 
     static public Item create(String name, int number, Item parent) { 
      return new Item(name, number, parent); 
     } 

     public String getName() { return this.name; } 
     public int getNumber() { return this.number; } 
     public Item getParent() { return this.parent; } 
    } 

    static public void main(String[] args) 
    { 

     EventList<Item> items = new BasicEventList<Item>(); 
     Item x1,x2,x3,x4; 
     x1 = Item.create("foo", 1, null); 
     items.add(x1); 
     x2 = Item.create("bar", 2, x1); 
     items.add(x2); 
     x3 = Item.create("baz", 1, x1); 
     items.add(x3); 
     x4 = Item.create("quux", 4, x2); 
     items.add(x4); 
     items.add(Item.create("wham", 3, x3)); 
     items.add(Item.create("blam", 11, x3)); 
     items.add(Item.create("shazaam", 20, x3)); 
     items.add(Item.create("August", 8, x4)); 
     items.add(Item.create("September", 9, x4)); 
     items.add(Item.create("October", 10, x4)); 
     items.add(Item.create("November", 11, x4)); 
     items.add(Item.create("December", 12, x4)); 

     EventList<Item> sortedItems = new SortedList<Item>(items, null); 
     final EventList<Item> displayList = sortedItems; 
     doit(new JTable(), "JTable cell renderer", displayList); 
     doit(new JXTable(), "JXTable cell renderer", displayList); 
    } 

    static public void doit(JTable table, String title, 
     final EventList<Item> displayList) 
    { 
     TableFormat<Item> tf = new ItemTableFormat(); 
     EventTableModel<Item> etm = 
      new EventTableModel<Item>(displayList, tf); 

     table.setModel(etm);  
     if (table instanceof JXTable) 
     { 
      ((JXTable)table).setColumnControlVisible(true); 
     } 
     TableColumnModel tcm = table.getColumnModel(); 
     final Color selectedGreen = new Color(128, 255, 128); 
     final Color unselectedGreen = new Color(224, 255, 224); 
     TableCellRenderer tcr = new DefaultTableCellRenderer() { 
      @Override public Component getTableCellRendererComponent(
        JTable table, Object value, 
        boolean isSelected, boolean hasFocus, 
        int row, int column) 
      { 
       Component c = super.getTableCellRendererComponent(
         table, value, isSelected, hasFocus, row, column); 
       Item item = displayList.get(row); 
       Color color = null; 
       if (item != null && ((item.getNumber() % 2) == 0)) 
       { 
        color = isSelected ? selectedGreen : unselectedGreen; 
       } 
       if (color == null) 
       { 
        color = isSelected 
         ? table.getSelectionBackground() 
         : table.getBackground(); 
       } 
       c.setBackground(color);          
       return c; 
      } 
     }; 
     for (int i = 0; i < tcm.getColumnCount(); ++i) 
     { 
      tcm.getColumn(i).setCellRenderer(tcr); 
     } 

     JPanel panel = new JPanel(); 
     panel.add(new JScrollPane(table)); 

     JFrame frame = new JFrame(title); 
     frame.getContentPane().add(panel); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     frame.pack(); 
    } 
} 

Odpowiedz

3

Dostałem odpowiedź od jednego z ludzi SwingX który powiedział, że muszę użyć Markera (zamiast TableCellRenderer) dla renderers zachowywać się poprawnie.

Było to hacky, ale nie polecił go.

+1

Dla kompletności: The hacky obejście jest: 'JXTable.putClientProperty (JXTable.USE_DTCR_COLORMEMORY_HACK, null)' – Kai

+0

W moim kodu ustawić go na 'FALSE:' table.putClientProperty (JXTable.USE_DTCR_COLORMEMORY_HACK, false); '. Działa dobrze. – Benj