简体   繁体   English

jTable右键弹出菜单

[英]jTable right-click popup menu

I have a SQL database and I am working on a program that will allow me to add/delete/modify records.我有一个 SQL 数据库,我正在开发一个允许我添加/删除/修改记录的程序。 I already managed to add records I am working on editing/deleting them.我已经设法添加我正在编辑/删除它们的记录。

I want to display the existing records in a table so I am using jTable.我想在表中显示现有记录,所以我使用 jTable。 I found some code online and modified it to pull the records and display them in a jtable but i dont know how to code the rightclick and display a popup menu.我在网上找到了一些代码并对其进行了修改以提取记录并将它们显示在 jtable 中,但我不知道如何编写右键单击代码并显示弹出菜单。

In that popup menu I want to display options such as delete record and modify record.在该弹出菜单中,我想显示删除记录和修改记录等选项。

This is the code I am using the make the jTable and display the data:这是我正在使用制作 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 );
}

I am new to Java so please be kind in your responses.我是 Java 新手,所以请善待您的回复。 Thank you all in advance for any assistance!提前感谢大家的任何帮助!

Here is an example on how to do that.这是有关如何执行此操作的示例。 The easiest way to achieve this, is to set a JPopupMenu on the JTable directly.实现这一点的最简单方法是直接在 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();
            }
        });
    }
}

In case you want to automatically select the row where the right-click was made, add the following snippet:如果要自动选择进行右键单击的行,请添加以下代码段:

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

            }
        });

A problem with a JTable is that the right click does not change the row selection. JTable 的一个问题是右键单击不会更改行选择。 So you if have an Action that works on a specific row you need to left click the row first before right clicking to have the popup menu displayed.因此,如果您有一个适用于特定行的操作,您需要先左键单击该行,然后右键单击以显示弹出菜单。

If you want the row to be selected where your right click then you can use code like the following:如果您希望在右键单击的位置选择该行,则可以使用如下代码:

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

Unfortunately, none of these solutions worked for me on both Macs and PC's.不幸的是,这些解决方案都不适用于 Mac 和 PC。 Not sure why.不知道为什么。 But this worked on both:但这对两者都有效:

@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
    int row = table.rowAtPoint(SwingUtilities.convertPoint(popup, 0, 0, table));

    if (row > -1)
        table.setRowSelectionInterval(row, row);
}

The main problem with my solution is that it doesn't show that the row is selected until after the user chooses one of the menu options.我的解决方案的主要问题是,在用户选择其中一个菜单选项之前,它不会显示该行已被选中。

Another issue is that context menus are dynamic, your solution does not deal with changing the menu depending on the clicked row另一个问题是上下文菜单是动态的,您的解决方案不会根据单击的行更改菜单

popupMenu.addPopupMenuListener(new PopupMenuListener() 
{
   @Override
   public void popupMenuWillBecomeVisible(PopupMenuEvent e) 
   { 
       int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
       generateTablePopupMenu(rowAtPoint); // here
       SwingUtilities.invokeLater(new Runnable() 
           ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM