Всплывающее меню контекстного контекстного меню jTable
У меня есть база данных SQL, и я работаю над программой, которая позволит мне добавлять/удалять/изменять записи. Мне уже удалось добавить записи, которые я работаю над редактированием/удалением их.
Я хочу отображать существующие записи в таблице, поэтому я использую 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, поэтому, пожалуйста, будьте добры в своих ответах. Спасибо всем за любую помощь!
Ответы
Ответ 1
Вот пример того, как это сделать. Самый простой способ достичь этого - установить 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
}
});
Ответ 2
Проблема с 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 );
}
}
Ответ 3
Другая проблема заключается в том, что контекстные меню являются динамическими, ваше решение не касается изменения меню в зависимости от щелкнутой строки
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()
...