java - JTable + JPopupMenu + ActionListener = 噩梦

标签 java swing awt actionlistener actionevent

我的主类是一个包含图形组件的窗口,其中包括 JTable

我创建了一个公共(public)类ContextMenu,它是JPopupMenu的自定义实现,并包含多个JMenuItem

我已在 JTable 上注册了一个 mouseListener,以便在检测到右键单击时显示 ContextMenu 的实例。

问题如下:“如何根据所选的 JMenuItem 将所选行传递给不同的函数?”

显而易见的答案是在我的 JMenuItem 上设置 ActionListener,但请记住 JTableJPopupMenu 位于不同的类/对象中。

一些代码片段胜过一千个字。

public class Tab implements ITab {
private ContextMenu contextMenu;
private JTable table;
private List<SomeObject> toProcess;
--- code --
private JScrollPane drawScrollTable() {
        Object columns[] = {
            "something",
            "somethingElse"
        };
        Object rows[][] = {};
        table = new JTable(new DefaultTableModel(rows, columns));
        JScrollPane scrollPane = new JScrollPane(table);

        table.setSelectionForeground(Color.BLACK);
        table.addMouseListener(new MouseAdapter() {         
            @Override
            public void mouseReleased(MouseEvent e) { 
                int selectedRow = table.rowAtPoint(e.getPoint());

                if (selectedRow >= 0 && selectedRow < table.getRowCount()) {
                    if (!table.getSelectionModel().isSelectedIndex(selectedRow)) {
                        table.setRowSelectionInterval(selectedRow, selectedRow);
                    }
                }

                if (e.isPopupTrigger() && e.getComponent() instanceof JTable) {  
                    this.show(e);
                }
            }

            private void show(MouseEvent e){
                contextMenu.show(e.getComponent(), e.getX(), e.getY());
            }
        });

        return scrollPane;
    }
-- code --
}

public class ContextMenu extends JPopupMenu {
    JMenuItem item;

    public ContextMenu(IBurpExtenderCallbacks callbacks){
        this.item= new JMenuItem("item");

        this.item(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {     
                 // Do action involving the selected row, even better if possible action involving the value hold in the column 0 of the selected row and the toProcess private field 
            }
        });

        add(item);
    }
}

我不知道我的要求是否可行。

最佳答案

MouseListener 应该收集 ContextMenu 的所有相关信息,将其打包在传输(内部私有(private)?)类中,并在实际显示之前传递此信息打开上下文菜单。

    table.addMouseListener(new MouseAdapter() {         
        @Override
        public void mouseReleased(MouseEvent e) { 
            int selectedRow = table.rowAtPoint(e.getPoint());

            if (selectedRow >= 0 && selectedRow < table.getRowCount()) {
                if (!table.getSelectionModel().isSelectedIndex(selectedRow)) {
                    table.setRowSelectionInterval(selectedRow, selectedRow);
                }
            }

            if (e.isPopupTrigger() && e.getComponent() instanceof JTable) {  
                this.show(e);
            }
        }

        private void show(MouseEvent e){
            int clickedRow=table.rowAtPoint(e.getPoint());
            int clickedCol=table.columnAtPoint(e.getPoint());
            Object data=table.getValueAt(row, i);

            DataClickedOnTable transportMeThere=new DataClickedOnTable(
              table, data, clickedRow, clickedColumn
            );
            contextMenu.setDataFromTable(transportMeThere);
            contextMenu.show(e.getComponent(), e.getX(), e.getY());
        }
    });
   ///....
   ///...


// Just an example of structure transporting the data
// Add whatever data members are relevant
private /* inner */ class DataClickedOnTable {
   public TestTable source;
   public Object data;
   public int row;
   public int column;

   public DataClickedOnTable(
     TestTable source, Object data, int row, int col
   ) {
     this.source=source;
     this.data=data;
     this.col=col;
     this.row=row;
   }
}
public class ContextMenu extends JPopupMenu {
    JMenuItem item1;
    JMenuItem item2; 

    Object dataFromTable; // make it an Integer 

    public ContextMenu(IBurpExtenderCallbacks callbacks){
        this.item1 = new JMenuItem("item");
        this.item2 = new JMenuItem("item");

        this.item1(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {     
                // You already have the relevant data in the dataFromTable
                // Do want you need in this context
            }
        });
        this.item2(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {     
                // You already have the relevant data in the dataFromTable
                // Do want you need to do in this context
            }
        });

        add(item1);
        add(item2);
    }

    void setDataFromTable(DataClickedOnTable data) {
      this.dataFromTable=data;
      // filter possible actions based on the received data - some
      // actions are possible, some won't.
      // Example:
      this.item1.setEnabled(null!=data && (data.row % 2)==0);
      this.item2.setEnabled(
            null!=data 
         && ((data.row % 2)==1 || data.data instanceof Number)
      );

    }
}

关于java - JTable + JPopupMenu + ActionListener = 噩梦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39926571/

相关文章:

java - java中对对象进行排序后存储排序顺序

java - 为什么我的 android Activity 执行如此缓慢?

java - 如何使用线程在java中暂停执行

java - 单击告诉它重新绘制的按钮后 Canvas 不会更新

java - hibernate映射xml有什么问题?

java - 使用 Java 批量上传到 Box*

java - JFrame背景图像设置背景图像时,其他按钮不会出现在框架上?

java - 在 Jtable 中重复按下箭头键

java - 检查矩形是否与文本相交

java - JFileChooser 和 FileDialog 的 UIManager 键是什么?