2011-04-14 4 views
1

Je rencontre des problèmes pour implémenter un rendu de cellule personnalisé qui encapsulera le contenu d'un message lorsqu'il dépasse une ligne de longueur. Ce qui suit est ce que j'ai:Line Wrapping Cell Renderer - Java

public class MessageTable extends JTable 
{ 

    private static MessageTable messageTable; 
    private DefaultTableModel model = new DefaultTableModel(); 
    private String[] emptyData = {}; 
    private TreeMap<Integer, String> messages = null; 

    public class LineWrapCellRenderer extends JTextArea implements TableCellRenderer { 

     @Override 
     public Component getTableCellRendererComponent(
         JTable table, 
         Object value, 
         boolean isSelected, 
         boolean hasFocus, 
         int row, 
         int column) { 
       this.setText((String)value); 
       this.setWrapStyleWord(true);      
       this.setLineWrap(true);  

       this.setBackground(Color.YELLOW); 

       int fontHeight = this.getFontMetrics(this.getFont()).getHeight(); 
       int textLength = this.getText().length(); 
       int lines = textLength/this.getColumns() +1;//+1, because we need at least 1 row.      
       int height = fontHeight * lines;       
       table.setRowHeight(row, height); 
       return this; 
     } 
    } 

    public MessageTable() 
    { 
     super(); 
     messageTable = this; 
     this.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);  

     model.addColumn("Message Number", emptyData); 
     model.addColumn("Message Content", emptyData); 

     this.setModel(model); 
     this.setFont(MappingView.theFont); 

     this.setDefaultRenderer(String.class, new LineWrapCellRenderer()); 
    } 

    /** 
    * Set the current messages. 
    * @param messages 
    */ 
    public void setCurrentMessages(TreeMap<Integer, String> messages) 
    { 
     clearCurrentMessages(); 

     this.messages = messages; 

     if (messages != null) 
     { 
      for (Integer key : messages.keySet()) 
      { 
       String[] row = { key.toString(), messages.get(key).toString() }; 
       model.addRow(row); 
      } 
     } 
    } 

Pour une raison quelconque, le LineWrapCellRenderer est jamais utilisé et les lignes ne contiennent jamais une ligne de texte.

Qu'est-ce que je fais mal?

+1

attention: tous les paramètres passés dans getXXRendererComponent (..) sont strictement en lecture seule! En d'autres termes: ne jamais en changer si ses propriétés – kleopatra

Répondre

1

Votre CellRenderer n'est pas utilisé parce que le modèle de table par défaut retourne Object.class pour une colonne (il ne l'emportait pas sur la mise en œuvre de AbstractTableModel):

public Class<?> getColumnClass(int columnIndex) { 
    return Object.class; 
} 

Donc, soit remplacer la méthode vous pour le modèle ou affecter le moteur de rendu à Object.class.

+1

Je crois que ce que vous vouliez dire est de changer this.setDefaultRenderer (String.class, new LineWrapCellRenderer()); à this.setDefaultRenderer (Object.class, new LineWrapCellRenderer()), cependant quand j'ai essayé ceci, j'obtiens une erreur de division par 0 sur la ligne: int lines = textLength/this.getColumns() +1; Pourquoi cela serait-il? – user632906

+1

Vous ne définissez jamais le nombre de colonnes (JTextArea.setColumns (...)). Ainsi, il renvoie toujours zéro et donne une division par zéro. – Howard