java – 在基于JTable面板的单元格编辑器中丢失第一个字符
作者:互联网
我有一个单元格编辑器,其中包含一个小按钮,然后是一个文本字段,可用于编辑内联值
我使用setSurrendersFocusOnKeystroke(true)和一个焦点监听器,以允许用户立即从键盘开始编辑,但问题是按下的fisrt键似乎被消耗而不是被添加到文本字段,我该如何防止这种情况?
完整的自包含示例如下
import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
public class PanelTableEditorTest extends JFrame {
private JTable table;
public PanelTableEditorTest() {
this.setLayout(new BorderLayout());
table = new JTable(10, 10);
table.getSelectionModel().setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
table.setCellSelectionEnabled(true);
table.setDefaultEditor(Object.class, new SimpleMultiRowCellEditor());
table.setSurrendersFocusOnKeystroke(true);
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F2, 0),
"none");
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.put(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, 0),
"startEditing");
this.add(table.getTableHeader(), BorderLayout.NORTH);
this.add(table, BorderLayout.CENTER);
pack();
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new PanelTableEditorTest();
}
});
}
public class SimpleMultiRowCellEditor extends DefaultCellEditor {
final JPanel panel;
private final JButton rowCount;
public SimpleMultiRowCellEditor() {
super(new JTextField());
this.setClickCountToStart(1);
rowCount = new JButton();
rowCount.setVisible(true);
panel = new JPanel();
panel.setOpaque(false);
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(rowCount);
panel.add(editorComponent);
panel.addFocusListener(new PanelFocusListener());
}
public Component getTableCellEditorComponent(
final JTable table,final Object val, final boolean isSelected,
final int row, final int column) {
rowCount.setText("1");
delegate.setValue(val);
editorComponent.requestFocusInWindow();
return panel;
}
class PanelFocusListener implements FocusListener {
public void focusGained(FocusEvent e) {
editorComponent.requestFocusInWindow();
}
public void focusLost(FocusEvent e) {
}
}
}
}
解决方法:
所以我找到了一个解决方案,感谢这篇文章http://jroller.com/santhosh/entry/keyboard_handling_in_tablecelleditor,以及一些有用的讨论以及它如何在http://forums.java.net/jive/thread.jspa?messageID=482236񵮼应用于其他组件
不完全理解解决方案这整个区域似乎是一个雷区
我还将此解决方案Get correct editing behaviour in JTable using java DefaultCellEditor添加到此中,以便当您使用键盘开始编辑字段时,现有值将被替换,但是当您双击字段时则不会.
我的一个困惑是,我没有像我期望的那样收到一个关键事件,但只是因为我必须考虑到这一点.
我已经从使用setSurrenderKeystrokes(true)回来了,因为这会导致其他编辑器出现问题,例如简单的textfieldingitor
import javax.swing.*;
import javax.swing.text.Caret;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.EventObject;
public class PanelTableEditorTest extends JFrame
{
private JTable table;
public PanelTableEditorTest()
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e)
{
}
this.setLayout(new BorderLayout());
table = new JTable(4, 4);
table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setCellSelectionEnabled(true);
table.setSurrendersFocusOnKeystroke(false);
table.setDefaultEditor(Object.class,new SimpleMultiRowCellEditor());
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(java.awt.event.
KeyEvent.VK_F2, 0), "none");
table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(java.awt.event.
KeyEvent.VK_ENTER, 0), "startEditing");
this.add(table.getTableHeader(), BorderLayout.NORTH);
this.add(table, BorderLayout.CENTER);
pack();
setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
new PanelTableEditorTest();
}
});
}
public class SimpleMultiRowCellEditor extends DefaultCellEditor
{
private EventObject event;
final JPanel panel;
private final JButton rowCount;
public SimpleMultiRowCellEditor()
{
super(new JTextField());
this.setClickCountToStart(1);
rowCount = new JButton();
rowCount.setVisible(true);
panel = new TableEditorPanel();
panel.setRequestFocusEnabled(true);
panel.setOpaque(false);
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(rowCount);
panel.add(editorComponent);
}
public boolean isCellEditable(EventObject anEvent)
{
event=anEvent;
return super.isCellEditable(anEvent);
}
public Component getTableCellEditorComponent(final JTable table, final Object val, final boolean isSelected, final int row, final int column)
{
rowCount.setText("1");
delegate.setValue(val);
if(event instanceof KeyEvent || event==null)
{
final Caret caret = ((JTextField)editorComponent).getCaret();
caret.setDot(0);
((JTextField)editorComponent).setText("");
}
return panel;
}
class TableEditorPanel extends JPanel
{
public void addNotify(){
super.addNotify();
editorComponent.requestFocus();
}
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed){
InputMap map = editorComponent.getInputMap(condition);
ActionMap am = editorComponent.getActionMap();
if(map!=null && am!=null && isEnabled()){
Object binding = map.get(ks);
Action action = (binding==null) ? null : am.get(binding);
if(action!=null){
return SwingUtilities.notifyAction(action, ks, e, editorComponent,
e.getModifiers());
}
}
return false;
}
}
}
}
标签:java,swing,tablecelleditor 来源: https://codeday.me/bug/20191008/1871992.html