日期:2014-05-20  浏览次数:20812 次

JScrollPane 排序后引起的程序的一个 bug, 请达人帮忙看看, 十分感谢!
先感谢下 scbb无私的帮助!

我写了个 Java的程序,里面有用到 JScrollPane。 有用到 2个按钮,其中一个是 Add,另一个是 Delete,分别对 JScrollPane 做添加行 和 删除行操作。

代码如下:

Java code

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneLayout;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class GlobalVari_13 extends JFrame implements KeyListener,
        ActionListener {
    private static final long serialVersionUID = 1L;

    private static double select = 0;
    private static int rowIndex = 0;

    public JTable table = null;

    public JButton buttonAdd = new JButton("Add");
    public JButton buttonDel = new JButton("Delete");
    public JButton buttonCls = new JButton("Close");

    // 表格方法使用
    public GlobalVari_13() {
        init();

        this.setTitle("Global Variables");
        this.setSize(new Dimension(650, 400));
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.setVisible(true);
        // this.setResizable(false);
    }

    class SymListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            Object obj = e.getSource();
            if (obj == buttonDel) {
                buttonDel_actionPerformed(e);
            }
        }
    }

    private void init() {
        Vector<String> colHeader = new Vector<String>();

        Vector<Vector<String>> dataVec = new Vector<Vector<String>>();

        colHeader.add("Variable");
        colHeader.add("Value  ");
        colHeader.add("Time  ");

        table = new JTable(dataVec, colHeader) {
            private static final long serialVersionUID = 1L;

            public boolean isCellEditable(int row, int column) {
                if (column > 1) {
                    return false;
                } else {
                    return true;
                }
            }

            public void editingStopped(ChangeEvent ce) {
                super.editingStopped(ce);
                int row = getSelectedRow();
                int col = getSelectedColumn();

                if (row >= 0 && col == 0) {
                    Object value = getValueAt(row, col);
                    DefaultTableModel model = (DefaultTableModel) table
                            .getModel();
                    boolean exist = false;
                    for (int i = 0; i < model.getRowCount(); i++) {
                        if (model.getValueAt(i, 0).equals((String) value)
                                && i != row) {
                            exist = true;
                            break;
                        }
                    }

                    if (exist == true) {
                        if (select == 1) {
                            model.removeRow(rowIndex);
                            select = 0;
                            buttonDel.setEnabled(false);
                        }
                    }

                } else if (row >= 0 && col == 1) {
                    Object value = getValueAt(row, col);
                    // 检查是不是浮点数
                    try {
                        double tempVal = Double.parseDouble((String) value);
                        setValueAt(BigDecimal.valueOf(tempVal)
                                .stripTrailingZeros(), row, col);
                    } catch (Exception e) {
                        // 不是浮点
                        setValueAt("", row, col);
                    }
                } else
                    return;
            }
        };

        /*DefaultTableModel model1 = (DefaultTableModel) table.getModel();
        model1.addRow(new Object[] { "gvar" + 1, "a",
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) });*/

        // 2设置表头行高
        table.getTableHeader().setPreferredSize(new Dimension(0, 20));
        // 3设置表内容行高
        table.setRowHeight(20);
        // 4设置单选模式
        table.getSelectionModel().setSelectionMode(
                ListSelectionModel.SINGLE_SELECTION);
        // 5设置单元格不可拖动
        table.getTableHeader().setReorderingAllowed(false);
        // 6设置不可改变列宽
        table.getTableHeader().setResizingAllowed(false);
        // 7设置列宽
        table.getColumnModel().getColumn(0).setPreferredWidth(95);
        table.getColumnModel().getColumn(1).setPreferredWidth(55);
        table.getColumnModel().getColumn(2).setPreferredWidth(30);
        // 注意索引越界

        DefaultTableCellRenderer right = new DefaultTableCellRenderer();
        right.setHorizontalAlignment(SwingConstants.RIGHT);
        table.getColumnModel().getColumn(1).setCellRenderer(right);
        table.getColumnModel().getColumn(2).setCellRenderer(right);

        ((DefaultTableCellRenderer) table.getTableHeader().getDefaultRenderer())
                .setHorizontalAlignment(JLabel.RIGHT);

        TableColumn column = table.getColumnModel().getColumn(0);
        MultiLineHeaderRenderer headerRenderer = new MultiLineHeaderRenderer(
                SwingConstants.LEFT, SwingConstants.CENTER);
        column.setHeaderRenderer(headerRenderer);

        // 把Value列设为只能输入浮点数
        column = table.getColumnModel().getColumn(1);
        JTextField textField = new JTextField();
        textField.setDocument(new DoubleDocument());
        textField.setHorizontalAlignment(JTextField.RIGHT);
        column.setCellEditor(new DefaultCellEditor(textField));

        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(
                table.getModel());
        table.setRowSorter(sorter);

        buttonAdd.setMnemonic(KeyEvent.VK_A);
        buttonAdd.setActionCommand("Add");
        buttonAdd.addActionListener(this);

        buttonDel.setMnemonic(KeyEvent.VK_D);
        buttonDel.setActionCommand("Delete");
        buttonDel.addActionListener(this);

        SymListener symListener = new SymListener();
        buttonDel.addActionListener(symListener);
        // 设置快捷键
        buttonDel.registerKeyboardAction(symListener,
                KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
                JComponent.WHEN_IN_FOCUSED_WINDOW);
        // 确定按钮为 "DELETE"

        rowIndex = table.getSelectedRow();
        System.out.println("index: " + rowIndex);
        // 监听事件
        table.getSelectionModel().addListSelectionListener(
                new ListSelectionListener() {
                    public void valueChanged(ListSelectionEvent e) {
                        if (e.getValueIsAdjusting()) {// 连续操作
                            rowIndex = table.getSelectedRow();
                            if (rowIndex != -1) {
                                System.out.println("Selected row: " + rowIndex);
                                buttonDel.setEnabled(true);
                                select = 1;
                            }
                        }
                    }
                });

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setLayout(new ScrollPaneLayout());
        scrollPane.setViewportView(table);
        scrollPane.setBounds(5, 5, 515, 350);
        this.getContentPane().add(scrollPane);

        buttonAdd.setEnabled(true);
        buttonDel.setEnabled(false);
        buttonCls.setEnabled(true);

        JPanel panel = new JPanel();
        panel.setBounds(520, 5, 10, 350);
        this.getContentPane().add(panel);

        panel.setLayout(null);
        panel.add(buttonAdd);
        buttonAdd.setSize(100, 22);
        buttonAdd.setLocation(530, 6);
        panel.add(buttonDel);
        buttonDel.setSize(100, 22);
        buttonDel.setLocation(530, 40);
        panel.add(buttonCls);
        buttonCls.setSize(100, 22);
        buttonCls.setLocation(530, 322);

        buttonCls.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                setVisible(false);
            }

            public void mousePressed(MouseEvent e) {
            }

            public void mouseReleased(MouseEvent e) {
            }

            public void mouseEntered(MouseEvent e) {
            }

            public void mouseExited(MouseEvent e) {
            }
        });

        this.pack();
    }

    public void actionPerformed(ActionEvent e) {
        buttonAdd_actionPerformed(e);
        buttonDel_actionPerformed(e);
    }

    public void buttonAdd_actionPerformed(ActionEvent e) {
        if ("Add".equals(e.getActionCommand())) {
            DefaultTableModel model = (DefaultTableModel) table.getModel();
            int rownum = table.getRowCount() + 1;
            boolean exist = false;
            for (int i = 0; i < model.getRowCount(); i++) {
                if (model.getValueAt(i, 0).equals("gvar" + rownum)) {
                    exist = true;
                    break;
                }
            }

            if (exist == false)
                model.addRow(new Object[] {
                        "gvar" + rownum,
                        0,
                        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                                .format(new Date()) });
        }
    }

    public void buttonDel_actionPerformed(ActionEvent e) {
        if ("Delete".equals(e.getActionCommand()) || e.getSource() == buttonDel) {
            if (select == 1) {
                DefaultTableModel model = (DefaultTableModel) table.getModel();
                model.removeRow(rowIndex);
                select = 0;
                buttonDel.setEnabled(false);
            }
        }
    }

    class DoubleDocument extends PlainDocument {
        private static final long serialVersionUID = 1L;

        public void insertString(int offset, String string,
                AttributeSet attributeSet) throws BadLocationException {
            try {
                int length = getLength();
                String currentContent = getText(0, length);
                StringBuffer currentBuffer = new StringBuffer(currentContent);
                currentBuffer.insert(offset, string);
                String newValue = currentBuffer.toString();
                Double.parseDouble(newValue);
            } catch (Exception ex) {
                Toolkit.getDefaultToolkit().beep();
                return;
            }
            super.insertString(offset, string, attributeSet);
        }
    }

    public static void main(String[] args) {
        new GlobalVari_13();
    }
}