JTable编辑器中的键绑定 [英] Key binding in JTable editor

查看:86
本文介绍了JTable编辑器中的键绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I found keybinding topic (JTable Key Bindings) similar to this. I learned that its keybinding is bound to the table not the editor.

我的目标是编辑器以VK-ENTER结尾的任何输入,它执行动作pindah(这是添加新行和设置光标在新行上闪烁)。对不起,我没有从这个例子中学习。

My goal is any input on editor ending with VK-ENTER, it executes action pindah (which is adding new row and set cursor blinking on new row). I'm sorry, I failed to learn from that example.

有没有办法呢?

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

Here is my code (excluding the import as Eclipse will suggest it automatically):

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);
         }
 }
}


推荐答案

不是答案,而是关于代码的几条评论。

Not an answer but several comments about your code.

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

First you need to understand about the Event Dispatch Thread (EDT). Updates to GUI components need to be done on the EDT.

通常,您不需要保持嵌套SwingUtilities.invokeLater()代码,因为您确实在EDT。

Normally you don't need to keep nesting SwingUtilities.invokeLater() code since you do create your GUI on the EDT.

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

The reason we needed to add the invokeLater(...) to make the first cell editable and have the cursor blinking is that you can't set focus on a component if the frame is not visible. So the invokeLater(...) allows us to add code to the end of the EDT so it executed after the setVsible(...) statement in your main() method.

所以,如果你想使用Key Bindings,你可以在你的Fpos类的构造函数中设置所有的Key Binding。

So, if you do want to use Key Bindings you could just set all the Key Bindings in the constructor of your Fpos class.

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

However, I don't know the proper solution for this current requirement.

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

Currently, an ActionListener is added to the JTextField that is used as the cell editor. When you press the Enter key the listener is invoked and the stop cell editing logic of the table is invoked, which means the value in the editor is added to the TableModel and the cell editor is removed from the table.

所以你不能简单地将一个Key Binding添加到编辑器,因为你需要发生这种默认行为。

So you can't just simply add a Key Binding to the editor since you need this default behaviour to occur.

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

I guess you could create a custom cell editor. Then in the ActionListener you can add your additional requirements.

这篇关于JTable编辑器中的键绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆