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
という行が挿入されますが、それは私のためではありません。行が追加された後"テーブルをリフレッシュ"にします。
[SSCCE](http://sscce.org) –
はrefreshTable()の代わりにdoLayout()を使用してください。ほとんどのコードはTableModelListenerから起動されたイベントのハンティングではなくXxxTableCellRendererを担当します。 – mKorbel