JTable mit JPopupMenu

Wie kann ich das Auslösen und JPopupMenu nur verhindern, wenn JTable'Row über ausgewähltem JTable'Row

meine getBounds : wenn gibt es einen anderen weg als getBounds aus der ausgewählten Zeile und ermitteln / vergleichen das mit getBounds

Mein einfacher Sscce zeigte nur einen unerwünschten Status, jede Zeile konnte ausgewählt werden und JPopupMenu von JTable ausgetriggers

 import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; public class TableCheckBox extends JFrame { private static final long serialVersionUID = 1L; private JTable table; public TableCheckBox() { Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"}; Object[][] data = { {"Buy", "IBM", new Integer(1000), new Double(80.50), false}, {"Sell", "MicroSoft", new Integer(2000), new Double(6.25), true}, {"Sell", "Apple", new Integer(3000), new Double(7.35), true}, {"Buy", "Nortel", new Integer(4000), new Double(20.00), false} }; DefaultTableModel model = new DefaultTableModel(data, columnNames); table = new JTable(model) { private static final long serialVersionUID = 1L; @Override public Class getColumnClass(int column) { return getValueAt(0, column).getClass(); } }; table.setPreferredScrollableViewportSize(table.getPreferredSize()); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane); createPopupMenu(); } private void createPopupMenu() { JPopupMenu popup = new JPopupMenu(); JMenuItem myMenuItem1 = new JMenuItem("cccccccccccccccccccccc"); JMenuItem myMenuItem2 = new JMenuItem("bbbbbbbbbbbbbbbbbbbbbb"); popup.add(myMenuItem1); popup.add(myMenuItem2); MouseListener popupListener = new PopupListener(popup); table.addMouseListener(popupListener); } private class PopupListener extends MouseAdapter { private JPopupMenu popup; PopupListener(JPopupMenu popupMenu) { popup = popupMenu; } @Override public void mousePressed(MouseEvent e) { maybeShowPopup(e); } @Override public void mouseReleased(MouseEvent e) { if (table.getSelectedRow() != -1) { maybeShowPopup(e); } } private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { popup.show(e.getComponent(), e.getX(), e.getY()); } } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { TableCheckBox frame = new TableCheckBox(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); frame.pack(); frame.setLocation(150, 150); frame.setVisible(true); } }); } } 

   

Es ist eine interessante Frage, weil es fehlende API auf JComponent hervorhebt 🙂

Wie wir alle wissen, ist die empfohlene Methode zur Registrierung von popupMenus die Verwendung der componentPopupMenu-Eigenschaft. Verwandte API ist

  void setComponentPopupMenu(JPopupMenu); JPopupMenu getComponentPopupMenu(); Point getPopupLocation(MouseEvent); 

Was fehlt (und eigentlich für diese Anforderung benötigt wird) ist

 JPopupMenu getComponentPopupMenu(MouseEvent); 

Dieser Mangel ist umso ärgerlicher, als getPopupLocation (nach AWTEventHelper tief im LAF) nach getComponentPopup () aufgerufen wird. Es gibt also keinen Spielraum für einen Hack wie das Speichern des letzten Mausereignisses, das das Popup ausgetriggers haben könnte, und dann die Entscheidung, ob ein Popup zurückgegeben werden soll. Wenn Sie null für den Standort angeben, wird dies nur an der Mausposition angezeigt

Der einzige (schmutzige) Hack (um meine völlige Unlust, sich mit einem MouseListener die Hände schmutzig zu machen 😉 ist, getComponentPopup zu überschreiben und dort zu entscheiden, ob er es basierend auf der aktuellen Mausposition zurückgeben soll oder nicht

  table = new JTable(model) { /** * @inherited 

*/ @Override public JPopupMenu getComponentPopupMenu() { Point p = getMousePosition(); // mouse over table and valid row if (p != null && rowAtPoint(p) >= 0) { // condition for showing popup triggered by mouse if (isRowSelected(rowAtPoint(p))) { return super.getComponentPopupMenu(); } else { return null; } } return super.getComponentPopupMenu(); } };

Der Nebeneffekt ist, dass die Popup-Darstellung nicht von der Tastatur ausgetriggers wird, solange sich die Maus irgendwo über dem Tisch befindet, was ein Problem sein könnte oder nicht.

Suchst du vielleicht so etwas?

Nur Popup über ausgewählte Zeile (n) anzeigen

  private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { // get row that pointer is over int row = table.rowAtPoint(e.getPoint()); // if pointer is over a selected row, show popup if (table.isRowSelected(row)) { popup.show(e.getComponent(), e.getX(), e.getY()); } } } 

Oder umgekehrt, um zu verhindern, dass Popup nur über ausgewählte Zeilen angezeigt wird:

  private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { int row = table.rowAtPoint(e.getPoint()); int[] selectedRows = table.getSelectedRows(); if (!table.isRowSelected(row)) { popup.show(e.getComponent(), e.getX(), e.getY()); } }