У меня есть графический интерфейс в 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.
*/