2013-05-24 80 views
16

Tôi có cơ sở dữ liệu SQL và tôi đang làm việc trên một chương trình cho phép tôi thêm/xóa/sửa đổi bản ghi. Tôi đã quản lý để thêm bản ghi tôi đang làm việc để chỉnh sửa/xóa chúng.jTable nhấp chuột phải vào trình đơn bật lên

Tôi muốn hiển thị các bản ghi hiện có trong một bảng để tôi đang sử dụng jTable. Tôi tìm thấy một số mã trực tuyến và sửa đổi nó để kéo các hồ sơ và hiển thị chúng trong một jtable nhưng tôi không biết làm thế nào để mã các rightclick và hiển thị một popup menu.

Trong trình đơn bật lên đó, tôi muốn hiển thị các tùy chọn như xóa bản ghi và sửa đổi bản ghi.

Đây là mã Tôi đang sử dụng làm cho JTable và hiển thị dữ liệu:

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); 
} 

Tôi mới vào Java vì vậy hãy loại trong phản ứng của bạn. Cảm ơn tất cả các bạn trước để được hỗ trợ!

+0

Hãy xem [JComponent # setComponentPopup] (http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#setComponentPopupMenu (javax .swing.JPopupMenu)) – MadProgrammer

+0

Giải pháp này (câu hỏi tương tự chưa được liên kết ở đây) hoạt động tốt nhất cho tôi: http://stackoverflow.com/a/17316876/411282 –

Trả lời

28

Dưới đây là ví dụ về cách thực hiện điều đó. Cách dễ nhất để đạt được điều này là đặt trực tiếp số JPopupMenu trên JTable.

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(); 
      } 
     }); 
    } 
} 

Trong trường hợp bạn muốn tự động chọn hàng nơi nhấp chuột phải được thực hiện, hãy thêm đoạn sau:

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, để sử dụng setComponentPopupMenu() để bạn không phải lo lắng về việc viết một MouseListener. – camickr

+0

Việc triển khai này sẽ không giải quyết được vấn đề trong câu hỏi, bởi vì nó bị mất thông tin về bản ghi mà người dùng đã nhấp chuột phải. (Bạn sẽ xóa/sửa đổi cái nào? Bạn sẽ thêm vào đâu trong bảng?) –

+0

@JoshuaGoldberg Đó là tùy thuộc vào bạn để quyết định bạn muốn làm gì với điều này. Thông thường, tôi đoán rằng việc xóa sẽ xảy ra trên (các) hàng đã chọn và việc chèn có thể là sau hàng được chọn hiện tại. Thực tế nhấp chuột phải không nhất thiết phải chọn hàng của JTable là L & F phụ thuộc. Nếu muốn, bạn có thể ép buộc điều đó bằng cách thêm một MouseListener thay đổi lựa chọn hàng trên nhấp chuột phải. Việc thực hiện này sẽ giải quyết vấn đề trong câu hỏi. –

14

Một vấn đề với một JTable là click chuột phải không thay đổi lựa chọn hàng. Vì vậy, nếu bạn có một hành động hoạt động trên một hàng cụ thể, bạn cần phải nhấp chuột trái vào hàng đầu tiên trước khi nhấp chuột phải để hiển thị menu bật lên.

Nếu bạn muốn hàng được lựa chọn nơi click chuột phải của bạn thì bạn có thể sử dụng mã như sau:

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

một vấn đề khác là bối cảnh các menu được động lực, giải pháp của bạn không đối phó với thay đổi menu tùy thuộc vào hàng nhấp

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() 
      ... 
Các vấn đề liên quan