2010-08-24 5 views
27

Kurz: Ich brauche ein „Rechtsklick Ereignis“, um die Zellenreihe zu markieren.Java Swing JTable; Rechtsklick-Menü (wie bekomme ich es zu „wählen“ aka markieren Sie die Zeile)

ich in einem ScrollPane in Java Swing (Netbeans Matisse) eine JTable verwenden. Ich habe einen mouseClicked Ereignis-Listener auf dem JTable, die die folgenden:

if (evt.getButton() == java.awt.event.MouseEvent.BUTTON3) { 
      System.out.println("Right Click"); 
      JPopUpMenu.show(myJTable, evt.getX(), evt.getY()) 
} 

Das Problem ist ... wenn ich einen Rechtsklick auf der JTable ausführen, wird die Zeile nicht markiert (I um die Auswahl zu Reihen gesetzt nur übrigens). Ich habe nach mehreren setSelected() - Funktionen gesucht, konnte aber keine passende finden. Standardmäßig markiert die linke Maustaste automatisch die Zeile. Wie richte ich es für richtige Klicks ein?

Antwort

80

wie folgt aus:

table.addMouseListener(new MouseAdapter() { 
    @Override 
    public void mouseReleased(MouseEvent e) { 
     int r = table.rowAtPoint(e.getPoint()); 
     if (r >= 0 && r < table.getRowCount()) { 
      table.setRowSelectionInterval(r, r); 
     } else { 
      table.clearSelection(); 
     } 

     int rowindex = table.getSelectedRow(); 
     if (rowindex < 0) 
      return; 
     if (e.isPopupTrigger() && e.getComponent() instanceof JTable) { 
      JPopupMenu popup = createYourPopUp(); 
      popup.show(e.getComponent(), e.getX(), e.getY()); 
     } 
    } 
}); 

......

+1

Einfach so:] ... die obere Hälfte von mouseReleased() ist, was ich brauchte. Wird als Antwort gewählt und akzeptiert. Danke, du bist der Mann (oder die Frau)! –

+6

Große Antwort. Ein Detail: auf einigen Plattformen (Mac OS X, um es zu nennen), ist das Popup-Menü Auslöser von 'mousePressed' anstatt' mouseReleased' also, wenn Sie diesen Code verwenden das Popup wird nicht angezeigt, wenn Sie Ihre Anwendung auf Mac OS laufen X. – gabuzo

+0

Was ist der Zweck, den rowIndex zweimal zu erhalten? Ich meine, was ist der Unterschied zwischen * r * und * rowindex *? –

1

Die akzeptierte Antwort nehmen Modifikator nicht Tasten wie ctrl oder Verschiebung Rechnung, aber sie zeigen, dass die aktuelle Auswahl sollte nicht ersetzt werden, aber erweitert werden.

Außerdem habe ich Multi-OS-Unterstützung hinzugefügt, indem Sie mousePressedundmouseReleased überprüfen.

Im Folgenden finden Sie ein vollständiges Beispiel zur Anpassung der ausgewählten Zeilen unter Verwendung der ListSelectionModel, einschließlich MouseEvent#getModifiers Prüfungen. Danach ist es möglich, eine (optionale) JPopupMenu zu öffnen.

JPopupMenu contextMenu = new JPopupMenu(); 
// ... 
// add elements to the popup menu 
// ... 

table.addMouseListener(new MouseAdapter() { 
    @Override 
    public void mousePressed(MouseEvent e) { 
    handleRowClick(e); 
    if (e.isPopupTrigger()) { 
     doPop(e); 
    } else { 
     hidePop(); 
    } 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
    if (e.isPopupTrigger()) { 
     doPop(e); 
    } 
    } 

    private void handleRowClick(MouseEvent e) { 
    ListSelectionModel selectionModel = table.getSelectionModel(); 
    Point contextMenuOpenedAt = e.getPoint(); 
    int clickedRow = table.rowAtPoint(contextMenuOpenedAt); 

    if (clickedRow < 0) { 
     // No row selected 
     selectionModel.clearSelection(); 
    } else { 
     // Some row selected 
     if ((e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK) { 
     int maxSelect = selectionModel.getMaxSelectionIndex(); 

     if ((e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) { 
      // Shift + CTRL 
      selectionModel.addSelectionInterval(maxSelect, clickedRow); 
     } else { 
      // Shift 
      selectionModel.setSelectionInterval(maxSelect, clickedRow); 
     } 
     } else if ((e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) { 
     // CTRL 
     selectionModel.addSelectionInterval(clickedRow, clickedRow); 
     } else { 
     // No modifier key pressed 
     selectionModel.setSelectionInterval(clickedRow, clickedRow); 
     } 
    } 
    } 

    private void doPop(MouseEvent e) { 
    if (table.getSelectedRowCount() == 0) { 
     return; 
    } 
    contextMenu.setVisible(true); 
    contextMenu.show(e.getComponent(), e.getX(), e.getY()); 
    } 

    private void hidePop() { 
    contextMenu.setVisible(false); 
    } 
}); 
+0

Es gibt keine Notwendigkeit zur manuellen Auswahl Handhabung respektieren die JTable bereits SHIFT und CTRL-Tasten und so weiter. Die einzige Änderung in der ursprünglichen Lösung benötigt wird, ist nicht setRowSelectionInterval() zu verwenden, falls die fokussierte Reihe bereits ausgewählt ist, wie: wenn table.setRowSelectionInterval (r, r), (table.getSelectionModel() isSelectedIndex (r)!). –

Verwandte Themen