2012-03-24 11 views
14

Auch von mir gelesen und Testantworten @kleopatraSo verwenden Renderer für Tableheader

enter image description here

enter image description here

enter image description here

von 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

Und was ist das Problem, das Sie haben? Das SSCCE funktioniert gut für mich. –

+0

@Jakub Zaverka vielleicht gibt es kein Problem mit Render, wahr ist, habe ich Probleme mit ArraysXxxException von implementiert Renderer von (@kleopatra) – mKorbel

+0

EDIT entfernt use_less RowSorter – mKorbel

Antwort

0

Ich hatte mir dies in der Vergangenheit geschehen, und ich war überzeugt, dass es mit der Zelle Renderer zu tun hatte, aber die ArraysXxxException Art von Ausnahmen mir gejagt, weil ich unselect vergessen hatte und stoppen die Zelle Bearbeitung vor der Zugabe/Zeilen entfernen Sie sollten versuchen clearSelection() und table.getCellEditor().stopCellEditing(); auf Ihrem JTable vor dem Entfernen/Hinzufügen und sehen, ob das Ihr Problem löst.

Erstens natürlich, stellen Sie sicher, es ist die Bearbeitung:

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

Meiner Erfahrung nach ist es besser, die DefaultTableCellHeaderRenderer zu erhalten, wenn Sie irgendwelche JTableRenderer überschreiben. Also, anstatt mit der JLabel von der Renderer direkt zu mischen, greifen Sie die Renderer mit super(). Also, sollten Sie den Code wie folgt aussehen:

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; 
    } 
}); 

Um zu versuchen, Ihre Fragen direkt zu beantworten:

Frage 1:

Q: Wie verwende Kunde Renderer ich richtig spezifischen Zellen zu malen in einer JTabelle?

A: Ihr aktueller Code ist ein Renderer auf dem JTableHeader. Um einen Renderer auf Tabellenzellen hinzufügen würde ein ähnlicher Code zu dem, was oben ist, nur würden Sie es durch die Spalte Modell gesetzt:

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

}); 

Hinweis dazu: JTables sind spaltenbasierte, was bedeutet, dass alle Daten, in einer bestimmten Spalte muss der gleiche Typ sein (Ihr SSCCE folgt dieser Konvention). Meine Lieblingsaufgabe ist es, eine benutzerdefinierte Renderer für jeden Typ bereitzustellen.Zum Beispiel, wenn ich eine Date Spalte haben, verwende ich diese Renderer:

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

Und ich nenne diesen Code mit etwas ähnliches:

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

Frage 2:

Q: particular eine Tabelle Header Farbe Java Swing

A: Umm .. Ihr SSCCE scheint es herausgefunden zu haben.

Frage 3:

F: über super.getTableCellRendererComponent (...) letzte Codezeile vor Rückkehr sein muss, ich bin nicht in der Lage von jenem Vorschlag richtig Renderer zu schreiben, für mich nur das funktioniert Weg

A: Ich bin mir nicht sicher, was du meinst "muss die letzte Codezeile sein, bevor es zurückkehrt." Das ist nicht der Fall ist, durch den Code bewiesen schnippeln ich oben

gab

Frage 4:

Q: JLabel hinzugefügt wird für Borders, Horizontal und Vordergrund, vor allem Hintergrund hat mir ein paar non_senses durch Verwendung von Komponenten statt von JLabel, (nicht wichtig hier irgendwie)

A: Ok ... die DefaultTableCellHeaderRenderer ist ausreichend für all diese, Grenzen, Ausrichtung, Vordergrund und Hintergrund.

+0

nicht über +1 gemeldet – mKorbel