2016-09-08 7 views
0

jtableが新しい行を取得した後にコードを起動する方法を探しています。私は非常に多くのスレッドを読んでいて、それらをテストしました。そのうちの1つはmodel.fireTableDataChanged()のようなものです。配置方法はわかりません。JTableで新しい行を追加した後のFireコード

ユーザーが新しい行を追加するたびに、行が追加された後、メソッドrefreshTable()が実行されます。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.event.ActionEvent; 

import javax.swing.AbstractCellEditor; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JTable; 
import javax.swing.JTextArea; 
import javax.swing.event.TableModelEvent; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableCellEditor; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableModel; 
import javax.swing.table.TableRowSorter; 

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

    public JayMultiLineTable(){ 
     super(); 
    } 

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

    @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()); 
      this.setDefaultEditor(Object.class, new MultiLineCellEditor()); 
     } 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((TableModelEvent e) -> { 
      switch (e.getType()) { 
       case TableModelEvent.DELETE: 
        refreshTable(); 
        break; 
       case TableModelEvent.INSERT: 
        refreshTable(); 
        break; 
       case TableModelEvent.UPDATE: 
        refreshTable(); 
        break; 
      } 
     }); 

    } 

    public static void main(String args[]){ 
     JFrame jf = new JFrame(); 
     jf.getContentPane().setLayout(new BorderLayout()); 
     JayMultiLineTable table = new JayMultiLineTable(); 
     table.setModel(new DefaultTableModel(
      new Object [][] { 
       {"this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample. this is a sample.", " this is a sample."," this is a sample."," this is a sample."} 
      }, 
      new String [] { 
       "Title 1", "Title 2", "Title 3", "Title 4" 
      } 
     )); 
     jf.getContentPane().add(table, BorderLayout.CENTER); 
     JButton btn = new JButton("add another row"); 
     btn.addActionListener((ActionEvent e)->{ 
      Object row[] = {"This is an added sample","This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample. This is an added sample","This is an added sample","This is an added sample"}; 
      ((DefaultTableModel)table.getModel()).addRow(row); 
      //table.refreshTable(); <--- unless I call this method, the row height will not adjust unless the addrow is fired again for the second time. 
     }); 
     jf.getContentPane().add(btn, BorderLayout.NORTH); 
     jf.setExtendedState(JFrame.MAXIMIZED_BOTH); 
     jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     jf.show(); 

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

class MultiLineCellEditor extends AbstractCellEditor implements TableCellEditor { 
    // This is the component that will handle the editing of the cell value 
    JComponent component = new JTextArea(); 

    public MultiLineCellEditor(){ 
     ((JTextArea)component).setLineWrap(true); 
     ((JTextArea)component).setWrapStyleWord(true); 
    } 
    // This method is called when a cell value is edited by the user. 
    public Component getTableCellEditorComponent(JTable table, Object value, 
      boolean isSelected, int rowIndex, int vColIndex) { 
     // 'value' is value contained in the cell located at (rowIndex, vColIndex) 

     if (isSelected) { 
      // cell (and perhaps other cells) are selected 
     } 

     // Configure the component with the specified value 
     ((JTextArea)component).setText((String)value); 

     // Return the configured component 
     return component; 
    } 

    // This method is called when editing is completed. 
    // It must return the new value to be stored in the cell. 
    public Object getCellEditorValue() { 
     return ((JTextArea)component).getText(); 
    } 

} 

EDIT説明ではないため

私の謝罪:

は、ここに私のコードです。

これは、ユーザーがレンダラーを追加せずに複数行のデータを使用できるカスタマイズされたJTableです。私の問題は、行を追加すると、その行が行の高さを調整せず、代わりにデフォルトのサイズになりますが、別の行を追加すると、前の行が更新され、複数行のテキストに合わせてサイズが変更されます。

ここで私が達成したいのは、問題が修正される行が挿入された後にrefreshTable()メソッドを起動することです。

これを実装するにはどうすればよいですか?

refreshTable()を含むtableModelListenerを追加すると、BEFOREという行が挿入されますが、それは私のためではありません。行が追加された後"テーブルをリフレッシュ"にします。

+1

[SSCCE](http://sscce.org) –

+0

はrefreshTable()の代わりにdoLayout()を使用してください。ほとんどのコードはTableModelListenerから起動されたイベントのハンティングではなくXxxTableCellRendererを担当します。 – mKorbel

答えて

1

DefaultTableModelが変更を検出した場合、対応するイベントが発生します。たとえば、大きい番号のsetRowCountを呼び出すとします(fireTableRowsInserted(old, rowCount-1);)。変更方法により、射出ん:

はインターフェースTableModelDefaultTableModelより低い条件である、とさえDefaultTableModelが全て発射機能が実装されていることいないことをAbstractTableModelに由来していることに注意してください。 Javadocの少なくともチェックが必要とされるであろう。それはあまりにもそれ以降のモデルに使用されるように

if (!(model instanceof DefaultTableModel)) { 
    throw bad luck; 
} 

は、setModeladdFireEventを移動します。 モデルの設定にテーブルモデルリスナーを追加すると、最初のrefreshTableを呼び出すポイントになる可能性があります。

refreshTableには計算が多いため、invokeLaterを呼び出してGUIを応答してください。

 this.getModel().addTableModelListener(e -> { // TableModelListener 
      SwingUtilities.invokeLater(() -> { // Runnable 
       switch (e.getType()) { 
        case TableModelEvent.DELETE: 
         refreshTable(); 
         break; 
        case TableModelEvent.INSERT: 
         refreshTable(); 
         break; 
        case TableModelEvent.UPDATE: 
         refreshTable(); 
         break; 
       } 
      }); 
     }); 
Javaで使用すると、ロガー多分問題を見つけます。

+0

Brilliant!ちょうど私が必要なもの!ありがとうございました! –

関連する問題