Search code examples
javaswingjtablejpopupmenufocuslistener

Incorrectly displaying data using JTable+focusLost()


I want to display correctly in the textbox data when selecting any rows from multiple tables.

  • When I right-click on any row of Table 1 I get table1: 1. If I click on any row of Table 2 I also get table1: 1 (but it should be table2: 1. ) .
  • When I left-click on the table 1 or 2 and then right-click I do not get any result.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class FocusTable extends JFrame {

    private JPanel contentPane;
    private JTextField textField; //Show selected row data here
    private JTable table1;
    private JTable table2;
    private JTable table3;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    FocusTable frame = new FocusTable();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public FocusTable() {
        setTitle("Test Focus Lost Table");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        textField = new JTextField();
        contentPane.add(textField, BorderLayout.SOUTH);
        textField.setColumns(10);

        JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        contentPane.add(tabbedPane, BorderLayout.CENTER);

        //----------------Create JPopupMenu-----------------
        JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem menuItemOpen = new JMenuItem("Show!");
        popupMenu.add(menuItemOpen);
        //---------------------------------------------------

        table1 = new JTable();
        table1.setComponentPopupMenu(popupMenu);
            //Show menu by pressing the right button
        table1.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {

                if (SwingUtilities.isRightMouseButton( e )) {
                    Point point = e.getPoint();
                    int column = table1.columnAtPoint(point);
                    int row = table1.rowAtPoint(point);
                    table1.changeSelection(row, column, false, false);
                }
            }
        });
            //Clear selected row
        table1.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                //textField.setText("Focus Lost table 1");
                table1.clearSelection();
            }
        });
            //Default model of Table 1
        table1.setModel(new DefaultTableModel(
            new Object[][] {
                {"table1: 1", null, null, null, null},
                {"table1: 2", null, null, null, null},
                {"table1: 3", null, null, null, null},
                {"table1: 4", null, null, null, null},
                {"table1: 5", null, null, null, null},
                {"table1: 6", null, null, null, null},
                {"table1: 7", null, null, null, null},
                {"table1: 8", null, null, null, null},
                {"table1: 9", null, null, null, null},
            },
            new String[] {
                "New column", "New column", "New column", "New column", "New column"
            }
        )
        @Override
        public boolean isCellEditable(int row, int column) {
           //all cells false
           return false;
        }   
    });
        tabbedPane.addTab("TabTable1", null, table1, null);

        table2 = new JTable();
        table2.setComponentPopupMenu(popupMenu);
            //Show menu by pressing the right button
        table2.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {

                if (SwingUtilities.isRightMouseButton( e )) {
                    Point point = e.getPoint();
                    int column = table2.columnAtPoint(point);
                    int row = table2.rowAtPoint(point);
                    table2.changeSelection(row, column, false, false);
                }
            }
        });
            //Clear selected row
        table2.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                //textField.setText("Focus Lost table 2");
                table2.clearSelection();
            }
        });
            //Default model of Table 2
        table2.setModel(new DefaultTableModel(
            new Object[][] {
                {null, "table2: 1", null, null, null},
                {null, "table2: 2", null, null, null},
                {null, "table2: 3", null, null, null},
                {null, "table2: 4", null, null, null},
                {null, "table2: 5", null, null, null},
                {null, "table2: 6", null, null, null},
                {null, "table2: 7", null, null, null},
                {null, "table2: 8", null, null, null},
                {null, "table2: 9", null, null, null},
            },
            new String[] {
                "New column", "New column", "New column", "New column", "New column"
            }
        ){
        @Override
        public boolean isCellEditable(int row, int column) {
           //all cells false
           return false;
        }   
    });
        tabbedPane.addTab("TabTable2", null, table2, null);

        table3 = new JTable(); 
            //Clear selected row when focus lost        
        table3.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                table2.clearSelection();
            }
        });
            //Show menu by pressing the right button
        table3.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {

                if (SwingUtilities.isRightMouseButton( e )) {
                    Point point = e.getPoint();
                    int column = table3.columnAtPoint(point);
                    int row = table3.rowAtPoint(point);
                    table3.changeSelection(row, column, false, false);
                }
            }
        });
        //Default model of Table 3
        table3.setModel(new DefaultTableModel(
            new Object[][] {
                {null, null, "table 3: 1", null, null},
                {null, null, "table 3: 2", null, null},
                {null, null, "table 3: 3", null, null},
                {null, null, "table 3: 4", null, null},
                {null, null, "table 3: 5", null, null},
                {null, null, "table 3: 6", null, null},
                {null, null, "table 3: 7", null, null},
                {null, null, "table 3: 8", null, null},
                {null, null, "table 3: 9", null, null},
            },
            new String[] {
                "New column", "New column", "New column", "New column", "New column"
            }
        ){
        @Override
        public boolean isCellEditable(int row, int column) {
           //all cells false
           return false;
        }   
    });
        table3.setComponentPopupMenu(popupMenu);

        tabbedPane.addTab("TabTable3", null, table3, null);

        //---------------------------Checking the selected table-------------------------------
        menuItemOpen.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(table1.getSelectedRow()!=-1){
                    textField.setText(table1.getValueAt(table1.getSelectedRow(), 0).toString());
                }else if(table2.getSelectedRow()!=-1){
                    textField.setText(table2.getValueAt(table2.getSelectedRow(), 1).toString());
                }else if(table3.getSelectedRow()!=-1){
                    textField.setText(table3.getValueAt(table3.getSelectedRow(), 2).toString());
                }
            }
        });
    }

}

Solution

  • Don't play around with the FocusListener. There is no need to clear the table selection. Users don't like to have the row selection disappear as they move from tab to tab. So get rid of the FocusListener and leave the row selection as is.

    Instead you can get the currently focused table by doing something like:

    menuItemOpen.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
    
            JMenuItem mi = (JMenuItem)e.getSource();
            JPopupMenu popup = (JPopupMenu)mi.getParent();
            JTable table = (JTable)popup.getInvoker();
    
            if (table.equals(table1))
            {
                textField.setText(table1.getValueAt(table1.getSelectedRow(), 0).toString());
            }
            else if (table.equals(table2))
            {
                textField.setText(table2.getValueAt(table2.getSelectedRow(), 1).toString());
            }
            else if (table.equals(table3))
            {
                textField.setText(table3.getValueAt(table3.getSelectedRow(), 2).toString());
            }
        }
    });