代码之家  ›  专栏  ›  技术社区  ›  Hendra

JTable编辑器中的键绑定

  •  0
  • Hendra  · 技术社区  · 8 年前

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

    我的目标是在编辑器上以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);
             }
     }
    }
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   camickr    8 年前

    不是答案,而是关于代码的一些注释。

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

    通常情况下,你不需要继续筑巢。invokeLater()代码,因为您确实在EDT上创建了GUI。

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

    因此,如果您确实想使用键绑定,可以在Fpos类的构造函数中设置所有键绑定。

    然而,我不知道这个当前需求的正确解决方案。

    目前,ActionListener被添加到用作单元格编辑器的JTextField中。当您按Enter键时,将调用侦听器,并且 stop cell editing logic 调用表的,这意味着编辑器中的值被添加到表模型中,单元格编辑器从表中删除。

    因此,您不能简单地将键绑定添加到编辑器中,因为您需要出现这种默认行为。