java - JTable 编辑器中的键绑定(bind)

标签 java swing jtable

我发现与此类似的键绑定(bind)主题( JTable Key Bindings )。我了解到它的键绑定(bind)绑定(bind)到表格而不是编辑器。

我的目标是编辑器上以 VK-ENTER 结尾的任何输入,它执行 pindah 操作(添加新行并设置光标在新行上闪烁)。抱歉,我没能从这个例子中学到东西。

有办法吗?

这是我的代码(不包括导入,因为 Eclipse 会自动建议它):

public class Fpos extends JFrame 
{
public static void main(String[] args) 
{
    EventQueue.invokeLater(new Runnable() 
    {
        public void run() 
        {
            try 
            {
                Fpos frame = new Fpos();
                frame.setVisible(true);
                frame.setLocationRelativeTo(null);  //make frame center of screen                   
            } catch (Exception e) {e.printStackTrace();}
        }
    });
}

public Fpos() 
{
    //create Jpanel
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(10, 10, 1300, 700);
    JPanel contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);
    //create label TOTAL
    JLabel lblTotal = new JLabel("TOTAL : Rp.");                
    lblTotal.setFont(new Font("Wide Latin", Font.PLAIN, 30));
    lblTotal.setBounds(33, 25, 312, 31);
    contentPane.add(lblTotal);
    //create label Total Amount
    JLabel lblNewLabel = new JLabel("123,456,789");
    lblNewLabel.setHorizontalAlignment(SwingConstants.RIGHT);
    lblNewLabel.setFont(new Font("Wide Latin", Font.PLAIN, 60));
    lblNewLabel.setBounds(583, 19, 659, 61);
    contentPane.add(lblNewLabel);
    //create jtable in scrollpane
    String[] columnNames = {"PLU", "NAME", "UOM", "QTY", "PRICE","AMOUNT"};
        Object[][] data = {{"", "", "", "", "", ""}};
         DefaultTableModel model = new DefaultTableModel(data, columnNames);
     JTable table = new JTable(model);                  
     table.setFont(new Font("Tahoma", Font.PLAIN, 20));
     table.setRowHeight(25);
     JScrollPane sp=new JScrollPane(table);             
     sp.setBounds(25,100,1240,556);
     contentPane.add(sp);
     //set column width
     TableColumnModel columnModel = table.getColumnModel();
     short a[] = {150,540,50,150,150,200};
     for(byte i=0;i<6;i++) { columnModel.getColumn(i).setPreferredWidth(a[i]); }
     //render column format left alignment
     for(byte i=0;i<3;i++) {table.getColumnModel().getColumn(i).setCellRenderer(new TextTableCellRenderer());}
     //render column format ###,##0 right alignment
     for(byte i=3;i<6;i++) {table.getColumnModel().getColumn(i).setCellRenderer(new NumberTableCellRenderer());}
     //make cursor blinking on selected cell + select all cell value
    SwingUtilities.invokeLater(new Runnable()
    {
        public void run() 
        {
             table.changeSelection(0, 0, false, false);
             if (table.editCellAt(0, 0))
             {
                Component editor = table.getEditorComponent();
                editor.setFont(new Font("Tahoma", Font.PLAIN, 20));
                editor.requestFocusInWindow();
                ((JTextComponent)editor).selectAll(); //select all cell value                   

                //key binding
                Action pindah = new AbstractAction() 
                {
                    @Override
                    public void actionPerformed(ActionEvent e) 
                    {
                         //add row at last row
                         model.addRow(data);
                        //i want to add new blank row but somehow there is value on column 0, so I have to set it blank. If you have a solution on this, you're very welcome
                         model.setValueAt("", model.getRowCount()-1, 0);
                         //make cursor blinking on selected cell + select all cell value
                            SwingUtilities.invokeLater(new Runnable()
                            {
                                public void run() 
                                {
                                     table.changeSelection(0, 0, false, false);
                                     if (table.editCellAt(model.getRowCount()-1, 0))
                                     {
                                        Component editor = table.getEditorComponent();
                                        editor.setFont(new Font("Tahoma", Font.PLAIN, 20));
                                        editor.requestFocusInWindow();
                                        ((JTextComponent)editor).selectAll(); //select all cell value                   
                                     }
                                }
                            });              
                    }
                };
                ((JComponent) editor).getInputMap().put(KeyStroke.getKeyStroke((char) KeyEvent.VK_ENTER), "pindah");
                ((JComponent) editor).getRootPane().getActionMap().put("pindah", pindah);


            }
         }
    });              

}

//  render column format left alignment
 public class TextTableCellRenderer extends DefaultTableCellRenderer 
    {public TextTableCellRenderer() {{setHorizontalAlignment(JLabel.LEFT);}} }
//  render column format to ###,##0
 public class NumberTableCellRenderer extends DefaultTableCellRenderer 
 {         
     public NumberTableCellRenderer() {setHorizontalAlignment(JLabel.RIGHT);}
         @Override
         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) 
         {
                 if (value instanceof Number) {value = NumberFormat.getNumberInstance().format(value);}
                 return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
         }
 }
}

最佳答案

不是答案,而是关于您的代码的一些评论。

首先您需要了解事件调度线程 (EDT)。 GUI 组件的更新需要在 EDT 上完成。

通常,您不需要继续嵌套 SwingUtilities.invokeLater() 代码,因为您确实在 EDT 上创建了 GUI。

我们需要添加 invokeLater(...) 以使第一个单元格可编辑并使光标闪烁的原因是,如果框架不是,则无法将焦点设置在组件上可见的。因此,invokeLater(...) 允许我们将代码添加到 EDT 的末尾,以便它在 main() 方法中的 setVsible(...) 语句之后执行。

因此,如果您确实想使用按键绑定(bind),您只需在 Fpos 类的构造函数中设置所有按键绑定(bind)即可。

但是,我不知道满足当前要求的正确解决方案。

目前,ActionListener 已添加到用作单元格编辑器的 JTextField。当您按 Enter 键时,将调用监听器并调用表的停止单元格编辑逻辑,这意味着编辑器中的值将添加到 TableModel 中,并且单元格编辑器将从表中删除.

因此,您不能简单地向编辑器添加键绑定(bind),因为您需要发生此默认行为。

我想您可以创建一个自定义单元格编辑器。然后在 ActionListener 中您可以添加您的附加要求。

关于java - JTable 编辑器中的键绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47447780/

相关文章:

java - 读取 Maven 项目中的 Java 构建路径条目

java - kafka log-compaction消费数据

java - 从重写的方法中获取对象

java - 与后端数据结构同步的 JTable 设计

java - 无法在 JTable 的单个单元格中添加两个按钮

java - 使用 AXIS2 创建的 ADB stub 在客户端获取原始 XML SOAP 响应

java - 在 Java 中将 XML 拆分为多个文档

java - JFileChooser - 打开/取消/退出按钮

java - 在 netbeans 中制作加载屏幕

java - JOptionPane.showMessageDialog 的可选替代方案