不好意思,由于错点了提交,请斑竹删除误发的帖子,谢谢!!现在重发一次,希望大家多帮忙
  
  小弟一直以来都从事delphi的开发,今年随着技术潮流的趋势开始学习java,埋头看书半年感觉小有成就。 
  这个月单位给个开发任务,做一个发票打印程序,必须实现的核心功能是:在表格中实现发票明细的录入。想想自己学java也有这么长时间,于是想用swing做,但偏偏这个核心功能没办法实现,郁闷死我了。到现在还不死心,因为这个程序的其他功能都已经实现,就这个功能无法完成,因此特来请教专家: 
  不说别的了,先把界面发给大家看看:这个界面是我用delphi实现的功能(btw:用delphi实现超级简单): 
    
    
  这个程序的功能是:
      1、在"商品编码"栏里输入数值后按回车,则"品名"和"单价"栏里自动填入事先定义好的"商品名称"和"单价",同时焦点移动到"数量"栏中;在"数量"栏中输入数量后按回车,这"金额"栏中自动计算出"单价"和"数量"的乘积,同时焦点移动到"金额"栏中。
    2、在"金额"栏中按回车,则新增一个空行,同时焦点移动到新增行的第一列中。
  
    
  上述这些功能,我都已经实现,但上个星期又加了新的需求:在第一列的输入框边上要添加一个button,用来选择已经定义好的商品(红圈内):
    
    于是一个通宵的看书和查找资料,通过TableCellRenderer实现了JTextField+JButton在栏中:
    
    通过定义JTable的InputMap和ActionMap实现了按回车键点按行移动:
    现在问题出现了两个问题:
    1、在JTable的第一列中输入数字后并按回车,光标并没有跳到第二列,而是留在了JButton上。
    2、在JTable的最后一列上按回车,新增一行后,光标并没有移动新增行的第一列上,而是移动到新增行的第二列上。

    
     这个JTable是根据老外的范例改写的,因此不能算是我的原创,希望各位sun专家能帮我看看,该如何改写:
     源码在这里,一共三个类:

  由于字符限制,在第二楼有更多源码:import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;public class CMiniTextField extends Box implements ActionListener,TableCellRenderer, FocusListener {
private JTextField jtf = new JTextField("");
private JButton lookup = new JButton("?"); public CMiniTextField() {
super(BoxLayout.X_AXIS);
createHorizontalBox();
lookup.addActionListener(this);
lookup.setPreferredSize(new Dimension(17, 17));
addContents();
doFocusTraversal();
addFocusListener(this);
} public JTextField getTextField() {
return jtf;
} public String getText() {
return jtf.getText();
} public void setFieldText(String text) {
jtf.setText(text);
updateUI();
} public JTextField getJTextField() {
return jtf;
} private void addContents() {
add(jtf);
add(lookup);
} public void actionPerformed(ActionEvent e) {

} public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
return this;
} public void focusGained(FocusEvent e) {
jtf.requestFocusInWindow();
} public void focusLost(FocusEvent e) {
} public void requestFocusAtStart() {
jtf.requestFocus();
} private void doFocusTraversal() {
Action gotoTextField1Action = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
jtf.requestFocusInWindow();
}
};
Action gotoButtonAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
lookup.requestFocusInWindow();
}
};
jtf.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
"gotoTextField2Action");
jtf.getActionMap().put("gotoTextField2Action", gotoButtonAction);
lookup.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
java.awt.event.InputEvent.SHIFT_MASK),
"gotoTextField1Action");
lookup.getActionMap().put("gotoTextField1Action", gotoTextField1Action);
}
}

解决方案 »

  1.   

    接上层:import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;public class CMiniTextFieldEditor extends AbstractCellEditor implements TableCellEditor {
    CMiniTextField m_addressBox; public CMiniTextFieldEditor() {
    m_addressBox = new CMiniTextField();
    } public Component getTableCellEditorComponent(JTable table, Object value,
    boolean isSelected, int rowIndex, int vColIndex) {
    m_addressBox.setFieldText(table.getValueAt(rowIndex, vColIndex) + "");
    m_addressBox.requestFocusAtStart();
    return m_addressBox;
    } public Object getCellEditorValue() {
    return m_addressBox.getText();
    }
    }
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;import javax.swing.AbstractAction;
    import javax.swing.Action;
    import javax.swing.JDesktopPane;
    import javax.swing.JFrame;
    import javax.swing.JInternalFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.KeyStroke;public class GUI extends JInternalFrame {
    JTable table;
    Vector data;
    Vector columns;
    JTextField cellTextField = new JTextField(); public GUI(String title, Dimension mainWindowSize) {
    super(title, true, true, true, true);
    initColumns();
    initData();
    initTable();
    buildFrame(mainWindowSize);
    } private void initColumns() {
    columns = new Vector();
    for (int i = 0; i < 5; i++)
    columns.add("col " + i);
    } private void initData() {
    data = new Vector();
    data.add(blankElement());
    } private void initTable() {
    try {
    table = new JTable(data, columns);
    table.setAutoscrolls(true);
    table.setColumnSelectionAllowed(false);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setSurrendersFocusOnKeystroke(true);
    } catch (Exception ex) {

    }

    final Action tabAction = table.getActionMap().get(
    "selectNextColumnCell");
    Action enterKey = new AbstractAction() {
    public void actionPerformed(ActionEvent e) {
    try {
    table.getCellEditor().stopCellEditing();
    } catch (Exception ex) {
    }
    int selectedRow = table.getSelectedRow();
    int selectedCol = table.getSelectedColumn();
    if (selectedCol == table.getColumnCount() - 1) {
    try {
    if (selectedRow == table.getRowCount() - 1
    && selectedCol == table.getColumnCount() - 1
    && table.getRowCount()<6) {
    addRow();

    }
    } catch (Exception ex) {
    if (selectedRow > 0) {
    setSelectedRow(selectedRow - 1);
    }
    JOptionPane.showMessageDialog(null, "Error: \n"
    + ex.getMessage());
    }
    } else if (selectedCol == 0) {
    System.out.println(table.getValueAt(selectedRow,
    selectedCol));
    }
    tabAction.actionPerformed(e);
    }
    };
    table.getInputMap().put(KeyStroke.getKeyStroke("ENTER"),
    "selectNextColumnCell");
    table.getActionMap().put("selectNextColumnCell", enterKey);
    activateRenderers();
    } private void activateRenderers() {
    table.getColumnModel().getColumn(0).setCellEditor(
    new CMiniTextFieldEditor());
    } public void setSelectedRow(int row) {
    table.setRowSelectionInterval(row, row);
    table.scrollRectToVisible(table.getCellRect(row, 0, true));
    } public void addRow() {
    data.addElement(blankElement());
    table.addNotify();
    setSelectedRow(table.getSelectedRow() + 1);
    table.changeSelection(table.getSelectedRow(), 0, false, false);
    //JOptionPane.showMessageDialog(null, table.getSelectedColumn());
    } public Vector blankElement() {
    Vector t = new Vector();
    t.add("");
    t.add(new Integer(0));
    t.add(new Long(0L));
    t.add(new Double(0));
    t.add(new Float(0));
    return t;
    } private void buildFrame(Dimension mainWindowSize) {
    try {
    JScrollPane sp = new JScrollPane(table);
    JPanel p = new JPanel(new GridBagLayout());
    p.add(sp, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
    GridBagConstraints.WEST, GridBagConstraints.BOTH,
    new Insets(5, 5, 5, 5), 0, 0));
    getContentPane().add(p, "Center");
    setVisible(true);
    setBounds(0, 0, (int) mainWindowSize.getWidth() - 50,
    (int) mainWindowSize.getHeight() - 100);
    toFront();
    setSelected(true);
    } catch (Exception ex) {
    System.out.println("Error: " + ex);
    }
    } public static void main(String[] args) {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(1000, 500);
    JDesktopPane jd = new JDesktopPane();
    jd.add(new GUI("Tariff Lines", f.getSize()));
    f.getContentPane().add(jd, "Center");
    f.setVisible(true);
    }
    }