web-dev-qa-db-fra.com

jTable menu contextuel contextuel

J'ai une base de données SQL et je travaille sur un programme qui me permettra d'ajouter/supprimer/modifier des enregistrements. J'ai déjà réussi à ajouter des enregistrements sur lesquels je travaille pour les éditer/les supprimer.

Je veux afficher les enregistrements existants dans une table afin d'utiliser jTable. J'ai trouvé du code en ligne et je l'ai modifié pour extraire les enregistrements et les afficher dans une table mais je ne sais pas comment coder le clic droit et afficher un menu contextuel.

Dans ce menu contextuel, je souhaite afficher des options telles que supprimer un enregistrement et modifier un enregistrement.

C'est le code que j'utilise pour make the jTable et pour afficher les données:

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

Je suis nouveau sur Java, soyez donc aimable dans vos réponses. Merci à tous pour toute aide!

19

Voici un exemple sur la façon de faire cela. Le moyen le plus simple d'y parvenir est de définir directement une JPopupMenu sur le 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();
            }
        });
    }
}

Si vous souhaitez sélectionner automatiquement la ligne où le clic droit a été effectué, ajoutez l'extrait de code suivant:

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

            }
        });
35
Guillaume Polet

Un problème avec une table JTable est que le clic droit ne modifie pas la sélection de ligne. Ainsi, si vous avez une action qui fonctionne sur une ligne spécifique, vous devez d'abord cliquer sur la ligne avant de cliquer avec le bouton droit de la souris pour afficher le menu contextuel.

Si vous voulez que la ligne soit sélectionnée à l'endroit où vous cliquez avec le bouton droit de la souris, vous pouvez utiliser le code suivant:

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

un autre problème est que les menus contextuels sont dynamiques, votre solution ne traite pas de la modification du menu en fonction de la ligne cliquée

    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() 
            ...
0
fdsfdsfdsfds