MouseClicked не запускается для JTable в графическом интерфейсе с Action и Mouse Listener - PullRequest
0 голосов
/ 05 мая 2011

У меня есть графический интерфейс в java swing с JTable и JButton, который реализует как ActionListener, так и MouseListener. Я использую оба, потому что ActionListener не может быть зарегистрирован для JTable. Если я выберу строку JTable и нажму кнопку «Удалить», строку необходимо удалить. Это работает только в первый раз, когда я нажимаю удалить. В следующий раз, когда я выберу строку, 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.
*/

Ответы [ 2 ]

3 голосов
/ 05 мая 2011

Вам нигде не нужен MouseListener, просто пусть действие кнопки запрашивает состояние выбора таблицы, что-то вроде

    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 голос
/ 05 мая 2011

Используйте ListSelectionListener в модели выбора таблиц для реагирования на изменения выбора, а не MouseListener.

...