java - 在具有操作和鼠标监听器的 GUI 中,未为 JTable 触发 MouseClicked

标签 java swing jtable listener jbutton

我在java swing中有一个GUI,带有JTable和JButtons,它们实现了ActionListener和MouseListener。我使用两者,因为 ActionListener 无法为 JTable 注册。如果我选择 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.
*/

最佳答案

您不需要任何地方的 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);

关于java - 在具有操作和鼠标监听器的 GUI 中,未为 JTable 触发 MouseClicked,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5895732/

相关文章:

java - Android - 释放位图内存

java - 编辑 JTable 时 vector 类类型发生变化

java - 监听器需要什么来检测 JTable 单元格是否已被双击并因此切换到编辑模式?

java - 提供的 java.sql.Connection 对象为空

java - 值对并使用第一个 java 进行排序

java - 使用java在selenium webdriver中的2个窗口之间切换

java - 使用键盘箭头在网格面板内移动 JButton

java - 如何在 Java Swing 中编写此 GUI

java - Java Applet 中的paint 和draw 方法有什么区别?

java - eclipse 中的 JTable 不显示列名