如何防止鼠标右键单击 JPopupMenu

问题描述 投票:0回答:1

我正在尝试用 Java 实现 GUI。 我将 JPopupMenu 绑定到 JTable。在 JTable 上单击鼠标右键,JPopupMenu 变得可见。

我设法阻止在 JTable 上单击鼠标左键。 我无法阻止鼠标左键单击 JPopupMenu 的任何项目。 事实上,每个 JMenuItem 都绑定到一个 ActionListener,其 actionPerformed 无法访问鼠标按钮。 我可以将 MouseListener 与 JMenuItem 关联起来吗? 如果这是不可能的,那么我怎样才能让 JPopupMenu 仅监听鼠标右键单击?

我的目标是为与 JPopupMenu 无关的其他任务保留 JTable 上的鼠标左键单击。 我想我需要将 JTable 绑定到另一个监听器。 同一个组件(JTable)可以与两个不同的监听器关联吗?

提前谢谢您。

下面我粘贴我的代码

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.border.EmptyBorder;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import java.awt.Color;
import java.awt.Font;
import java.awt.Dimension;
import java.awt.Point;
import javax.swing.UIManager;
import java.awt.Rectangle;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.border.SoftBevelBorder;
import javax.swing.border.BevelBorder;
import javax.swing.JScrollPane;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.AbstractListModel;
import javax.swing.DefaultListModel;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Component;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Vector;

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

//--------- Define ActionListener
class PopupActionListener implements ActionListener 
{
    public void actionPerformed(ActionEvent actionEvent) {
     System.out.println("Selected: " + actionEvent.getActionCommand());
}
}


public class MyNewGUI extends JFrame 
{
    
// INSTANCE VARIABLE/COMPONENTS
        private JPanel ctpMain;
        private JTextField txtNewPoint;
        private JLabel lblNewPoint;
        private JButton btnNewPoint;
        private JButton btnDeleteAll;
        private JButton btnDeleteUnused;
        private JScrollPane scrPoints;
        private JButton btnExit;
        DefaultTableModel pointsTableModel = new DefaultTableModel ();
        JTable tblPoints = new JTable(pointsTableModel);
        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem menuItemAddBefore;
        JMenuItem menuItemAddAfter;
        JMenuItem menuItemRemove;
        JMenuItem menuItemRename;

/**************************** Launch the application *********************************************/
    public static void main(String[] args) 
    {
        try 
        {
            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (Throwable e) 
        {
            e.printStackTrace();
        }
        EventQueue.invokeLater(new Runnable()
        {
            public void run() 
            {
                try
                {
                    MyNewGUI frame = new MyNewGUI();
                    frame.setVisible(true);
                } catch (Exception e) 
                {
                    e.printStackTrace();
                }
            }
        });
    }

    
//**************************  JFrame Class Constructor --> Create the frame   ***************************                                                                                                                                                                                                                                                                                                                                                        */
    public MyNewGUI() 
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(new Rectangle(10, 10, 100, 100));
        setMinimumSize(new Dimension(100, 100));
        setFont(new Font("Arial", Font.BOLD, 16));
        setBounds(1050,200,800,800);
        setTitle("MyNewGUI");
        initComponents();
        
        btnExit = new JButton("Exit GUI");
        btnExit.setFont(new Font("Arial", Font.BOLD, 16));
        btnExit.setBounds(14, 254, 101, 26);
        ctpMain.add(btnExit);
        setVisible(true);
        createEvents();
    }
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    //  This method contains all of the code for creating and initializing components
    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void initComponents()
    {
        setTitle("MyGUI");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 1041, 779);
        ctpMain = new JPanel();
        ctpMain.setBounds(new Rectangle(5, 5, 0, 0));
        ctpMain.setAlignmentY(5.0f);
        ctpMain.setAlignmentX(5.0f);
        ctpMain.setSize(new Dimension(10, 10));
        ctpMain.setPreferredSize(new Dimension(100, 100));
        ctpMain.setLocation(new Point(10, 10));
        ctpMain.setFont(new Font("Arial", Font.BOLD, 16));
        ctpMain.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
        setContentPane(ctpMain);
        
        btnNewPoint = new JButton("Add New Point");
        
        btnNewPoint.setBounds(14, 55, 167, 29);
        btnNewPoint.setFont(new Font("Arial", Font.BOLD, 16));
        
        txtNewPoint = new JTextField();
        txtNewPoint.setBounds(162, 14, 144, 29);
        txtNewPoint.setFont(new Font("Arial", Font.BOLD, 16));
        txtNewPoint.setColumns(10);
        
        lblNewPoint = new JLabel("  Point Identifier");
        lblNewPoint.setLocation(new Point(14, 19));
        lblNewPoint.setSize(new Dimension(136, 19));
        lblNewPoint.setDisplayedMnemonicIndex(1);
        lblNewPoint.setAutoscrolls(true);
        lblNewPoint.setFont(new Font("Arial", Font.BOLD, 16));
        
        JTextArea textArea = new JTextArea();
        textArea.setBounds(179, 197, 1, 16);
        textArea.setText("");
        
        JPanel pnPoints = new JPanel();
        pnPoints.setBounds(321, 21, 211, 668);
        pnPoints.setFont(new Font("Arial", Font.BOLD, 24));
        pnPoints.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null), "", TitledBorder.CENTER, TitledBorder.TOP, null, new Color(64, 0, 64)));
        ctpMain.setLayout(null);
        ctpMain.add(btnNewPoint);
        ctpMain.add(txtNewPoint);
        ctpMain.add(lblNewPoint);
        ctpMain.add(textArea);
        ctpMain.add(pnPoints);
        pnPoints.setLayout(null);
        
        scrPoints = new JScrollPane();
        scrPoints.setBounds(0, 0, 206, 668);
        pnPoints.add(scrPoints);
        
// --------- Initialize JTable Model with points fromCliff's code
        pointsTableModel.addColumn("Point Names");
        pointsTableModel.insertRow(0, new Object[] { "ONE" });
        pointsTableModel.insertRow(0, new Object[] { "TWO" });   
        pointsTableModel.insertRow(0, new Object[] { "THREE" });     
        scrPoints.setViewportView(tblPoints);
        tblPoints.setFocusable(true);
        tblPoints.setRowSelectionAllowed(true);
        tblPoints.setVisible(true);
        
        
// --------- Initialize popupMenu with items ---
        PopupListener myListener = new PopupListener();
        menuItemAddBefore = new JMenuItem("Add Point Before");
    //  menuItemAddBefore.addMouseListener(myListener);
        menuItemAddAfter = new JMenuItem("Add Point After");
    //  menuItemAddAfter.addMouseListener(myListener);
        menuItemRemove = new JMenuItem("Remove Current Point");
    //  menuItemRemove.addMouseListener(myListener);
        menuItemRename = new JMenuItem("Rename Current Point");
    //  menuItemRename.addMouseListener(myListener);
        popupMenu.add(menuItemAddBefore);
        popupMenu.add(menuItemAddAfter);
        popupMenu.add(menuItemRemove);
        popupMenu.add(menuItemRename);
        
// --------- Set popupMenu to tblPoints
        tblPoints.setComponentPopupMenu(popupMenu); 
        tblPoints.addMouseListener(myListener);
    //  tblPoints.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
                
        btnDeleteAll = new JButton("Delete All Points");
        btnDeleteAll.setFont(new Font("Arial", Font.BOLD, 16));
        btnDeleteAll.setBounds(14, 192, 167, 26);
        ctpMain.add(btnDeleteAll);
        
        btnDeleteUnused = new JButton("Delete Unused Points");
        btnDeleteUnused.setFont(new Font("Arial", Font.BOLD, 16));
        btnDeleteUnused.setBounds(14, 126, 205, 26);
        ctpMain.add(btnDeleteUnused);
    }
     
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//  This method contains all of the code for creating events
/////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void createEvents() 
    {
        
//-------- Append Point To Point Names List ------------------------------------------------------------
        btnNewPoint.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {
                String newPoint = txtNewPoint.getText();    
                pointsTableModel.addRow(new Object[] {newPoint});
                txtNewPoint.setText("");
            }
        });
        
//-------- Remove Unused Points From Point Names List ---------------------------------------------------
        btnDeleteUnused.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e)
            {
                // TO BE DEVELOPED
            }
        });

//-------- Empty Point Names List --------------------------------------------------------------------------        
        btnDeleteAll.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {
                while (pointsTableModel.getRowCount() > 0) 
                    pointsTableModel.removeRow(0);
            }
        });

//--------------- Button EXIT Handler --------------------------------------------------------------------------------------------------------------------
        btnExit.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {
                Object[] options = {"Exit Without Saving", "Exit With Saving","Cancel"};        //Custom button text
                int sel = JOptionPane.showOptionDialog(null ,
                    "Would you like to save your work before exiting ? ",
                    "EXIT WORK SESSION",
                    JOptionPane.YES_NO_CANCEL_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    null,
                    options,
                    options[2]);
// Process Customer's Selection
                if (sel == 0) 
                {
                     JOptionPane.showMessageDialog(null, "You chose to exit your work session without saving!");
                     System.exit(0);    
                }
                if(sel == 1) 
                {
                     JOptionPane.showMessageDialog(null, "You chose to save your work session before exiting !");
//                   if(lstPoints != null && !pointsTableModel.isEmpty())  // If JList contains Points
//                   {
//                       pointsList.clear();     // Empty Points storage
//                       System.out.print("\n pointsList after clear():  " + pointsList);       // DEBUG-PURPOSE
//                       System.out.print("\n pointsTableModel :  " + pointsTableModel);         // DEBUG-PURPOSE
//                       System.out.print("\n pointsTableModel size:  " + pointsTableModel.size() );        // DEBUG-PURPOSE
//                       System.out.print("\n");
//                       for(int i=0; i < pointsTableModel.size(); i++)
//                           pointsList.add(pointsTableModel.get(i));    // Move Points from JList to Points storage
//                       System.out.print("Saved Points:  " + pointsList + "\n");
//                   }else 
//                       JOptionPane.showMessageDialog(null, "Your Ponts List is empty!"); 
//                   System.exit(0);    
                }
                if(sel == 2) 
                     JOptionPane.showMessageDialog(null, "You changed your mind !");
            }
        });
        
//--------------- JMenuItem Handler To Add Item Before Selected JTable Row-------------------------------------------------------------------------------------------------------
        menuItemAddBefore.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent ev) 
            {
                int row = tblPoints.getSelectedRow();
                  if (row == -1) 
                      return;
                System.out.print("Add Point to tblPoints Before Row:  " + row + "\n");
                String precedingPointName = JOptionPane.showInputDialog("Enter Following Point Name");
                System.out.println(precedingPointName);   
                pointsTableModel.insertRow(row, new Object[] {precedingPointName});
                tblPoints.getSelectionModel().clearSelection();
            }
        }); 
                
//--------------- JMenuItem Handler To Add Item After Selected JTable Row-------------------------------------------------------------------------------------------------------
        menuItemAddAfter.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent ev) 
            {
                int row = tblPoints.getSelectedRow();
                  if (row == -1 || !tblPoints.isCellEditable(row,0)) 
                      return;
                String value = tblPoints.getValueAt(row, 0).toString(); 
                System.out.print("Add Point to tblPoints After PointName: " + value + " On  Row:  " + row + "\n");
                String followingPointName = JOptionPane.showInputDialog("Enter Following Point Name");
                System.out.println(followingPointName);   
                pointsTableModel.insertRow(row +1, new Object[] {followingPointName});
                tblPoints.getSelectionModel().clearSelection();
            }
        });         
        
//--------------- JMenuItem Handler To Remove Selected JTable Row----------------------------------------------------------------------------------------------------------------
        menuItemRemove.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent ev) 
            {
                int row = tblPoints.getSelectedRow();
                  if (row == -1) 
                      return;
                System.out.print("Remove Point at tblPoints rown:  " + row + "\n");
                pointsTableModel.removeRow(tblPoints.getSelectedRow());
                tblPoints.getSelectionModel().clearSelection();
            }
        }); 
        
//--------------- JMenuItem Handler To Rename Item At Selected JTable Row----------------------------------------------------------------------------------------------------------------
        menuItemRename.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent ev) 
            {
                int row = tblPoints.getSelectedRow();
                 if (row == -1) 
                      return;
                 System.out.print("Rename Point at tblPoints rown:  " +  row + "\n");
                 String replacingPointName = JOptionPane.showInputDialog("Enter Current Point Replacing Name");
                 tblPoints.getModel().setValueAt(replacingPointName, row, 0);
                 tblPoints.getSelectionModel().clearSelection();
            }
        });         

    }  //-----------------------------------  End Of  createEvents() Method ----------------------------------------------------------------------  
    
// ********* Inner classes *********

    public class PopupListener extends MouseAdapter
    {
         public PopupListener()                 //  Default Constructor
         {
            System.out.print("\n Default PopupListener Constructor engaged \n ");
         }
         
         public void mousePressed(MouseEvent e) 
         
         {
            if(e.getButton() == MouseEvent.BUTTON3)
            {
                  Point p = e.getPoint();
                  Component c = e.getComponent();
                  int row = tblPoints.rowAtPoint(p);
                  System.out.print("\n `Selected row:  " + row + "\n");
                  if (row == -1)
                  {
                      tblPoints.getSelectionModel().clearSelection();
                      return;
                  }
                  else
                      tblPoints.setRowSelectionInterval(row, row);
            }
            else
                tblPoints.getSelectionModel().clearSelection();
         }
     }
}
java jtable actionlistener mouselistener
1个回答
0
投票

在显示弹出菜单之前,如果鼠标指针下方的行尚未选择,您似乎需要右键单击以选择表格行。

为此,您应该删除

tblPoints.setComponentPopupMenu(popupMenu);
并使用您自己的 MouseListener 和键映射自行显示 JPopupMenu。通常,setComponentPopupMenu 会处理所有这些,但您需要自定义该行为。

MouseListener mousePopupListener = new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent event) {
        showPopup(event);
    }

    @Override
    public void mouseReleased(MouseEvent event) {
        showPopup(event);
    }

    @Override
    public void mouseClicked(MouseEvent event) {
        showPopup(event);
    }

    private void showPopup(MouseEvent event) {
        int row = tblPoints.rowAtPoint(event.getPoint());
        if (row >= 0 && !tblPoints.isRowSelected(row)) {
            tblPoints.setRowSelectionInterval(row, row);
        }

        if (popupMenu.isPopupTrigger(event)) {
            popupMenu.show(tblPoints, event.getX(), event.getY());
        }
    }
};
tblPoints.addMouseListener(mousePopupListener);

响应鼠标按下、鼠标松开和鼠标单击事件至关重要,因为不同的平台对于弹出菜单有不同的行为。

但是……这还不够。 Swing 应用程序需要“可访问”,这意味着它们需要支持使用键盘来激活控件。 (例如,用户可以按 Tab 键选择某个按钮,然后按空格键来“按下”该按钮。)在大多数平台上,可以使用 PC 键盘上的菜单键(通常带有“🗉”符号)来激活弹出菜单, Java 表示为 KeyEvent.VK_CONTEXT_MENU,以及 Shift-F10。 String actionName = "showPopup"; Action keyboardMenuDisplayer = new AbstractAction(actionName) { private static final long serialVersionUID = 1; @Override public void actionPerformed(ActionEvent event) { Point location; PointerInfo info = MouseInfo.getPointerInfo(); if (info != null) { location = info.getLocation(); SwingUtilities.convertPointFromScreen(location, tblPoints); } else { int focusedRow = tblPoints.getSelectionModel().getLeadSelectionIndex(); int focusedColumn = tblPoints.getColumnModel().getSelectionModel().getLeadSelectionIndex(); if (focusedRow >= 0 && focusedColumn >= 0) { Rectangle cell = tblPoints.getCellRect(focusedRow, focusedColumn, false); location = cell.getLocation(); } else { location = new Point(); } } popupMenu.show(tblPoints, location.x, location.y); } }; tblPoints.getActionMap().put(actionName, keyboardMenuDisplayer); InputMap inputMap = tblPoints.getInputMap(JComponent.WHEN_FOCUSED); inputMap.put(KeyStroke.getKeyStroke("CONTEXT_MENU"), actionName); inputMap.put(KeyStroke.getKeyStroke("shift F10"), actionName);

© www.soinside.com 2019 - 2024. All rights reserved.