仅为每行的JButton激活最后一个按钮的actionlistener

时间:2016-04-25 12:19:50

标签: java swing jtable

您好我正在编写一个小应用程序来同时ping几个主机。

正如你在下面的图片中看到的那样,我有一个带有一列按钮的jtable。我的问题如下:我使用相同的actionListener向整个列添加相同的Button。如果我单击其中一个按钮,则仅激活最后一个按钮的actionlistener,并将名称更改为单击按钮的名称。为什么?

按钮的目标是用户在第一列中插入IP地址并通过单击按钮开始ping。现在将几个ping发送到IP地址以确定其连接。如果用户插入IP地址,则表模型中的PingRow对象会正确存储地址。我在tablemodel中使用了对象而不是二维数组。

申请图片

http://i.stack.imgur.com/ONrcO.jpg

Button“neueZeilehinzufügen”的actionlistener。这意味着“添加新行”。 actionlistener实例是tablemodel中使用的PingRow对象,第二列是JButton。该操作将主机放入其actionlistener中。该动作应以某种方式获得行的正确数量或行的正确对象。在最后两行中,我向列添加了CellRenderer和Cell Editor。它们用于渲染JButton。

public class NewRow implements ActionListener{
JTable table;

Model_Main mMain;
public NewRow(JTable table_Ping, Model_Main MM) {
    table = table_Ping;
    mMain = MM;
}
@Override
public void actionPerformed(ActionEvent e) {
    //Get the tablemodel
    PingTableModel modelA = (PingTableModel) table.getModel();
    //JButton definition
    OJButton tmp = new OJButton(table.getRowCount());
    tmp.setText("Starte Ping: " + tmp.getId());
    //Instance a object for the new row
    PingRow pingRowObject = new PingRow("",tmp,0,0,table.getRowCount());
    //Instance the action
    PingAddressAction pingAddressAction = new PingAddressAction(pingRowObject);
    //Add the object to an arraylist
    mMain.getListederPingRows().add(pingRowObject);
    //Add the object to the tablemodel
    modelA.addRow(pingRowObject);
    //Rob Camick Class
    ButtonColumn buttonColumn = new ButtonColumn(table,pingAddressAction,1);
}

}

CellEditor - OJButton是一个普通的JButton,带有额外的id用于测试目的;我从Mister Camick的教程中复制了mouselistener并将其添加到JTable中。

public class JButtonEditor extends AbstractCellEditor implements TableCellEditor {
OJButton button;
String txt;

public JButtonEditor(OJButton Button, PingRow pingRowObject, JTable table, Action action) {
    super();
    button = Button;
    button.setOpaque(true);
    button.addActionListener(e1 -> {
        //TODO: Bug fixen. Wenn man zu schnell eine weitere Zeile hinzufügt wird die gleiche rowcount übergeben.
        int row = table.convertRowIndexToModel(table.getEditingRow());
        fireEditingStopped();
        //  Invoke the Action
        ActionEvent event = new ActionEvent(
                table,
                ActionEvent.ACTION_PERFORMED,
                "" + row);
        action.actionPerformed(event);
    });
}
public Component getTableCellEditorComponent(JTable table, Object value,
                                             boolean isSelected, int row, int column) {
    txt = (value == null) ? "" : value.toString();
    button.setText(txt);
    return button;
}


}

行动

public class PingAddressAction implements Action {
PingRow pingRowObject;

public PingAddressAction(PingRow pingRowObject) {
    this.pingRowObject = pingRowObject;
}

@Override
public void actionPerformed(ActionEvent e) {
    Ping_Thread ping_thread = new Ping_Thread(pingRowObject);

    if (ping_thread.isStatus()) {
        ping_thread.start();
    }
}....

解决方案

  1. 从教程中实施该课程:https://tips4java.wordpress.com/2009/07/12/table-button-column/
  2. 写一个这样的动作:

    public class PingAddressAction implements Action {
    
    @Override
    public void actionPerformed(ActionEvent e) {
    
    JTable table = (JTable) e.getSource();
    PingTableModel modelA = (PingTableModel) table.getModel();
    //Get the row number from the event actioncommand and the object from the tablemodel
    PingRow pingRowObject= modelA.getData(Integer.valueOf(e.getActionCommand()));
    //the object contains all the information from the row
    Ping_Thread ping_thread = new Ping_Thread(pingRowObject);
    
    if (ping_thread.isStatus()) {
        ping_thread.start();
    }
    }.....
    

2 个答案:

答案 0 :(得分:1)

aJTable.rowAtPoint(evt.getPoint());

答案 1 :(得分:1)

查看Table Button Column以获得更好的方法来实现JButton作为列的渲染器/编辑器。

您只需要在调用单元格的编辑器时提供要调用的Action

此外,变量名称不应以大写字符开头。其他一些变量是正确的。你的代码是一堆乱七八糟的东西,因为论坛突出了基于你没有遵循的Java约定的类/变量。