2013-05-24 11 views
16

Mam bazę danych SQL i pracuję nad programem, który pozwoli mi dodawać/usuwać/modyfikować rekordy. Udało mi się już dodać rekordy, nad którymi pracuję nad ich edytowaniem/usuwaniem.jTable menu podręczne prawym przyciskiem myszy

Chcę wyświetlić istniejące rekordy w tabeli, więc używam jTable. Znalazłem kod online i zmodyfikowałem go, aby wyciągnąć rekordy i wyświetlić je w jtable, ale nie wiem jak zakodować prawy przycisk i wyświetlić menu podręczne.

W tym menu podręcznym chcę wyświetlić opcje, takie jak usuwanie rekordu i modyfikowanie rekordu.

Jest to kod Używam uczynić JTable i wyświetlić dane:

private void menuDeleteAuthorActionPerformed(java.awt.event.ActionEvent evt) {             
    TableFromDatabase deleteAuthor = new TableFromDatabase(); 
    deleteAuthor.pack(); 
    deleteAuthor.setVisible(true); 

    Vector columnNames = new Vector(); 
    Vector data = new Vector(); 

    try 
    { 

     Connection connection = DriverManager.getConnection(url, user, password); 

     // Read data from a table 

     String sql = "SELECT * FROM Authors"; 
     Statement stmt = connection.createStatement(); 
     ResultSet rs = stmt.executeQuery(sql); 
     ResultSetMetaData md = rs.getMetaData(); 
     int columns = md.getColumnCount(); 

     // Get column names 

     for (int i = 1; i <= columns; i++) 
     { 
      columnNames.addElement(md.getColumnName(i)); 
     } 

     // Get row data 

     while (rs.next()) 
     { 
      Vector row = new Vector(columns); 

      for (int i = 1; i <= columns; i++) 
      { 
       row.addElement(rs.getObject(i)); 
      } 

      data.addElement(row); 
     } 

     rs.close(); 
     stmt.close(); 
     connection.close(); 
    } 
    catch(Exception e) 
    { 
     System.out.println(e); 
    } 

    // Create table with database data 

    JTable table = new JTable(data, columnNames) 
    { 
     public Class getColumnClass(int column) 
     { 
      for (int row = 0; row < getRowCount(); row++) 
      { 
       Object o = getValueAt(row, column); 

       if (o != null) 
       { 
        return o.getClass(); 
       } 
      } 

      return Object.class; 
     } 
    }; 

    JScrollPane scrollPane = new JScrollPane(table); 
    getContentPane().add(scrollPane); 

    JPanel buttonPanel = new JPanel(); 
    getContentPane().add(buttonPanel, BorderLayout.SOUTH); 
} 

Jestem nowy w Javie więc proszę być uprzejmy w swoich odpowiedziach. Z góry dziękuję za wszelką pomoc!

+0

Spójrz na [JComponent # setComponentPopup] (http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#setComponentPopupMenu (javax .swing.JPopupMenu)) – MadProgrammer

+0

To rozwiązanie (podobne pytanie, które nie jest jeszcze tutaj powiązane) działało najlepiej ja: http://stackoverflow.com/a/17316876/411282 –

Odpowiedz

28

Oto przykład, jak to zrobić. Najprostszym sposobem osiągnięcia tego jest ustawienie bezpośrednio na JTable JPopupMenu.

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Arrays; 
import java.util.Vector; 

import javax.swing.JFrame; 
import javax.swing.JMenuItem; 
import javax.swing.JOptionPane; 
import javax.swing.JPopupMenu; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.SwingUtilities; 

public class TestTableRightClick { 

    protected void initUI() { 
     final JFrame frame = new JFrame(TestTableRightClick.class.getSimpleName()); 
     Vector<String> columns = new Vector<String>(Arrays.asList("Name", "Age")); 
     Vector<Vector<String>> data = new Vector<Vector<String>>(); 
     for (int i = 0; i < 50; i++) { 
      Vector<String> row = new Vector<String>(); 
      for (int j = 0; j < columns.size(); j++) { 
       row.add("Cell " + (i + 1) + "," + (j + 1)); 
      } 
      data.add(row); 
     } 
     final JTable table = new JTable(data, columns); 
     final JPopupMenu popupMenu = new JPopupMenu(); 
     JMenuItem deleteItem = new JMenuItem("Delete"); 
     deleteItem.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JOptionPane.showMessageDialog(frame, "Right-click performed on table and choose DELETE"); 
      } 
     }); 
     popupMenu.add(deleteItem); 
     table.setComponentPopupMenu(popupMenu); 
     frame.add(new JScrollPane(table), BorderLayout.CENTER); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new TestTableRightClick().initUI(); 
      } 
     }); 
    } 
} 

w przypadku chcesz, aby automatycznie wybrać wiersz, gdzie prawym przyciskiem myszy została wykonana, należy dodać następujący fragment:

popupMenu.addPopupMenuListener(new PopupMenuListener() { 

      @Override 
      public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 
       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table)); 
         if (rowAtPoint > -1) { 
          table.setRowSelectionInterval(rowAtPoint, rowAtPoint); 
         } 
        } 
       }); 
      } 

      @Override 
      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void popupMenuCanceled(PopupMenuEvent e) { 
       // TODO Auto-generated method stub 

      } 
     }); 
+1

+1, za używanie setComponentPopupMenu(), więc nie musisz się martwić o pisanie MouseListener. – camickr

+0

Ta implementacja nie rozwiąże problemu w pytaniu, ponieważ utracono informacje o tym, który rekord został kliknięty prawym przyciskiem myszy. (Który z nich chciałbyś usunąć/zmodyfikować? Gdzie w tabeli mógłbyś dodać?) –

+0

@JoshuaGoldberg To zależy od Ciebie, aby zdecydować, co chcesz z tym zrobić. Zwykle domyślam się, że usunięcie wystąpiłoby w wybranych wierszach i wstawienie prawdopodobnie nastąpiłoby po aktualnie wybranym wierszu. Fakt, że kliknięcie prawym przyciskiem myszy niekoniecznie wybiera wiersz JTable jest zależny od L & F. Jeśli chcesz, możesz to również wymusić, dodając MouseListener, który zmienia wybór wiersza po kliknięciu prawym przyciskiem myszy. Ta implementacja rozwiąże problem w pytaniu. –

14

Problem z JTable jest to, że prawy przycisk myszy nie zmienia wybór wiersza. Więc jeśli masz działanie, które działa na konkretny wiersz, musisz kliknąć lewym wierszem przed prawym kliknięciem, aby wyświetlić menu podręczne.

Jeśli chcesz wiersz zostać wybrany gdzie prawym przyciskiem myszy, a następnie można użyć kodu jak poniżej:

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class TableRightClick extends JFrame implements ActionListener 
{ 
    JPopupMenu popup; 

    public TableRightClick() 
    { 
     popup = new JPopupMenu(); 
     popup.add(new JMenuItem("Do Something1")); 
     popup.add(new JMenuItem("Do Something2")); 
     popup.add(new JMenuItem("Do Something3")); 
     JMenuItem menuItem = new JMenuItem("ActionPerformed"); 
     menuItem.addActionListener(this); 
     popup.add(menuItem); 

     JTable table = new JTable(50, 5); 
     table.addMouseListener(new MouseAdapter() 
     { 
      public void mousePressed(MouseEvent e) 
      { 
       System.out.println("pressed"); 
      } 

      public void mouseReleased(MouseEvent e) 
      { 
       if (e.isPopupTrigger()) 
       { 
        JTable source = (JTable)e.getSource(); 
        int row = source.rowAtPoint(e.getPoint()); 
        int column = source.columnAtPoint(e.getPoint()); 

        if (! source.isRowSelected(row)) 
         source.changeSelection(row, column, false, false); 

        popup.show(e.getComponent(), e.getX(), e.getY()); 
       } 
      } 
     }); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     getContentPane().add(new JScrollPane(table)); 
    } 

    public void actionPerformed(ActionEvent e) 
    { 
     Component c = (Component)e.getSource(); 
     JPopupMenu popup = (JPopupMenu)c.getParent(); 
     JTable table = (JTable)popup.getInvoker(); 
     System.out.println(table.getSelectedRow() + " : " + table.getSelectedColumn()); 
    } 

    public static void main(String[] args) 
    { 
     TableRightClick frame = new TableRightClick(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
0

Inną kwestią jest to, że kontekst menu są dynamika, rozwiązanie nie dotyczy zmiana menu w zależności od klikniętego rzędu

popupMenu.addPopupMenuListener(new PopupMenuListener() 
    { 
     @Override 
     public void popupMenuWillBecomeVisible(PopupMenuEvent e) // juste pour selectionner la row quant on right click, putain de swing de merde 
     { 
      int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table)); 
      generateTablePopupMenu(rowAtPoint); <<<<<<<<<<<< here 
      SwingUtilities.invokeLater(new Runnable() 
      ... 
Powiązane problemy