2012-03-24 15 views
14

Nawet Czytam i odpowiedziach testowych przez @kleopatraJak korzystać Renderer na TableHeader

enter image description here

enter image description here

enter image description here

od SSCCE

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.table.*; 

public class SelectedTableHeader { 

    private JFrame frame = new JFrame("Table Demo"); 
    private JTableHeader header; 
    private Object selectedColumn = null; 
    private String[] columnNames = {"String", "Integer", "Float", "Double", "Locale & Double", "Boolean"}; 
    private Object[][] data = { 
     {"aaa", new Integer(12), new Float(12.15), new Double(100.05), new Double(12.05), true}, 
     {"bbb", new Integer(5), new Float(7.154), new Double(6.1555), new Double(417.55), false}, 
     {"CCC", new Integer(92), new Float(0.1135), new Double(3.1455), new Double(11.05), true}, 
     {"ddd", new Integer(12), new Float(31.15), new Double(10.05), new Double(23.05), true}, 
     {"eee", new Integer(5), new Float(5.154), new Double(16.1555), new Double(17.55), false}, 
     {"fff", new Integer(92), new Float(4.1135), new Double(31.1455), new Double(3.05), true}}; 
    private TableModel model = new DefaultTableModel(data, columnNames) { 

     private static final long serialVersionUID = 1L; 

     @Override 
     public Class<?> getColumnClass(int column) { 
      return getValueAt(0, column).getClass(); 
     } 
    }; 
    private JTable table = new JTable(model); 

    public SelectedTableHeader() { 
     header = table.getTableHeader(); 
     header.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       JTableHeader h = (JTableHeader) e.getSource(); 
       int i = h.columnAtPoint(e.getPoint()); 
       Object o = h.getColumnModel().getColumn(i).getHeaderValue(); 
       if (i < 0) { 
        selectedColumn = null; 
        return; 
       } 
       selectedColumn = o; 
       h.requestFocusInWindow(); 
      } 
     }); 
     final TableCellRenderer hr = table.getTableHeader().getDefaultRenderer(); 
     header.setDefaultRenderer(new TableCellRenderer() { 

      private JLabel lbl; 

      @Override 
      public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
       if (selectedColumn == value) { 
        lbl = (JLabel) hr.getTableCellRendererComponent(table, value, true, true, row, column); 
        lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createLineBorder(Color.red, 1))); 
        lbl.setHorizontalAlignment(SwingConstants.LEFT); 
       } else { 
        lbl = (JLabel) hr.getTableCellRendererComponent(table, value, false, false, row, column); 
        lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0))); 
        lbl.setHorizontalAlignment(SwingConstants.CENTER); 
       } 
       if (column == 0) { 
        lbl.setForeground(Color.red); 
       } else { 
        lbl.setForeground(header.getForeground()); 
       } 
       /*return (value == selectedColumn) ? hr.getTableCellRendererComponent(
       table, value, true, true, row, column) : hr.getTableCellRendererComponent(
       table, value, false, false, row, column);*/ 
       return lbl; 
      } 
     }); 
     table.setRowHeight(20); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     JScrollPane scroll = new JScrollPane(table); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(scroll); 
     frame.pack(); 
     frame.setLocation(150, 150); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       SelectedTableHeader selectedTableHeader = new SelectedTableHeader(); 
      } 
     }); 
    } 
} 
+0

A jaki masz problem? SSCCE działa dobrze dla mnie. –

+0

@Jakub Zaverka być może nie ma problemu z Render, prawda jest, że mam problemy z ArraysXxxException przez implementacje Renderer przez (@kleopatra) – mKorbel

+0

EDIT usunięto use_less RowSorter – mKorbel

Odpowiedz

0

miałem to się ze mną w przeszłości i byłem przekonany, że miał do czynienia z renderujący komórki, ale ArraysXxxException rodzaj Wyjątki polować mnie, bo zapomniał unselect i zakończyć edycję komórka przed dodaniem/usuwanie wierszy. Powinieneś wypróbować clearSelection() i table.getCellEditor().stopCellEditing(); na swoim JTable przed usunięciem/dodaniem i zobaczyć, czy to rozwiąże twój problem.

Po pierwsze, oczywiście, upewnij się, że edytuje:

if (table.isEditing()) { 
    table.getCellEditor().stopCellEditing(); 
} 
4

Z mojego doświadczenia wynika, że ​​lepiej, aby uzyskać DefaultTableCellHeaderRenderer kiedy nadpisać dowolny JTableRenderer. Zamiast więc ingerować w JLabel bezpośrednio z Renderer, można pobrać Renderer z super(). Tak, Twój kod powinien wyglądać tak:

header.setDefaultRenderer(new DefaultTableCellHeaderRenderer() { 


    @Override 
    public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     DefaultTableCellHeaderRenderer rendererComponent = (DefaultTableCellHeaderRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 

     if (selectedColumn == value) { 
      rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createLineBorder(Color.red, 1))); 
      rendererComponent.setHorizontalAlignment(SwingConstants.LEFT); 
     } else { 
      rendererComponent.setBorder(BorderFactory.createCompoundBorder(rendererComponent.getBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 0))); 
      rendererComponent.setHorizontalAlignment(SwingConstants.CENTER); 
     } 
     if (column == 0) { 
      rendererComponent.setForeground(Color.red); 
     } else { 
      rendererComponent.setForeground(header.getForeground()); 
     } 

     return rendererComponent; 
    } 
}); 

Aby spróbować odpowiedzieć na Twoje pytania bezpośrednio:

Pytanie 1:

Q: Jak prawidłowo używać renderujące klientów malować specyficznych komórek w JTable?

A: Twój obecny kod ustawia Renderer na JTableHeader. Aby dodać Renderer na swoich komórkach tabeli byłby podobny kod do tego, co powyżej, tylko chcesz ustawić go przez model Kolumna:

table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() { 
    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 

     // Set your code to render your component. 

     return renderer; 
    } 

}); 

notatkę o tym: JTables są kolumny oparte, co oznacza, że ​​wszystkie dane w pewnej kolumnie musi być tego samego typu (twoja SSCCE podąża za tą konwencją). Moją ulubioną rzeczą jest dostarczenie niestandardowego Renderer dla każdego typu.Na przykład, kiedy mam kolumnę Date, używam tego renderujący:

import java.awt.Component; 
import javax.swing.JTable; 
import javax.swing.table.DefaultTableCellRenderer; 
import org.joda.time.LocalDate; 

/** 
* 
* @author Ryan 
*/ 
public class DateCellRenderer extends DefaultTableCellRenderer { 

    String pattern; 
    public DateCellRenderer(String pattern){ 
     this.pattern = pattern; 
    } 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     DefaultTableCellRenderer renderer = (DefaultTableCellRenderer)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
     if (value != null && value instanceof LocalDate) { 
      renderer.setText(((LocalDate)value).toString(pattern)); 
     } else 
      throw new IllegalArgumentException("Only supported Object type is LocalDate."); 

     return renderer; 
    } 
} 

i wzywam ten kod z czymś podobnym:

table.getColumn("Date Entered").setCellRenderer(new DateCellRenderer("MMM dd, yyyy")); 

Pytanie 2:

Q: szczególny jeden nagłówek tabeli kolor java huśtawka

A: Umm .. Wydaje się, że Twój SSCCE to wymyślił.

Pytanie 3:

Q: o super.getTableCellRendererComponent (...) musi być ostatni wiersz kodu przed zwrotów, nie jestem w stanie napisać poprawny Renderer przez tych sugestii, dla mnie to działa tylko sposób

A: Nie jestem pewien, co masz na myśli "musi to być ostatnia linia kodu przed zwrotem". To nie jest przypadek, sprawdzone przez kod ciach dałem powyżej

Pytanie 4:

Q: JLabel dodaje do granic, horizontalAlignment i nowej wiedzy, zwłaszcza Tło spowodowane mi kilka non_senses za pomocą komponentu zamiast JLabel (nie ważne tutaj jakoś)

A: Ok ... DefaultTableCellHeaderRenderer jest wystarczający dla wszystkich, granic, wyrównania, pierwszego planu i tła.

+0

nie powiadomiono o +1 – mKorbel

Powiązane problemy