Question

I have One Jtable in which i have added JComobox like this.

TableColumn sportColumn = jTable1.getColumnModel().getColumn(2);
        comboBox = new JComboBox();
        comboBox.addItem("Snowboarding");
        comboBox.addItem("Rowing");
        comboBox.addItem("Chasing toddlers");
        comboBox.addItem("Speed reading");
        comboBox.addItem("Teaching high school");
        comboBox.addItem("None");
        sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

and i have added one mouse event of jtable like this.

private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {                                     
        // TODO add your handling code here:
        try {
            int row = jTable1.rowAtPoint(evt.getPoint());
            int col = jTable1.columnAtPoint(evt.getPoint());

            System.out.println("Row" + row + "Column" + col);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

and i am getting proper out put of row and column.enter image description here

but when i click on the cell where i added Jcombobox that time its not giving out put of that row and column. still i have called clickevent of table in combobox click event but its giving all time row 0 and even column 0 here screen shot.

enter image description here

so how do i solved it so i can have that row and column?

Was it helpful?

Solution

As I see it, you have three basic options...

You Could...

Attach a CellEditorListener to the DefaultCellEditor and monitor for editingStopped events...

editor.addCellEditorListener(new CellEditorListener() {
    @Override
    public void editingStopped(ChangeEvent e) {
        System.out.println("Editing stopped");
        TableCellEditor editor = (TableCellEditor) e.getSource();
        Object value = editor.getCellEditorValue();
        System.out.println("Selected value = " + value);
    }

    @Override
    public void editingCanceled(ChangeEvent e) {
    }
});

The problem with this, is it's not possible to actually determine the cell that's been edited. Even with a reference to the JTable, by the time you receive this event, the table is no longer in edit mode...So all you know is the value of the editor...

You Could...

Attach a TableModelListener to the TableModel...

model.addTableModelListener(new TableModelListener() {
    @Override
    public void tableChanged(TableModelEvent e) {
        int type = e.getType();
        switch (type) {
            case TableModelEvent.UPDATE:
                if (e.getFirstRow() - e.getLastRow() == 0) {
                    TableModel model = (TableModel) e.getSource();
                    int row = e.getFirstRow();
                    int col = e.getColumn();
                    System.out.println("Update " + row + "x" + col + " = " + model.getValueAt(row, col));
                }
                break;
        }
    }
});

This will let you know when the value of a cell has changed (and a lot of other things, but this is what we're interested), what it won't tell you, is why it changed.

This approach is good, because it provides all the information you need to know in order to find the value and the cell.

You Could...

Simply override the TableModel's setValueAt method and provide some sort of notification of your own...

While this is kind of duplicating the functionality of the TableModelListener you could devise the event information so that it provides more relevant information as the TableModelEvent covers a lot of user cases...

Example

Below is an example taken TableRenderDemo and modified to to demonstrate the first two concepts

import java.awt.BorderLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableModel;

/**
 * TableRenderDemo is just like TableDemo, except that it explicitly initializes
 * column sizes and it uses a combo box as an editor for the Sport column.
 */
public class TableRenderDemo extends JPanel {

    public TableRenderDemo() {
        super(new BorderLayout());

        JTable table = new JTable(new MyTableModel());
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true);

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //Set up column sizes.
        initColumnSizes(table);

        //Fiddle with the Sport column's cell editors/renderers.
        setUpSportColumn(table, table.getColumnModel().getColumn(2));

        //Add the scroll pane to this panel.
        add(scrollPane);
    }

    /*
     * This method picks good column sizes.
     * If all column heads are wider than the column's cells'
     * contents, then you can just use column.sizeWidthToFit().
     */
    private void initColumnSizes(JTable table) {
        MyTableModel model = (MyTableModel) table.getModel();
        model.addTableModelListener(new TableModelListener() {
            @Override
            public void tableChanged(TableModelEvent e) {
                int type = e.getType();
                switch (type) {
                    case TableModelEvent.UPDATE:
                        if (e.getFirstRow() - e.getLastRow() == 0) {
                            TableModel model = (TableModel) e.getSource();
                            int row = e.getFirstRow();
                            int col = e.getColumn();
                            System.out.println("Update " + row + "x" + col + " = " + model.getValueAt(row, col));
                        }
                        break;
                }
            }
        });
        TableColumn column = null;
        Component comp = null;
        int headerWidth = 0;
        int cellWidth = 0;
        Object[] longValues = model.longValues;
        TableCellRenderer headerRenderer
                        = table.getTableHeader().getDefaultRenderer();

        for (int i = 0; i < 5; i++) {
            column = table.getColumnModel().getColumn(i);

            comp = headerRenderer.getTableCellRendererComponent(
                            null, column.getHeaderValue(),
                            false, false, 0, 0);
            headerWidth = comp.getPreferredSize().width;

            comp = table.getDefaultRenderer(model.getColumnClass(i)).
                            getTableCellRendererComponent(
                                            table, longValues[i],
                                            false, false, 0, i);
            cellWidth = comp.getPreferredSize().width;

            column.setPreferredWidth(Math.max(headerWidth, cellWidth));
        }
    }

    public void setUpSportColumn(final JTable table,
                    TableColumn sportColumn) {
        //Set up the editor for the sport cells.
        JComboBox comboBox = new JComboBox();
        comboBox.addItem("Snowboarding");
        comboBox.addItem("Rowing");
        comboBox.addItem("Knitting");
        comboBox.addItem("Speed reading");
        comboBox.addItem("Pool");
        comboBox.addItem("None of the above");
        TableCellEditor editor = new DefaultCellEditor(comboBox);
        editor.addCellEditorListener(new CellEditorListener() {

            @Override
            public void editingStopped(ChangeEvent e) {
                System.out.println("Editing stopped");
                TableCellEditor editor = (TableCellEditor) e.getSource();
                Object value = editor.getCellEditorValue();
                System.out.println("Selected value = " + value);
            }

            @Override
            public void editingCanceled(ChangeEvent e) {
            }
        });
        sportColumn.setCellEditor(editor);

        //Set up tool tips for the sport cells.
        DefaultTableCellRenderer renderer
                        = new DefaultTableCellRenderer();
        renderer.setToolTipText("Click for combo box");
        sportColumn.setCellRenderer(renderer);
    }

    class MyTableModel extends AbstractTableModel {

        private String[] columnNames = {"First Name",
            "Last Name",
            "Sport",
            "# of Years",
            "Vegetarian"};
        private Object[][] data = {
            {"Kathy", "Smith",
                "Snowboarding", new Integer(5), new Boolean(false)},
            {"John", "Doe",
                "Rowing", new Integer(3), new Boolean(true)},
            {"Sue", "Black",
                "Knitting", new Integer(2), new Boolean(false)},
            {"Jane", "White",
                "Speed reading", new Integer(20), new Boolean(true)},
            {"Joe", "Brown",
                "Pool", new Integer(10), new Boolean(false)}
        };

        public final Object[] longValues = {"Jane", "Kathy",
            "None of the above",
            new Integer(20), Boolean.TRUE};

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public int getRowCount() {
            return data.length;
        }

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }

        @Override
        public Object getValueAt(int row, int col) {
            return data[row][col];
        }

        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn't implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */
        @Override
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        /*
         * Don't need to implement this method unless your table's
         * editable.
         */
        @Override
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            if (col < 2) {
                return false;
            } else {
                return true;
            }
        }

        /*
         * Don't need to implement this method unless your table's
         * data can change.
         */
        @Override
        public void setValueAt(Object value, int row, int col) {
            data[row][col] = value;
            fireTableCellUpdated(row, col);
        }
    }

    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("TableRenderDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        TableRenderDemo newContentPane = new TableRenderDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

OTHER TIPS

Using below code you can get values of selected rows and column. enter image description here

table.addMouseListener(new MouseAdapter() 
      {
        @Override
        public void mouseClicked(MouseEvent e) 
        {
            try {
                int rowss = table.rowAtPoint(e.getPoint());
                System.out.println("rowss" + rowss);
                printDebugData(table);
            } catch (ParseException ex) {
                Logger.getLogger(ShowEmployee.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

        private void printDebugData(JTable jTable1) throws ParseException
        {
              String selectedData = null;

            int numRows = jTable1.getRowCount();
            int numCols = jTable1.getColumnCount();
            int[] selectedRow = jTable1.getSelectedRows();
            int[] selectedColumns = jTable1.getSelectedColumns();
            javax.swing.table.TableModel model = jTable1.getModel();
            for (int i = 0; i < selectedRow.length; i++)
            {
                for (int j = 0; j < selectedColumns.length; j++) 
                {
                    selectedData = (String) jTable1.getValueAt(selectedRow[i], selectedColumns[j]);
                }
                System.out.println("Selected: " + selectedData);
            }
        }
        });

  }

check with mouselistner with your jtbale.

UPDATE : add this two line before printdebugdata() called.

  int rowss = table.rowAtPoint(e.getPoint());
  System.out.println("rowss" + rowss);

I got the row number check my output.

OUTPUT :

rowss0
Selected: Smith
rowss0
Selected: Smith
rowss1
Selected: Snowboarding
rowss1
Selected: Rowing
rowss1
Selected: Rowing
rowss1
Selected: Rowing
rowss2
Selected: Snowboarding
rowss2
Selected: Snowboarding
rowss2
Selected: Snowboarding
rowss2
Selected: Snowboarding

Thanks..

Well Its Little But strange for me but ya i do solved it but i dont think so that is the proper ansewer but i solved it. i called. Combo button Action Performed event and have called Mouse click of jtable in that. with null instead of the Event. check it out.

 comboBox.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
                jTable1MouseClicked(null);
            }
        });


 private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {                                     
        // TODO add your handling code here:
        try {
            //evt.getPoint();
            System.out.println("row" + jTable1.getSelectedRow());
            System.out.println("col" + jTable1.getSelectedColumn());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }                                    

may be its not Right way but i solved it this threw. its working.

best solution is

jTable1.getModel().addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                System.out.println("Changed Column"+e.getColumn());
                System.out.println("first row"+e.getFirstRow());
            }
        });

    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top