2016-04-15 8 views
1

Ich versuche PreparateRenderer-Komponente mit benutzerdefinierten Cell-Renderer zu verwenden. Die Idee besteht darin, die gesamte Zeile mithilfe von prepareRenderer und zellenwertbasierten Anpassungen mit dem Customer CellRenderer zu zeichnen.Können wir die preparateRenderer-Komponente und den benutzerdefinierten Cell-Renderer zusammen verwenden?

preparateRenderer funktioniert wie erwartet, indem die gesamte Zeile hervorgehoben wird, aber die Zelle, die vom benutzerdefinierten CellRenderer hervorgehoben wird, zeigt keine Farbe an, wenn sie nicht ausgewählt wird. Das benutzerdefinierte CellRendering scheint nur an der Zellenauswahl zu arbeiten (wobei die Zelle hervorgehoben wird, die 1 enthält, aber nur bei der Auswahl).

http://i.stack.imgur.com/NGGvc.png

Alle Ideen, wie in Hand arbeiten beide Hand zu machen?

Code unten, um das Problem zu reproduzieren.

[![import javax.swing.*; 
import javax.swing.table.DefaultTableCellRenderer; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableModel; 
import java.awt.*; 

public class SortTableWithColors_ extends JFrame { 
    public static void main(String\[\] args) { 
     SortTableWithColors_ frame = new SortTableWithColors_(); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public SortTableWithColors_() { 
     Object\[\] columnNames = {"B", "C"}; 
     Object\[\]\[\] data = {{new Integer(1), new Integer(4)}, 
       {new Integer(2), new Integer(5)}, 
       {new Integer(3), new Integer(3)}, 
       {new Integer(4), new Integer(1)}}; 
     // table model 
     DefaultTableModel model = new DefaultTableModel(data, columnNames); 

     // set table model in Jtable 
//  JTable table = new JTable(model); 
     NewJTable table = new NewJTable(model); 
     table.setAutoCreateRowSorter(true); 
     getContentPane().add(new JScrollPane(table)); 

     // Tell the table what to use to render our columns 
     for (int i = 0; i < 2; i++) { 
      table.getColumnModel().getColumn(i).setCellRenderer(new NewRenderer()); 
     } 
    } 

    // Custom Renderer 
    public class NewRenderer extends DefaultTableCellRenderer { 
     @Override 
     public Component getTableCellRendererComponent 
       (JTable table, Object value, boolean isSelected, 
       boolean hasFocus, int row, int column) { 
      JLabel cell = (JLabel) super.getTableCellRendererComponent 
        (table, value, isSelected, hasFocus, row, column); 

      int rowModel = (int) table.convertRowIndexToModel(row); 
      int colModel = (int) table.convertColumnIndexToModel(column); 
      int rowView = (int) table.convertRowIndexToView(row); 
      int colView = (int) table.convertColumnIndexToView(column); 

      // set color 
//   cell.setBackground(new Color(0xFFFFFF)); 
//   cell.setForeground(new Color(0x000000)); 

      //set selection colors 
      if (isSelected) { 
       cell.setBackground(new Color(0x4AC3FF)); 
       cell.setForeground(new Color(0x000000)); // AM 
      } 
      // Selective cell colouring based on value 

      // paint cells 
      int val = (int) value; 
      if (val == 1) { 
       cell.setBackground(Color.GREEN); 
      } 
      return cell; 
     } 
    } 

    public class NewJTable extends JTable { 
     public NewJTable(TableModel model) { 
      super(model); 
     } 

     public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { 
      Component c = super.prepareRenderer(renderer, row, column); 
      // Color row based on a cell value 
      if (!isRowSelected(row)) { 
       c.setBackground(getBackground()); 
       int modelRow = convertRowIndexToModel(row); 
       int val = (int) getModel().getValueAt(modelRow, 0); 
       if (val == 3) { 
        c.setBackground(Color.YELLOW); 
       } 
      } 
      return c; 

     } 
    } 
}] 
+0

In der Theorie, ja, aber Sie werden wahrscheinlich feststellen, dass Sie ständig Änderungen vornehmen müssen, wie der 'prepareRenderer' ändert, was der' TableCellRenderer' wollte, basierend auf den Daten – MadProgrammer

+1

Für eine nette kleine Tirade über das Thema, Du könntest dir [dies] (http://stackoverflow.com/questions/25279727/java-abstracttablemodel-2- different-color-for-each-row/25279954#25279954) ansehen, es ist keine "perfekte" Lösung , aber es ist ein Schritt in eine bessere Richtung, mit einigen ordentlichen Nebenwirkungen;) – MadProgrammer

+0

Das ist hilfreich und eine Menge Denkanstöße. Ich mag die Idee, Jviewport zum Rendern zu verwenden. – Amit

Antwort

1

Versuchen Sie nicht, zwei Dinge gleichzeitig zu tun. Sie müssen das Rendering logisch in zwei Schritte unterteilen.

Der Renderer-Code wird vor dem Prepare-Renderer-Code ausgeführt. So:

  1. Zuerst müssen Sie den Renderer so arbeiten lassen, wie Sie möchten, dass er funktioniert.

  2. Dann zweitens Sie die Standard-Wiedergabe aufheben, indem Sie die Zeile markieren den Wert 3.

Der entscheidende Punkt enthält, wenn der Hintergrund in Ihrem Renderer zu ändern ist, dass Sie es immer auf den Standardwert zurückgesetzt muss vor Anpassungen vornehmen.

So in der Rendering-Code, den Sie Ihren Kommentar gesetzt Linien müssen:

// set color (ie. restore the default values) 
cell.setBackground(new Color(0xFFFFFF)); 
cell.setForeground(new Color(0x000000)); 

Dann in der prepareRenderer Sie brauchen nicht den Hintergrund zurückgesetzt, nur ändern, wenn Ihre Bedingung erfüllt ist:

// get rid of this, the default has already been set. 
// this code should only provide the override 
//c.setBackground(getBackground()); 

Hinweis: Dies funktioniert nur, wenn Sie einen benutzerdefinierten Renderer für alle Spalten haben, der den Hintergrund auf den Standard zurücksetzt. Da wir die obige Anweisung auskommentieren müssen, liegt es nun in der Verantwortung jedes Renderers, den Hintergrund zurückzusetzen.

+0

@amit, hat dies Ihre Frage nicht beantwortet? – camickr

+0

@ camickr. Ja, tat es. Entschuldigung für verspätete Antwort. Ich habe Jviewport route wie von MadProgrammer vorgeschlagen implementiert. Aber stimme deinen hilfreichen Kommentaren zu. – Amit