先感谢下 scbb无私的帮助!我写了个 Java的程序,里面有用到 JScrollPane。 有用到 2个按钮,其中一个是 Add,另一个是 Delete,分别对 JScrollPane 做添加行 和 删除行操作。代码如下:
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();
}
}

解决方案 »

  1.   

    操作如下:
    其中 JScrollPane 排序后会引起的程序的一个 bug。1. 用 Add按钮添加 2行数据。2. 把第一行的 value值改为 1.3. 按 value列排序。4. 用 Delete按钮删除第 2行的数据。
    这时候,bug 出现了,第一行处于被选中的状态,但是 Delete按钮不起作用了,用定义好的快捷键 alt+D 或键盘 Delete按钮也不起作用。没有搞明白。请达人指点迷津。十分感谢!
      

  2.   

    操作如下:
    其中 JScrollPane 排序后会引起的程序的一个 bug。1. 用 Add按钮添加 2行数据。2. 把第一行的 value值改为 1.3. 按 value列排序。4. 用 Delete按钮删除第 2行的数据。
    这时候,bug 出现了,第一行处于被选中的状态,但是 Delete按钮不起作用了,用定义好的快捷键 alt+D 或键盘 Delete按钮也不起作用。没有搞明白。请达人指点迷津。十分感谢!
      

  3.   

    操作如下:
    其中 JScrollPane 排序后会引起的程序的一个 bug。1. 用 Add按钮添加 2行数据。2. 把第一行的 value值改为 1.3. 按 value列排序。4. 用 Delete按钮删除第 2行的数据。
    这时候,bug 出现了,第一行处于被选中的状态,但是 Delete按钮不起作用了,用定义好的快捷键 alt+D 或键盘 Delete按钮也不起作用。没有搞明白。请达人指点迷津。十分感谢!
      

  4.   

    baidu真烂呀,操作如下:
    其中 JScrollPane 排序后会引起的程序的一个 bug。1. 用 Add按钮添加 2行数据。2. 把第一行的 value值改为 1.3. 按 value列排序。4. 用 Delete按钮删除第 2行的数据。
    这时候,bug 出现了,第一行处于被选中的状态,但是 Delete按钮不起作用了,用定义好的快捷键 alt+D 或键盘 Delete按钮也不起作用。没有搞明白。请达人指点迷津。十分感谢!
      

  5.   


    ldh911, 我一直没搞懂,我现在的这个 JFrame, 用布局管理器怎么画呢?
      

  6.   


    ldh911, 我一直没搞懂,我现在的这个 JFrame, 用布局管理器怎么画呢?
      

  7.   


    那你帮我搞定好不,真的有bug
      

  8.   

    我没有宝宝那么有耐心帮你改好啦~我告诉你错在哪吧
    你是通过select来判断是否被选中的,但是select是你自己设定的一个变量,select在你删除第2个的时候被置0了,所以删除不了,你编辑下第一行就可以删了~因为select在你编辑结束后置1。
    当然这不是你想要的结果,所以不要用你自己设定的变量来判断是否选中!
    找找看有没selectIndex()这样的方法吧,要不你等宝宝来?我要下班咯亲
      

  9.   

    好吧~帮你找到了 Jtable.getSelectedRow()这个方法~
    没事翻翻API对你有好处~
      

  10.   

    哦,好吧。我先找找看。Thanks a million!
      

  11.   

            buttonCls.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
    buttonDel_actionPerformed(e);
    }        
            });

            this.pack();
    红色为添加的代码。    public void actionPerformed(ActionEvent e) {
            buttonAdd_actionPerformed(e);
            //buttonDel_actionPerformed(e);
        }
        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);
                    int row = table.getSelectedRow();
                    if (row == -1) {
                     select = 0;
                     buttonDel.setEnabled(false);
                    }

                }
            }
        }绿色为修改过的。
      

  12.   


    scbb 真是贵人相助呀,感激不尽。现在运行正常,不过scbb 给点修改的代码我还没有看懂,还在研究中。
      

  13.   

    再问一个问题好不,虽然指定了 键盘Delete 键为 按钮Delete的快捷键,但是当 JScrollPane里的第一列 Variable 或第二列 Value处于选中的状态时,按下键盘的Delete键会让光标进入到 Cell里,而不是删除那一行数据。当 JScrollPane里的第三列 Time处于选中的状态时,按下键盘的Delete键就会删除那一行数据。
    键盘的 alt + D 键就不太一样。但是当 JScrollPane里的第一列 Variable 或第二列 Value处于选中的状态时,按下键盘的alt + D 键虽然会让光标进入到 Cell里,但随后会马上删除那一行数据。
    这个有没有办法解决,让键盘的 Delete键 和 alt + D键行为完全一样呢?
      

  14.   

    再问一个问题好不,虽然指定了 键盘Delete 键为 按钮Delete的快捷键,但是当 JScrollPane里的第一列 Variable 或第二列 Value处于选中的状态时,按下键盘的Delete键会让光标进入到 Cell里,而不是删除那一行数据。当 JScrollPane里的第三列 Time处于选中的状态时,按下键盘的Delete键就会删除那一行数据。
    键盘的 alt + D 键就不太一样。当 JScrollPane里的第一列 Variable 或第二列 Value处于选中的状态时,按下键盘的alt + D 键虽然会让光标进入到 Cell里,但随后会马上删除那一行数据。
    这个有没有办法解决,让键盘的 Delete键 和 alt + D键行为完全一样呢?
      

  15.   

    宝宝果然是好人呀~~
    说下新问题吧~Delete键有他自定义的功能,虽然可以拦截,但是最好不要这样做,否则会导致你想删cell里的东西的时候把整行删了!
    其实行为不一样没什么大不了的~如果完全一样干嘛还弄两个快捷键?
      

  16.   

    哦,那好吧。这个地方不改了。那再问另外一个问题吧。现在鼠标左键双击 JScrollPane里的第一列 Variable 或者第二列 Value, 光标会进入 cell, 是落在单元格内容的最左边或者最右边。我希望改成 当鼠标左键双击 JScrollPane里的第一列 Variable 或者第二列 Value, 光标会进入 cell,而且单元格的内容是全选中状态。这个可以有办法么?
      

  17.   

    给你个思路,自己写个继承JtextField的类,监听当获得焦点时.selectAll()
    然后用这个自定义类:
    column.setCellEditor(new DefaultCellEditor(textField));
    能不能实现我就不知道了应该可以吧
    最好结个贴呗~宝宝很辛苦的~
      

  18.   

    好吧,结贴!多谢scbb大力相助!