我有一个带有自定义CellEditor的JTable,它在JScrollPane中使用JTextArea。当我通过鼠标单击进入编辑模式时,它可以完美工作。但是,当我尝试在聚焦单元格时键入一些字母时,什么也没有发生。单元格获得“编辑模式样式”(背景更改),但保持空白…
任何想法 ?
public class MultiLineCellEditor extends DefaultCellEditor {
JTextArea textArea;
JScrollPane scrollPane;
public MultiLineCellEditor( final JTable table ) {
super( new JTextField() );
getComponent().setName( "Table.editor" );
setClickCountToStart( 2 );
textArea = new JTextArea();
scrollPane = new JScrollPane();
scrollPane.setViewportView( textArea );
editorComponent = scrollPane;
}//end MultiLineCellEditor
public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected,
int row, int column ) {
this.setValue( value );
scrollPane.setBorder( new LineBorder( Color.black ) );
return scrollPane;
}
public void setValue( Object value ) {
textArea.setText( ( value != null ) ? value.toString() : "" );
}
public Object getCellEditorValue() {
return textArea.getText();
}
}//end class
这是我的测试代码:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class MultiLineCellEditorTest {
public JComponent makeUI() {
String[] columnNames = {"JTextField", "JTextArea"};
Object[][] data = {
{"aaa", "JTextArea+JScrollPane\nCtrl-Enter: stopCellEditing"},
{"bbb", "ggg"}, {"ccccDDD", "hhh\njjj\nkkk"}
};
TableModel model = new DefaultTableModel(data, columnNames) {
@Override public Class<?> getColumnClass(int column) {
return String.class;
}
};
JTable table = new JTable(model) {
@Override public void updateUI() {
super.updateUI();
TableColumn col = getColumnModel().getColumn(1);
col.setCellEditor(new TextAreaCellEditor());
col.setCellRenderer(new TextAreaCellRenderer());
}
};
table.setAutoCreateRowSorter(true);
table.setSurrendersFocusOnKeystroke(true);
table.setRowHeight(64);
return new JScrollPane(table);
}
public static void main(String... args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new MultiLineCellEditorTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class TextAreaCellRenderer implements TableCellRenderer {
private final JTextArea textArea = new JTextArea();
public TextAreaCellRenderer() {
textArea.setLineWrap(true);
textArea.setBorder(BorderFactory.createEmptyBorder(1, 5, 1, 5));
}
@Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
if (isSelected) {
textArea.setForeground(table.getSelectionForeground());
textArea.setBackground(table.getSelectionBackground());
} else {
textArea.setForeground(table.getForeground());
textArea.setBackground(table.getBackground());
}
textArea.setFont(table.getFont());
textArea.setText(Objects.toString(value, ""));
return textArea;
}
}
//class TextAreaCellEditor extends AbstractCellEditor implements TableCellEditor {
class TextAreaCellEditor implements TableCellEditor {
private static final String KEY = "Stop-Cell-Editing";
private final JScrollPane scroll;
private final JTextArea textArea = new JTextArea();
public TextAreaCellEditor() {
//super();
scroll = new JScrollPane(textArea);
scroll.setBorder(BorderFactory.createEmptyBorder());
textArea.setLineWrap(true);
textArea.setBorder(BorderFactory.createEmptyBorder(1, 5, 1, 5));
KeyStroke enter = KeyStroke.getKeyStroke(
KeyEvent.VK_ENTER, InputEvent.CTRL_MASK);
textArea.getInputMap(JComponent.WHEN_FOCUSED).put(enter, KEY);
textArea.getActionMap().put(KEY, new AbstractAction() {
@Override public void actionPerformed(ActionEvent e) {
stopCellEditing();
}
});
}
@Override public Object getCellEditorValue() {
return textArea.getText();
}
@Override public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
System.out.println("2. getTableCellEditorComponent");
textArea.setFont(table.getFont());
textArea.setText(Objects.toString(value, ""));
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
textArea.setCaretPosition(textArea.getText().length());
textArea.requestFocusInWindow();
System.out.println("4. invokeLater: getTableCellEditorComponent");
}
});
return scroll;
}
@Override public boolean isCellEditable(final EventObject e) {
if (e instanceof MouseEvent) {
return ((MouseEvent) e).getClickCount() >= 2;
}
System.out.println("1. isCellEditable");
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
if (e instanceof KeyEvent) {
KeyEvent ke = (KeyEvent) e;
char kc = ke.getKeyChar();
if (Character.isUnicodeIdentifierStart(kc)) {
textArea.setText(textArea.getText() + kc);
System.out.println("3. invokeLater: isCellEditable");
}
}
}
});
return true;
}
//Copid from AbstractCellEditor
protected EventListenerList listenerList = new EventListenerList();
transient protected ChangeEvent changeEvent = null;
@Override public boolean shouldSelectCell(EventObject e) {
return true;
}
@Override public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
@Override public void cancelCellEditing() {
fireEditingCanceled();
}
@Override public void addCellEditorListener(CellEditorListener l) {
listenerList.add(CellEditorListener.class, l);
}
@Override public void removeCellEditorListener(CellEditorListener l) {
listenerList.remove(CellEditorListener.class, l);
}
public CellEditorListener[] getCellEditorListeners() {
return listenerList.getListeners(CellEditorListener.class);
}
protected void fireEditingStopped() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for(int i = listeners.length-2; i>=0; i-=2) {
if(listeners[i]==CellEditorListener.class) {
// Lazily create the event:
if(changeEvent == null) changeEvent = new ChangeEvent(this);
((CellEditorListener)listeners[i+1]).editingStopped(changeEvent);
}
}
}
protected void fireEditingCanceled() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for(int i = listeners.length-2; i>=0; i-=2) {
if(listeners[i]==CellEditorListener.class) {
// Lazily create the event:
if(changeEvent == null) changeEvent = new ChangeEvent(this);
((CellEditorListener)listeners[i+1]).editingCanceled(changeEvent);
}
}
}
}
编辑:用委托替换继承
我已经为我的组织的需求添加了一些自定义属性到注册字段。根据文档自定义了主题并添加了验证。很好用。我可以添加这些属性到帐户管理页面也通过修改帐户模板。
我有一个JTable,其中添加了一个JButton(Delete button)和一个JComboBox作为两列上的自定义单元格编辑器。现在,当我在组合框中选择一个项目并单击Delete按钮时,所选行被删除,但已删除行的组合框在该行上呈现。我是否也必须从表中删除单元编辑器。如果我不选择我的组合框,代码就可以正常工作。请帮帮我。 我的代码是这样的:- 我在main中实例化了我的类的一个对象,然后单击
在“定义”选项卡,你可以创建和编辑视图的 SELECT 语句 SQL。Navicat Data Modeler 为编辑视图定义提供广泛的高级功能,例如:编辑代码功能、智能自动完成代码、设置 sql 格式及更多。 【提示】当你在视图创建工具创建视图,SELECT 语句将会自动生成。 美化 SQL(仅适用于非 Essentials 版) 若要格式化凌乱的 SQL 代码到一个结构良好的脚本,你可以点击
在“SQL 编辑器”选项卡,你可以创建和编辑视图的 SELECT 语句 SQL。Navicat Data Modeler 为编辑视图定义提供广泛的高级功能,例如:编辑代码功能、智能自动完成代码、设置 sql 格式及更多。 【提示】当你在视图创建工具创建视图,SELECT 语句将会自动生成。 美化 SQL(仅适用于非 Essentials 版) 若要格式化凌乱的 SQL 代码到一个结构良好的脚本,你
我正在研究带有注释的Spring MVC。我还没有注册任何自定义日期编辑 在我的类中,我有一个类型为java.lang.Date的属性 我读到的是customDateEditor默认不注册。但是当我提交带有空白日期的表单时,它抛出了illegalArgumentException 如果我输入日期然后提交它不抛出异常 在那之后,我将绑定结果作为参数添加到控制器方法,现在它正在接受空白值 我没有向控制
我正在将我的项目从Spring 2.5.6迁移到Spring 4.0.6。下面是我们拥有的客户属性编辑器的xml定义。 但是,当我启动服务器时,我在日志中看到以下异常。 这是我班级里Spring罐子的清单