2016-09-07 18 views
0

我已經嘗試修改表格單元格大小,特別是preferredSize()。高度代碼,它只是結束了太高或不會去多行。JTable單元太高? CustomTableCellRenderer

所有我想要做的就是讓細胞適應的內容和我一直在這樣做了三個小時> _ <

FYI這是一個多細胞呈現。謝謝! 這裏是我的代碼:

package testpackage; 
import java.awt.CardLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Insets; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.JTextArea; 
import javax.swing.event.ListSelectionEvent; 
import javax.swing.event.ListSelectionListener; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableCellRenderer; 

public class TestRender extends JFrame { 

    public TestRender() { 
     JTable jTable1 = new JTable(){ 
      @Override 
      public boolean isCellEditable(int row, int col){ 
       return true; 
      } 
     }; 

     jTable1.setModel(new DefaultTableModel(
      new Object [][] { 
       {"asdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasdasd", null, null, null} 
      }, 
      new String [] { 
       "Title 1", "Title 2", "Title 3", "Title 4" 
      } 
     )); 

     jTable1.setDefaultRenderer(Object.class, new TextWrapCellRenderer()); 

     for (int row = 0; row < jTable1.getRowCount(); row++){ 
      int rowHeight = jTable1.getRowHeight(); 

      for (int column = 0; column < jTable1.getColumnCount(); column++){ 
       Component comp = jTable1.prepareRenderer(jTable1.getCellRenderer(row, column), row, column); 
       rowHeight = Math.max(rowHeight, comp.getPreferredSize().height); 
      } 

      jTable1.setRowHeight(row, rowHeight); 
     } 

     jTable1.getSelectionModel().addListSelectionListener(new ListSelectionListener() { 
      @Override 
      public void valueChanged(ListSelectionEvent e) { 
       System.out.println(jTable1.getValueAt(jTable1.getSelectedRow(), 0).toString()); 
      } 
     }); 

     getContentPane().setLayout(new CardLayout()); 
     getContentPane().add(new JScrollPane(jTable1)); 
     this.setExtendedState(JFrame.MAXIMIZED_BOTH); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


    } 

    public static void main(String args[]) { 
     new TestRender().show(); 
    } 
} 
class TextWrapCellRenderer extends JTextArea implements TableCellRenderer { 
    private static final long serialVersionUID = 1L; 

    public TextWrapCellRenderer() { 
     setLineWrap(true); 
     setWrapStyleWord(true); 
     setSelectionColor(Color.GREEN); 
    } 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     setText((String)value); 
     setSize(table.getColumnModel().getColumn(column).getWidth(),this.getPreferredSize().height); 
     setSelectionColor(Color.GREEN); 

     if (isSelected){ 
      setBackground(table.getSelectionBackground()); 
      setForeground(table.getSelectionForeground()); 
     }else{ 
      setBackground(table.getBackground()); 
      setForeground(table.getForeground()); 
     } 
     return this; 
    } 
} 

Here's what it looks like right now

更新1: 添加一個實例行如預期將產生多效應。但行高仍然過高,留下空白。

UPDATE 2: 通過運行時添加行不會產生多行效果,而是顯示爲標準行。

btn.addActionListener((ActionEvent e)->{ 
      Object[] row = {null,"uydfaiywhdfwaywefgihaasdfadsfadsfadfasdfasdfasdfasdfadsfasdfadsfasdfadsfasdfasdfasdfadsfjewfkuaywehfijlawkhrfuioaewjfhygkualiowjkharlufih",null,null}; 
      ((DefaultTableModel)jTable1.getModel()).addRow(row); 
     }); 

編輯3

我改變了我的TableCellRenderer此:

public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) { 

     if (isSelected) { 
      setForeground(table.getSelectionForeground()); 
      setBackground(table.getSelectionBackground()); 
     }else{ 
      setForeground(table.getForeground()); 
      setBackground(table.getBackground()); 
     } 
     setFont(table.getFont()); 

     if (hasFocus) { 
      setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); 
      if (table.isCellEditable(row, column)) { 
       setForeground(UIManager.getColor("Table.focusCellForeground")); 
       setBackground(UIManager.getColor("Table.focusCellBackground")); 
      } 
     } else { 
      setBorder(new EmptyBorder(1, 2, 1, 2)); 
     } 
     setText((value == null) ? "" : value.toString()); 
     int x = this.getLineCount(); 
     table.setRowHeight(row, x); 
     return this; 
    } 

瞄準渲染器將改變基於JTextArea中的行高度。但似乎該行的高度變成了零。也許我把它放在錯誤的塊?我需要每行的高度取決於jtextarea中的行數。

UPDATE 4 仍然是死路一條。

import javax.swing.JTable; 
import javax.swing.JTextArea; 
import javax.swing.event.TableModelEvent; 
import javax.swing.event.TableModelListener; 
import javax.swing.table.DefaultTableModel; 

public class NewJFrame2 extends javax.swing.JFrame { 
    MultiLineTableCustomizer mltc = new MultiLineTableCustomizer(); 
    public NewJFrame2() { 
     initComponents(); 
    } 

    @SuppressWarnings("unchecked")    
    private void initComponents() { 

     jScrollPane1 = new javax.swing.JScrollPane(); 
     jTable1 = new javax.swing.JTable(); 
     jButton1 = new javax.swing.JButton(); 
     jScrollPane2 = new javax.swing.JScrollPane(); 
     jTextArea1 = new javax.swing.JTextArea(); 
     jScrollPane3 = new javax.swing.JScrollPane(); 
     jTextArea2 = new javax.swing.JTextArea(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     jTable1.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] { 

      }, 
      new String [] { 
       "Title 1", "Title 2" 
      } 
     )); 
     jTable1.setDefaultRenderer(Object.class, new MultiLineCellRendererx()); 
     jTable1.getModel().addTableModelListener(new TableModelListener() { 
      @Override 
      public void tableChanged(TableModelEvent e) { 
       refreshTable(jTable1); 
      } 
     }); 
     jScrollPane1.setViewportView(jTable1); 

     jButton1.setText("jButton1"); 
     jButton1.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       jButton1ActionPerformed(evt); 
      } 
     }); 

     jTextArea1.setColumns(20); 
     jTextArea1.setLineWrap(true); 
     jTextArea1.setRows(5); 
     jTextArea1.setWrapStyleWord(true); 
     jScrollPane2.setViewportView(jTextArea1); 

     jTextArea2.setColumns(20); 
     jTextArea2.setLineWrap(true); 
     jTextArea2.setRows(5); 
     jTextArea2.setWrapStyleWord(true); 
     jScrollPane3.setViewportView(jTextArea2); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap() 
       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
        .addComponent(jScrollPane1) 
        .addGroup(layout.createSequentialGroup() 
         .addComponent(jButton1) 
         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
         .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 
         .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
         .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 
         .addGap(0, 0, Short.MAX_VALUE))) 
       .addContainerGap()) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
        .addGroup(layout.createSequentialGroup() 
         .addGap(8, 8, 8) 
         .addComponent(jButton1)) 
        .addGroup(layout.createSequentialGroup() 
         .addContainerGap() 
         .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 
        .addGroup(layout.createSequentialGroup() 
         .addContainerGap() 
         .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) 
       .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
       .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 359, Short.MAX_VALUE) 
       .addContainerGap()) 
     ); 

     pack(); 
    }      

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
     Object[] row = {jTextArea1.getText(), jTextArea2.getText()}; 
     ((DefaultTableModel)jTable1.getModel()).addRow(row); 
     refreshTable(jTable1); 
    }           
    public void refreshTable(JTable jTable1){ 
     for (int row = 0; row < jTable1.getRowCount(); row++){ 
      int rowHeight = jTable1.getRowHeight(); 

      for (int column = 0; column < jTable1.getColumnCount(); column++){ 
       JTextArea comp = (JTextArea)jTable1.prepareRenderer(jTable1.getCellRenderer(row, column), row, column); 
       if(rowHeight<((comp.getLineCount()+1)*30)){ 
        rowHeight = (comp.getLineCount()+1)*30; 
       } 
      } 
      jTable1.setRowHeight(row, rowHeight); 
     } 
    } 
    public static void main(String args[]) { 

     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new NewJFrame2().setVisible(true); 
      } 
     }); 
    } 

    private javax.swing.JButton jButton1; 
    private javax.swing.JScrollPane jScrollPane1; 
    private javax.swing.JScrollPane jScrollPane2; 
    private javax.swing.JScrollPane jScrollPane3; 
    private javax.swing.JTable jTable1; 
    private javax.swing.JTextArea jTextArea1; 
    private javax.swing.JTextArea jTextArea2; 
    // End of variables declaration     
} 
+2

應該如何樣子?你能發佈圖片/ ascii藝術嗎? – Frakcool

+0

根據要求添加了一張照片。仍然無法解決問題。 –

+0

這就是它現在的樣子,但是,**應該如何看起來像? – Frakcool

回答

1

榮譽給你@Frakcool

你爲我做這一切成爲可能。謝謝!我希望你可以發表一個答案,我會標記它。

這裏是結果:

import java.awt.Color; 
import java.awt.Component; 
import javax.swing.JTable; 
import javax.swing.JTextArea; 
import javax.swing.event.TableModelEvent; 
import javax.swing.event.TableModelListener; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableModel; 
import javax.swing.table.TableRowSorter; 

/** 
* 
* @author Innocentus 
*/ 
public class MultiLineJTable extends JTable{ 

    public MultiLineJTable(){ 
     super(); 
    } 

    public MultiLineJTable(Object[][] row, String[] col){ 
     DefaultTableModel dtm = new DefaultTableModel(row,col); 
     this.setModel(dtm); 
     addFireEvent(); 
     this.setDefaultRenderer(Object.class, new MultiLineCellRendererx()); 
    } 

    @Override 
    public void setModel(TableModel dataModel) { 
     if (dataModel == null) { 
      throw new IllegalArgumentException("Cannot set a null TableModel"); 
     } 
     if (this.dataModel != dataModel) { 
      TableModel old = this.dataModel; 
      if (old != null) { 
       old.removeTableModelListener(this); 
      } 
      this.dataModel = dataModel; 
      dataModel.addTableModelListener(this); 

      tableChanged(new TableModelEvent(dataModel, TableModelEvent.HEADER_ROW)); 

      firePropertyChange("model", old, dataModel); 

      if (getAutoCreateRowSorter()) { 
       setRowSorter(new TableRowSorter<TableModel>(dataModel)); 
      } 
      addFireEvent(); 
     } 
     try { 
      this.setDefaultRenderer(Object.class, new MultiLineCellRendererx()); 
     } catch (Exception e) { 
     } 
    } 

    public void refreshTable(){ 
     JTable tbl = this; 
     for (int row = 0; row < tbl.getRowCount(); row++){ 
      int rowHeight = tbl.getRowHeight(); 

      for (int column = 0; column < tbl.getColumnCount(); column++){ 
       Component comp = tbl.prepareRenderer(tbl.getCellRenderer(row, column), row, column); 
       rowHeight = Math.max(rowHeight, comp.getPreferredSize().height); 
      } 

      tbl.setRowHeight(row, rowHeight); 
     } 
    } 

    private void addFireEvent(){ 
     this.getModel().addTableModelListener(new TableModelListener() { 
      @Override 
      public void tableChanged(TableModelEvent e) { 

       switch (e.getType()) { 
        case TableModelEvent.DELETE: 
         refreshTable(); 
         break; 
        case TableModelEvent.INSERT: 
         refreshTable(); 
         break; 
        case TableModelEvent.UPDATE: 
         refreshTable(); 
         break; 
       } 
      } 
     }); 
    } 
} 
class MultiLineCellRendererx extends JTextArea implements TableCellRenderer { 

    public MultiLineCellRendererx() { 
     setLineWrap(true); 
     setWrapStyleWord(true); 
     setSelectionColor(Color.GREEN); 
    } 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
     setText((String)value); 
     setSize(table.getColumnModel().getColumn(column).getWidth(),this.getPreferredSize().height); 
     setSelectionColor(Color.GREEN); 

     if (isSelected){ 
      setBackground(table.getSelectionBackground()); 
      setForeground(table.getSelectionForeground()); 
     }else{ 
      setBackground(table.getBackground()); 
      setForeground(table.getForeground()); 
     } 
     return this; 
    } 
} 
+0

對不起,我再也忍不住了,因爲我今天參加了一次考試,所以我必須學習,我要到家了,所以我來看看你是否能夠解決它,我看到你可以!恭喜! :) – Frakcool

+0

謝謝!在你的幫助下,我能夠解決它。這甚至比提供編碼解決方案更好。它讓我精力充沛,讓我更瞭解自定義表格渲染!現在我正在渲染自定義控件,甚至最終學會了如何使用自定義表格編輯器。我欠你很多,謝謝! –

+0

我不會發表一個答案,因爲你的更好,因爲它有代碼,所以接受它,這樣做沒有羞恥:)很高興我可以幫助 – Frakcool