1

i created a java swing application that have multiple jTables. I added multiple mouse listeners for making context menu with anonymous classes. But each time the action listeners are pointing to the first table only. Please help. Each time iam getting is the updated value for first table .

  • i have 3 Jtables named jTableNum1, jTableNum2, jTableNum3.
  • what i want is cut, copy, paste function for each cell in my three Jtables.
  • so i created popumenus & called like:

     jTableNum1.addMouseListener(new MouseAdapter() {

               @Override
               public void mouseClicked(MouseEvent e) {
                     rowH = jTableNum1.getSelectedRow();
                    if (e.isPopupTrigger()) {
                       highlightRow(e);
                       doPopup(e);
                   }
               }

               @Override
               public void mouseReleased(MouseEvent e) {

                   if (e.isPopupTrigger()) {
                       highlightRow(e);

                       doPopup(e);
                   }
               }

               protected void doPopup(MouseEvent e) {
                  popupMenu.show(e.getComponent(), e.getX(), e.getY());
               }

               protected void highlightRow(MouseEvent e) {
                   JTable table = (JTable) e.getSource();
                   Point point = e.getPoint();
                   int row = table.rowAtPoint(point);
                   int col = table.columnAtPoint(point);

                   table.setRowSelectionInterval(row, row);
                   table.setColumnSelectionInterval(col, col);
               }

           });

   popupMenu1.add(new clearFuncs (1,rowH));// arg1=  tableNumber , arg2 = the highlighted row)

-

-// similiarly for jTableNum2 & jTableNum3

   public class clearFuncs extends AbstractAction {
   int num;
   int rowH;
   public clearFuncs (int num,int r) {
        this.num = num;
        this.rowH = r;
    putValue(NAME, "Clear");
    }public clearFuncs (int num) {
        this.num = num;
    putValue(NAME, "Clear");
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        int row;
        switch(num){
        case 1: row = jTableNum1.getSelectedRow();
        System.out.println("row = "+rowH);
        jTableNum1.setValueAt("", row, 0);
                break;
        case 2: row = jTableNum2.getSelectedRow();
        System.out.println("row = "+row);
        jTableNum2.setValueAt("", row, 0);
        break;
        case 3: row = jTableNum3.getSelectedRow();
        System.out.println("row = "+row);
        jTableNum3.setValueAt("", row, 0);
        break;

        }          
    }

}               

-

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
Syamili V
  • 53
  • 1
  • 10
  • 4
    Some sample code would be helpful. – MD Sayem Ahmed Jul 28 '14 at 13:07
  • 3
    Welcome to Stack Overflow... http://stackoverflow.com/help/mcve ... http://stackoverflow.com/help/how-to-ask – Paul Samsotha Jul 28 '14 at 13:08
  • @peeskillet i am new to this site. Please help. ( also tried my best to align the code) – Syamili V Jul 28 '14 at 13:54
  • Your problem is for table2 and table3 but you've only showed us code for table1 – Paul Samsotha Jul 28 '14 at 14:05
  • Also, are these table visible all the same time? The reason I ask is, if not, generally we don't use multiple tables. We can just switch out the models. – Paul Samsotha Jul 28 '14 at 14:06
  • Also, you should post a runnable, compilable example we can test out. I don't think you've provided enough information for us to help you out. Please carefully read the link on `mcve` and try to create one. If something in your code is not obvious enough to spot, it helps if there is enough code for us to run and test – Paul Samsotha Jul 28 '14 at 14:07
  • Thanks for the reply..for the code, all the time the listeners point to firstly added table actions. So, if i add jTableNum3 first then that table keeps working fine and rest all with no changes... – Syamili V Jul 28 '14 at 14:13
  • Also if you are using the same `clearFunct` for all the popups, your problem makes sense. you are pointing to the same table1 in the code. Maybe you want to pass a table to action constructor and use that _referenced_ table. That way you can use the same action for all the popups – Paul Samsotha Jul 28 '14 at 14:13
  • You could also just create a mouse adapter class and use it for all the table, to keep from repetitive code. – Paul Samsotha Jul 28 '14 at 14:17
  • can you please give an example... – Syamili V Jul 28 '14 at 14:19

1 Answers1

3

I problem I see is that you are referencing the first table in the Action ClearFuncs. You could easily convert to a generic Action the will be used for all tables. Also same with the MouseAdapter. It couls easily be reconfigured to be used for all the tables, so to avoid repetition. See the example below where I do this. Leave a comment if you have any questions.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;

public class TableContextMenuDemo {

    @SuppressWarnings("serial")
    private JTable createTableWithRandomData(int tableNumber) {
        String[] cols = { "col 1", "col 2", "col 3" };
        JTable table = new JTable(new DefaultTableModel(getRandomData(10,
                cols.length), cols)) {
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(200, 150);
            }
        };
        ClearFuncs action1 = new ClearFuncs(tableNumber, table);
        SayHelloAction action2 = new SayHelloAction();
        JPopupMenu popupMenu = createPopupMenu(action1, action2);
        PopupAdapter listener = new PopupAdapter(popupMenu);
        table.addMouseListener(listener);
        return table;
    }

    class SayHelloAction extends AbstractAction {
        public SayHelloAction() {
            putValue(NAME, "Hello");
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Hello World");

        }
    }

    private Integer[][] getRandomData(int rows, int cols) {
        Random random = new Random();
        Integer[][] data = new Integer[rows][cols];
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                data[i][j] = random.nextInt(Integer.MAX_VALUE);
            }
        }
        return data;
    }

    private JPopupMenu createPopupMenu(Action... actions) {
        JPopupMenu menu = new JPopupMenu();
        for (Action a : actions) {
            menu.add(a);
        }
        return menu;
    }

    class PopupAdapter extends MouseAdapter {
        JPopupMenu popupMenu;

        public PopupAdapter(final JPopupMenu popupMenu) {
            this.popupMenu = popupMenu;
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.isPopupTrigger()) {
                highlightRow(e);
                doPopup(e);
            }
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            if (e.isPopupTrigger()) {
                highlightRow(e);
                doPopup(e);
            }
        }

        protected void doPopup(MouseEvent e) {
            popupMenu.show(e.getComponent(), e.getX(), e.getY());
        }

        protected void highlightRow(MouseEvent e) {
            JTable table = (JTable) e.getSource();
            Point point = e.getPoint();
            int row = table.rowAtPoint(point);
            int col = table.columnAtPoint(point);

            table.setRowSelectionInterval(row, row);
            table.setColumnSelectionInterval(col, col);
        }

    }

    class ClearFuncs extends AbstractAction {
        int num;

        private JTable table;

        public ClearFuncs(int num, JTable table) {
            this.num = num;
            this.table = table;
            putValue(NAME, "Clear");
        }

        public ClearFuncs(int num) {
            this.num = num;
            putValue(NAME, "Clear");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            int col = table.getSelectedColumn();
            int row = table.getSelectedRow();
            System.out.println("row = " + row + ", col = " + col + ", table: " + num);
            table.setValueAt("", row, col);
        }
    }

    private void createAndShowGui() {
        JFrame frame = new JFrame();
        frame.setLayout(new FlowLayout());
        for (int i = 1; i <= 3; i++) {
            JTable table = createTableWithRandomData(i);
            JScrollPane scrollPane = new JScrollPane(table);
            scrollPane
                    .setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
            frame.add(scrollPane);
        }
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TableContextMenuDemo().createAndShowGui();
            }
        });
    }
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Can you give some links on the topics like mouse listeners, MouseAdapter PopupAdapter. PLease – Syamili V Jul 29 '14 at 02:13
  • lol PopupAdapter is my own class I just made up that extends MouseAdapter. The code is really no difference from hw you coded the anonymous class, but I created a spearate class and passed the JPopupMenu to it, so it could be referenced. But yeah, see [Writing Event Listeners](http://docs.oracle.com/javase/tutorial/uiswing/events/index.html) for a full list of tutorials for the different kinds of listeners for swing – Paul Samsotha Jul 29 '14 at 02:14
  • ok .. for adding one more menu for my right click where should i add the function.(how to call the table listener) – Syamili V Jul 29 '14 at 02:23
  • If you look at my `createPopupMenu` method, you can see that it takes a varargs of `Action` instances. I call this method `createTableWithRandomData` but I only pass one `Action`, which is the `ClearFuncs` instance. You can pass more then once Action to it. Also see more at [How to use Menus](http://docs.oracle.com/javase/tutorial/uiswing/components/menu.html) – Paul Samsotha Jul 29 '14 at 02:26
  • Is it like this: " table.addMouseListener(new PopupAdapter(createPopupMenu(new ClearFuncs(tableNumber, table),new renameFuncs(tableNumber, table )));" – Syamili V Jul 29 '14 at 02:37
  • See my edited code. I made it a little easier to read. And I added another Action. But yeah, you got the idea, as long as `renameFuncts` is an `Action` that has a constructor that accepts those parameters you're using – Paul Samsotha Jul 29 '14 at 02:42
  • can i ask for one more help, how to create a rename function in a cell of a JTable. – Syamili V Jul 29 '14 at 02:55
  • You should post another question. Different questions should be put into different topics, so each question is available to all. If everyone were to keep asking different questions on the same post, it would become more of a help desk site. So ask another question. And make sure you include detail, so the question isn't closed, as this one initially was. If I don't have time to get to it, there are a lot of users here that are more than capable, provided you've given information to go off of. Keep in mind this site is not a code factory either, so people want to see your attempt. Cheers! – Paul Samsotha Jul 29 '14 at 02:59