Java 自定义可更改的、意外的行为
为了创建自定义JTable结构,我从一个非常简单的项目开始,以便更好地理解。不幸的是,一旦我开始定制东西,我就会有奇怪的行为,我希望你能帮助我理解它们。多谢各位 以下是我的小项目:Java 自定义可更改的、意外的行为,java,swing,jtable,Java,Swing,Jtable,为了创建自定义JTable结构,我从一个非常简单的项目开始,以便更好地理解。不幸的是,一旦我开始定制东西,我就会有奇怪的行为,我希望你能帮助我理解它们。多谢各位 以下是我的小项目: public class Tableau extends JFrame { public Tableau() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800,600); setCont
public class Tableau extends JFrame {
public Tableau() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(800,600);
setContentPane(new Panel());
setVisible(true);
}
public static void main(String[] args) {
new Tableau();
}
private static class Panel extends JPanel {
private JTable table = new Table(4, 4);
public Panel() {
add(table);
}
}
private static class Table extends JTable {
private Renderer randerer = new Renderer();
public Table(int row, int col) {
super(new Model(row, col));
setAutoResizeMode(AUTO_RESIZE_OFF);
setDefaultRenderer(String.class, randerer);
setDefaultEditor(String.class, randerer);
}
private class Renderer implements TableCellRenderer, TableCellEditor {
String previousContent = "";
JTextPane rendererComponent = new JTextPane();
public Renderer() {
super();setOpaque(true);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
rendererComponent.setText((String)value);
rendererComponent.setBorder(hasFocus ? BorderFactory.createLineBorder(Color.RED) : null);
rendererComponent.setBackground(isSelected ? Color.PINK : Color.GREEN);
FontMetrics fm = rendererComponent.getFontMetrics(rendererComponent.getFont());
if(((String)value).length()!=0) {rendererComponent.setPreferredSize(new Dimension(fm.stringWidth((String)value),fm.getHeight()));}
else {rendererComponent.setPreferredSize(new Dimension(20, fm.getHeight()));}
return rendererComponent;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
rendererComponent.setText((String)value);
rendererComponent.setBackground(isSelected ? table.getSelectionBackground() : Color.MAGENTA);
if(isSelected) {rendererComponent.selectAll();}
previousContent = (String)value;
return rendererComponent;
}
@Override
public Object getCellEditorValue() {
return rendererComponent.getText();
}
@Override
public boolean isCellEditable(EventObject anEvent) {
return true;
}
@Override
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
@Override
public boolean stopCellEditing() {
fireEditingStoppedEvent();
return true;
}
@Override
public void cancelCellEditing() {
rendererComponent.setText(previousContent);
fireEditingCanceledEvent();
}
protected void fireEditingStoppedEvent() {
for(CellEditorListener l : listeners) {l.editingStopped(new ChangeEvent(this));}
}
protected void fireEditingCanceledEvent() {
for(CellEditorListener l : listeners) {l.editingCanceled(new ChangeEvent(this));}
}
private List<CellEditorListener> listeners = new LinkedList<CellEditorListener>();
@Override
public void addCellEditorListener(CellEditorListener l) {
listeners.add(l);
}
@Override
public void removeCellEditorListener(CellEditorListener l) {
listeners.remove(l);
}
}
}
private static class Model implements TableModel {
// private ColumnModel colonnes = new ColumnModel();
private List<List<Cellule>> colonnes = new LinkedList<List<Cellule>>();
private int rowCount = 0;
// private List<Cellule> cellules = new LinkedList<Cellule>();
private static class Cellule {
public Cellule() {}
public Cellule(Object content) {this.content = content;}
private Object content;
private Object getContent() {return content;}
private void setContent(Object newContent) {content = newContent;}
}
public Model(int row, int col) {
for(int j=0; j<col; j++) {
insertColumn(j);
}
for(int i=0; i<row; i++) {
insertRow(i);
}
}
@Override
public int getRowCount() {
return rowCount;
}
@Override
public int getColumnCount() {
return colonnes.size();
}
@Override
public String getColumnName(int columnIndex) {
String result = "";
for (; columnIndex >= 0; columnIndex = columnIndex / 26 - 1) {
result = (char)((char)(columnIndex%26)+'A') + result;
}
return result;
}
@Override
public Class<?> getColumnClass(int columnIndex) {
return colonnes.isEmpty() ? Object.class : getValueAt(columnIndex, 0).getClass();
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return colonnes.get(columnIndex).get(rowIndex).getContent();
}
@Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
colonnes.get(columnIndex).get(rowIndex).setContent(aValue);
fireTableChanged(new TableModelEvent(this, rowIndex, rowIndex, columnIndex, TableModelEvent.UPDATE));
}
protected void fireTableChanged(TableModelEvent e) {
for(TableModelListener l : listeners) {
l.tableChanged(null);
}
}
public void insertColumn(int index) {
List<Cellule> newColumn = new LinkedList<Cellule>();
for(int i = 0; i<getRowCount(); i++) {
Cellule newCell = new Cellule("");
newColumn.add(newCell);
}
colonnes.add(index, newColumn);
fireTableChanged(new TableModelEvent(this, 0, getRowCount(), index, TableModelEvent.INSERT));
}
public void insertRow(int index) {
for(List<Cellule> colonne : colonnes) {
Cellule newCell = new Cellule("");
colonne.add(index, newCell);
}
rowCount++;
fireTableChanged(new TableModelEvent(this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
}
public void removeColumn(int index) {
colonnes.remove(index);
fireTableChanged(new TableModelEvent(this, 0, getRowCount(), index, TableModelEvent.DELETE));
}
public void removeRow(int index) {
for(List<Cellule> row : colonnes) {
row.remove(index);
}
rowCount--;
fireTableChanged(new TableModelEvent(this, index, index, TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE));
}
private List<TableModelListener> listeners = new LinkedList<TableModelListener>();
@Override
public void addTableModelListener(TableModelListener l) {
listeners.add(l);
}
@Override
public void removeTableModelListener(TableModelListener l) {
listeners.remove(l);
}
}
}
基本上,我们有一个JFrame类表,其中包含一个JPanel类面板,其中包含一个JTable类表。此表使用TableModel类模型和JTextPane类呈现器,用于呈现和编辑表内容
以下是我的问题:
1如果我单击一个单元格,它将变为白色,我不明白在给定渲染器代码的情况下,这是如何可能的。。。。如果我写了什么,首先,单元格中没有显示任何内容,但是,当我移动焦点时,文本会出现
2如果我单击一个单元格,然后使用箭头键移动焦点,那么选择似乎是正确的。红色边框显示正确,等等。为什么我只单击而不使用箭头时选择不正确
谢谢 这实际上是4个独立的问题,其中一些问题可以在文档中得到回答。我将从这里删除它,用我的尝试创建一个新问题。1和2都是相互关联的,是我最感兴趣的。3只是有一个意见,但我可以删除它。谢谢3在教程中有答案,有一种简单的方法可以更改选择操作。1关于为什么会有一堆TableCellEditor关于列表中的循环,2有多少JTables已经与一个模型JTable表链接;,因为您需要在renderer/editor类中传递JTable,3然后JTextPane可以是局部变量,而不是扩展的原因,4 putClientPropertyterminateEditOnFocusLost,Boolean.TRUE;==stopCellEditing,那么stopCellEditing是反生产力的5返回冒号的原因是什么?行数:colonnes.get0.size;,单元格可以有空值太6通知表模型是错误的,顺便说一句fireTableChanged重置tablemodel,不是好主意,你可以很简单地丢失所有自定义TableCellRenderer/编辑器。。。。等