以下の例では、JTable
JList
と2つのJButton
(追加と削除)があります。リストには、追加ボタンをクリックすると6つの項目(文字列)があり、選択した値が表に追加されます。
テーブル内の文字列は、カスタムレンダラー(ボタンとラベル付きのJPanel
)を使用して表示されます。ボタンのテキストとラベルのテキストは、Stringの値に変更されます。
編集者がエントリーするまでは、すべてうまくいく。エディタを使用すると、ボタンをクリックすることが可能になります。
テーブルに文字列を初めて追加すると、行の高さがパネルの適切な高さに調整され、ボタンとラベルのテキストが設定されます。
行をクリックしてテーブルからエントリを削除し、[削除]ボタンをクリックすると、すべて期待どおりになります。
ここに問題があります:行の高さがあり、ラベルとボタンのテキストが設定されていない(レンダラーとエディタの両方が呼び出されていないため)ブレークポイントを使ってチェックしています)。
もちろん、私はカスタムレンダラを使って新しい行を表示したいのですが、どうしたらいいですか?追加テーブルの前のエントリを表示するカスタムTableCellEditor
package test;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.util.EventObject;
import javax.swing.AbstractAction;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.event.CellEditorListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class MainForm
extends javax.swing.JFrame
{
private JTable table;
private JScrollPane tableScrollPane;
private JList list;
private JScrollPane listScrollPane;
private JButton add;
private JButton remove;
public MainForm()
{
tableScrollPane = new JScrollPane();
table = new JTable();
listScrollPane = new JScrollPane();
list = new JList();
add = new JButton(new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
add();
}
});
add.setText("add");
remove = new JButton(new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
remove();
}
});
remove.setText("remove");
setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.LINE_AXIS));
tableScrollPane.setViewportView(table);
listScrollPane.setViewportView(list);
add(tableScrollPane);
DefaultTableModel model = new DefaultTableModel();
model.addColumn("test");
table.setModel(model);
TableColumn col = table.getColumn("test");
col.setCellRenderer(new CustomTableCellRenderer());
col.setCellEditor(new CustomTableCellEditor());
DefaultListModel listModel = new DefaultListModel();
listModel.addElement("test1");
listModel.addElement("test2");
listModel.addElement("test3");
listModel.addElement("test4");
listModel.addElement("test5");
listModel.addElement("test6");
list.setModel(listModel);
add(listScrollPane);
add(add);
add(remove);
}
private void add()
{
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(new Object[]
{
list.getSelectedValue()
});
}
private void remove()
{
int selectedRow = table.getSelectedRow();
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.removeRow(selectedRow);
}
public static void main(String[] args)
{
new MainForm().setVisible(true);
}
public class CustomTableCellRenderer
extends customPanel
implements TableCellRenderer
{
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus, int row,
int column)
{
setText((String) value);
if (isSelected || hasFocus)
{
setBackground(UIManager.getColor("List.selectionBackground"));
setForeground(UIManager.getColor("List.selectionForeground"));
}
else
{
setBackground(UIManager.getColor("Panel.background"));
setForeground(UIManager.getColor("Panel.foreground"));
}
table.setRowHeight(row, (int)getPreferredSize().height);
return this;
}
}
public class CustomTableCellEditor
extends customPanel
implements TableCellEditor
{
Object value;
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row,
int column)
{
this.value = value;
setText((String) value);
setBackground(UIManager.getColor("List.selectionBackground"));
setForeground(UIManager.getColor("List.selectionForeground"));
table.setRowHeight(row, (int)getPreferredSize().height);
return this;
}
public Object getCellEditorValue()
{
return value;
}
public boolean isCellEditable(EventObject anEvent)
{
return true;
}
public boolean shouldSelectCell(EventObject anEvent)
{
return true;
}
public boolean stopCellEditing()
{
setBackground(UIManager.getColor("Panel.background"));
setForeground(UIManager.getColor("Panel.foreground"));
return true;
}
public void cancelCellEditing()
{
}
public void addCellEditorListener(CellEditorListener l)
{
}
public void removeCellEditorListener(CellEditorListener l)
{
}
}
public class customPanel
extends JPanel
{
private JLabel label;
private JButton button;
public customPanel()
{
label = new JLabel();
button = new JButton();
add(label);
add(button);
}
public void setText(String text)
{
label.setText(text);
button.setText(text);
}
}
}
あなたのカスタムエディタの実装は_invalid_です(問題の可能性があります)。契約によって、内部的な理由で編集が終了したときにリスナーに通知する必要があります。あなたはその契約に自明に従うことができません... – kleopatra
Java命名規則を覚えておいてください。(常に!) – kleopatra
読みやすさに影響しない場合は、テスト目的以外は常に命名規則を使用します。私は欠けている通知のために撃つでしょう、それが動作する場合は意味をなさない。 – siebz0r