我在java swing中有一个GUI,它有一个JTable和JButtons,它们实现了ActionListener和MouseListener。我使用两者是因为无法为JTable注册ActionListener。如果我选择一行JTable并按下JButton“删除”,则必须删除一行。这仅适用于我第一次按删除。下次我选择一行时,似乎没有触发mouseListener。每当我点击JTable时,我都会打印所选的行号。如果我连续点击JTable,行就会被正确打印。但是,如果我按下其中一个按钮(触发ActionPerformed),然后不调用JTable mouseClicked。这里有什么问题?
先谢谢
发布代码:
private void createTable(){
tableModel=new SimpleTableModel(row);
//SimpleTableModel populates the table model from vector
jTable1 = new JTable(tableModel);
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jScrollPane1 = new JScrollPane(jTable1);
jTable1.addMouseListener(this);
//Add the scroll pane to this panel.
add(jScrollPane1);
this.repaint();
}
public void mouseClicked(MouseEvent evt) {
if (SwingUtilities.isLeftMouseButton(evt) && evt.getSource() == jTable1) {
selectedRow = jTable1.getSelectedRow();
ruleId = (String) jTable1.getValueAt(selectedRow, 0);
System.out.println("You have selected row=" + selectedRow
+ " with ruleId=" + ruleId);
}
}
更多代码(由kleopatra建议 - 我只是在方法doAction()中添加了一些更改):
private void doAction() {
Action delete = new AbstractAction("Delete Selected Row") {
@Override
public void actionPerformed(ActionEvent e) {
/*
* if (jTable1.getSelectedRow() < 0) return; int modelRowIndex =
* jTable1.convertRowIndexToModel(jTable1.getSelectedRow());
* ((DefaultTableModel)
* jTable1.getModel()).removeRow(modelRowIndex);
*
* Since I use a tableModel (which is a class named
* SimpleTableModel) that inherits AbstractTableModel,
* ClassCastException popped up. So I used normal code.
*/
selectedRow = jTable1.getSelectedRow();
System.out.println("Selected row:" + selectedRow);
if (selectedRow == -1) {
System.out
.println("Select a row in the table before clicking \"Delete\"");
return;
}
row.remove(selectedRow);
createTable();
}
};
JButton button = new JButton(delete);
}
这是完整的代码:
public class Data {
private String a;
private String b;
private String c;
private String d;
private String e;
public Data() {
}
public Data(String aa, String bb, String cc, String dd,String ee) {
setA(aa);
setB(bb);
setC(cc);
setD(dd);
setE(ee);
}
public void setA(String a) {
this.a = a;
}
public String getA() {
return a;
}
public void setB(String b) {
this.b = b;
}
public String getB() {
return b;
}
public void setC(String c) {
this.c = c;
}
public String getC() {
return c;
}
public void setD(String d) {
this.d = d;
}
public String getD() {
return d;
}
public void setE(String e) {
this.e = e;
}
public String getE() {
return e;
}
}
public class SimpleTableModel extends AbstractTableModel {
public String[] colNames = { "AA","BB","CC","DD","EE"};
public Class[] colTypes ={String.class, String.class, String.class,String.class,String.class };
Vector dataVector;
public SimpleTableModel(Vector dataVector) {
super();
this.dataVector = dataVector;
}
public int getColumnCount() {
return colNames.length;
}
public String getColumnName(int column) {
return colNames[column];
}
public int getRowCount() {
return dataVector.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Data macData = (Data) (dataVector.elementAt(rowIndex));
switch (columnIndex) {
case 0:
return macData.getA();
case 1:
return macData.getB();
case 2:
return macData.getC();
case 3:
return macData.getD();
case 4:
return macData.getE();
}
return new String();
}
}
public class DisplayGUI extends JPanel implements ActionListener {
private JTable jTable1;
private JButton jButton1;
private JScrollPane jScrollPane1;
private SimpleTableModel tableModel;
static Vector<Data> row=new Vector<Data>(10,10);
static int selectedRow;
public DisplayGUI(){
initComponents();
}
private void initComponents(){
jButton1 =new JButton();
jButton1.setText("Delete");
jButton1.addActionListener(this);
row.addElement(new Data("abc","bcd","cde","def","efg"));
row.addElement(new Data("1","2","3","4","5"));
row.addElement(new Data("10","11","12","13","14"));
createTable();
add(jButton1);
}
private void createTable() {
tableModel=new SimpleTableModel(row);
jTable1 = new JTable(tableModel);
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jScrollPane1 = new JScrollPane(jTable1);
add(jScrollPane1);
this.repaint();
}
public static void main(String[] args){
JFrame frame = new JFrame("DisplayGUI");
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
DisplayGUI newContentPane = new DisplayGUI();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.setVisible(true);
}
public void actionPerformed(ActionEvent evt){
if(evt.getSource()==jButton1){
selectedRow=jTable1.getSelectedRow();
System.out.println("You have selected "+selectedRow);
if(selectedRow==-1){
JOptionPane.showMessageDialog(this, "Select a row in the
table before clicking \"Delete\"",
"Alert!",JOptionPane.PLAIN_MESSAGE);
return;
}
row.remove(selectedRow);
createTable();
}
}
}
进行了以下更改以使我的代码正常工作:
private void initComponents(){
jButton1 =new JButton();
jButton1.setText("Delete");
jButton1.addActionListener(this);
row.addElement(new Data("abc","bcd","cde","def","efg"));
row.addElement(new Data("1","2","3","4","5"));
row.addElement(new Data("10","11","12","13","14"));
tableModel=new SimpleTableModel(row);
jTable1 = new JTable(tableModel);
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jScrollPane1 = new JScrollPane(jTable1);
add(jScrollPane1);
add(jButton1);
createTable();
}
private void createTable() {
tableModel.setDataVector(row);
//Added a setDataVector method to class Data
jTable1.setModel(tableModel);
this.repaint();
}
/*Also, added a condition jTable1.getRowCount()==0 to check for empty table before
*deleting in actionPerformed.
*/
答案 0 :(得分:3)
你不需要任何地方的MouseListener,只需让按钮的Action查询表的选择状态,如
Action delete = new AbstractAction("Delete Selected Row") {
@Override
public void actionPerformed(ActionEvent e) {
if (table.getSelectedRow() < 0) return;
int modelRowIndex = table.convertRowIndexToModel(table.getSelectedRow());
((DefaultTableModel) table.getModel().removeRow(modelRowIndex);
}
};
JButton button = new JButton(delete);
答案 1 :(得分:1)
在表选择模型上使用ListSelectionListener来响应选择更改,而不是MouseListener。