2013-05-24 4 views
16

У меня есть база данных SQL, и я работаю над программой, которая позволит мне добавлять/удалять/изменять записи. Мне уже удалось добавить записи, которые я работаю над редактированием/удалением их.jTable контекстное меню правой кнопкой мыши

Я хочу отображать существующие записи в таблице, поэтому я использую jTable. Я нашел код в Интернете и изменил его, чтобы вытащить записи и отобразить их в jtable, но я не знаю, как закодировать правый клик и отобразить всплывающее меню.

В этом всплывающем меню я хочу отображать такие параметры, как удаление записи и изменение записи.

Это код, я использую сделать JTable и отображать данные:

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

Я новичок в Java, поэтому запаситесь рода в ваших ответах. Спасибо всем за любую помощь!

+0

Посмотрите на [JComponent # setComponentPopup] (http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#setComponentPopupMenu (javax .swing.JPopupMenu)) – MadProgrammer

+0

Это решение (аналогичный вопрос, который еще не связан здесь) работал лучше всего me: http://stackoverflow.com/a/17316876/411282 –

ответ

28

Вот пример того, как это сделать. Самый простой способ добиться этого - установить JPopupMenu на 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(); 
      } 
     }); 
    } 
} 

В случае, если вы хотите, чтобы автоматически выбрать строку, в которой щелчок правой кнопки мыши была сделана, добавьте следующий фрагмент кода:

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, для использования setComponentPopupMenu(), поэтому вам не нужно беспокоиться о написании MouseListener. – camickr

+0

Эта реализация не решит проблему в вопросе, поскольку она потеряла информацию о том, какую запись щелкнул пользователь. (Какой из них вы бы удалили или изменили? Где в таблице вы бы добавили?) –

+0

@JoshuaGoldberg Это зависит от вас, чтобы решить, что вы хотите с этим сделать. Обычно я предполагаю, что удаление будет происходить в выбранной строке (строках), и вставка, вероятно, будет после текущей выбранной строки. Тот факт, что щелчок правой кнопкой мыши не обязательно выбирает строку JTable, зависит от L & F. Если вы хотите, вы можете заставить это также добавить MouseListener, который изменяет выбор строки при щелчке правой кнопкой мыши. Эта реализация решит проблему в вопросе. –

14

Проблема с JTable, что правый щелчок не изменяет выбор строки. Таким образом, если у вас есть действие, которое работает в определенной строке, вам нужно щелкнуть строку сначала, прежде чем щелкнуть правой кнопкой мыши, чтобы отобразить всплывающее меню.

Если вы хотите строку следует выбрать, где ваша правая кнопка мыши, то вы можете использовать код вроде следующее:

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

другой проблема в том, что контекст меню динамики, ваше решение не имеет дело с изменением меню в зависимости от щелкнули строки

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() 
      ... 
Смежные вопросы