【问题标题】:MouseClicked not triggered for JTable in a GUI with both Action and Mouse Listener带有动作和鼠标侦听器的 GUI 中的 JTable 未触发 MouseClicked
【发布时间】:2011-05-05 09:51:49
【问题描述】:

我在 java swing 中有一个带有 JTable 和 JButtons 的 GUI,它实现了 ActionListener 和 MouseListener。我同时使用这两种方法是因为 ActionListener 无法为 JTable 注册。如果我选择 JTable 的一行并按下 JButton“Delete”,则必须删除一行。这仅适用于我第一次按删除。下次我选择一行时,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.
*/

【问题讨论】:

  • 您未显示的代码有问题 ;-)
  • 更改 '.'在第 42 行的第 42 列中添加“,”。那应该可以解决问题。如果没有,请发布SSCCE。
  • 对不起,代码在这里... tableModel=new SimpleTableModel(row); //SimpleTableModel 从向量 jTable1 = new JTable(tableModel); 填充表模型jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); jScrollPane1 = 新 JScrollPane(jTable1); jTable1.addMouseListener(this); //将滚动窗格添加到此面板。添加(jScrollPane1); this.repaint();
  • @Niranjani S 请将代码编辑到您的问题中。并尽量让我们每个人都可以尝试运行并为他/她自己测试它。
  • @Niranjani 这里有一个注意事项,根据经验和我记得在某处写的内容(甚至可能是在 Java 文档中),您不应该继续使用 mouseClicked,而是使用 mousePressed 或 mouseReleased。

标签: java swing jtable listener jbutton


【解决方案1】:

你不需要在任何地方使用 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);

【讨论】:

  • @kleopatra 感谢您的即时回复。您的代码似乎第一次工作。但第二次或后续尝试总是将 selectedRow 返回为 -1。
  • @Niranjani 这可能是因为 没有 选择 - 代码删除了选定的行:-)
  • @kleopatra getSelectedRow() 的 javadoc 说它返回“第一个选定行的索引”;因此,对于随后单击按钮 Delete,getSelectedRow() 将返回 -1,即使在单击之前选择了其他有效行(删除)。
  • @Niranjani - 文档没有问题,只有您的代码有问题(请参阅我对您问题的评论)。
  • @Niranjani,你希望我做什么?让它运行是你的工作,所以第一件事就是你接受我的建议(全部!全部)。顺便说一句,您对 TableModel 的实现是完全错误的(这可能就是您认为需要重新创建完整表的原因)从简单开始,阅读教程,使用 Swing 附带的默认类而不是滚动您自己的..
【解决方案2】:

在表选择模型上使用 ListSelectionListener 来响应选择更改,而不是 MouseListener。

【讨论】:

  • hach ... 最后必须关闭 OTN 上的灯 :-)
  • 那么鼠标监听器可能仍然有用。使用 ListSelectionListener 仅当您更改当前选定的行时,您才会获得该行。这一切都取决于我们正在实现的代码。
  • @kleopatra 是的,那里没有足够的活动让我分心:P
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-14
  • 2013-06-14
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 2013-08-22
相关资源
最近更新 更多