{"id":289,"date":"2025-08-24T04:00:14","date_gmt":"2025-08-24T04:00:14","guid":{"rendered":"https:\/\/iotnoob.com\/wordpress\/?p=289"},"modified":"2025-08-25T05:10:41","modified_gmt":"2025-08-25T05:10:41","slug":"automatic-add-new-row-at-the-end-of-table","status":"publish","type":"post","link":"https:\/\/iotnoob.com\/wordpress\/2025\/08\/24\/automatic-add-new-row-at-the-end-of-table\/","title":{"rendered":"Automatic add new row at the end of table"},"content":{"rendered":"\n<p>\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e2a\u0e23\u0e49\u0e32\u0e07 JTable \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a \u0e01\u0e23\u0e2d\u0e01\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25 \u0e42\u0e14\u0e22<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0e44\u0e21\u0e48\u0e15\u0e49\u0e2d\u0e07\u0e21\u0e35\u0e1b\u0e38\u0e48\u0e21 \u0e40\u0e1e\u0e37\u0e48\u0e2d add new row,<\/li>\n\n\n\n<li>\u0e43\u0e0a\u0e49\u0e27\u0e34\u0e18\u0e35 detect \u0e27\u0e48\u0e32\u0e21\u0e35\u0e01\u0e32\u0e23\u0e43\u0e2a\u0e48\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e17\u0e35\u0e48 row \u0e27\u0e48\u0e32\u0e07\u0e17\u0e49\u0e32\u0e22\u0e15\u0e32\u0e23\u0e32\u0e07\u0e2b\u0e23\u0e37\u0e2d\u0e44\u0e21\u0e48 \u0e16\u0e49\u0e32\u0e21\u0e35\u0e43\u0e2b\u0e49\u0e40\u0e1e\u0e34\u0e48\u0e21 row \u0e43\u0e2b\u0e21\u0e48\u0e2b\u0e25\u0e31\u0e07\u0e08\u0e32\u0e01\u0e19\u0e31\u0e49\u0e19<\/li>\n\n\n\n<li>\u0e16\u0e49\u0e32\u0e21\u0e35\u0e01\u0e32\u0e23\u0e25\u0e1a\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25\u0e08\u0e19\u0e01\u0e25\u0e32\u0e22\u0e40\u0e1b\u0e47\u0e19 row \u0e27\u0e48\u0e32\u0e07 \u0e01\u0e47\u0e43\u0e2b\u0e49\u0e25\u0e1a row \u0e27\u0e48\u0e32\u0e07\u0e19\u0e31\u0e49\u0e19\u0e17\u0e34\u0e49\u0e07\u0e44\u0e1b<\/li>\n\n\n\n<li>\u0e2a\u0e23\u0e49\u0e32\u0e07 table \u0e14\u0e49\u0e27\u0e22 TableModel<\/li>\n\n\n\n<li>\u0e43\u0e2b\u0e49\u0e21\u0e35 column \u0e17\u0e35\u0e48\u0e41\u0e01\u0e49\u0e44\u0e02\u0e44\u0e14\u0e49\u0e14\u0e49\u0e27\u0e22 drowdown list<\/li>\n\n\n\n<li>\u0e43\u0e2b\u0e49 column \u0e17\u0e35\u0e48\u0e40\u0e2b\u0e25\u0e37\u0e2d\u0e41\u0e01\u0e49\u0e44\u0e02\u0e14\u0e49\u0e27\u0e22 Text Field<\/li>\n\n\n\n<li>\u0e40\u0e27\u0e25\u0e32\u0e41\u0e01\u0e49\u0e44\u0e02 \u0e40\u0e1e\u0e35\u0e22\u0e07 click \u0e17\u0e35\u0e48 cell \u0e19\u0e31\u0e49\u0e19\u0e04\u0e23\u0e31\u0e49\u0e07\u0e40\u0e14\u0e35\u0e22\u0e27\u0e01\u0e47\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e40\u0e02\u0e49\u0e32 edit mode \u0e44\u0e14\u0e49\u0e40\u0e25\u0e22<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e40\u0e1b\u0e47\u0e19 JPanel \u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e08\u0e30\u0e44\u0e14\u0e49 Add \u0e44\u0e1b\u0e43\u0e19\u0e15\u0e33\u0e41\u0e2b\u0e19\u0e48\u0e07\u0e17\u0e35\u0e48\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23 \u0e19\u0e48\u0e32\u0e08\u0e30\u0e14\u0e35\u0e01\u0e27\u0e48\u0e32\u0e2a\u0e23\u0e49\u0e32\u0e07\u0e40\u0e1b\u0e47\u0e19 JTable \u0e40\u0e1e\u0e23\u0e32\u0e30\u0e21\u0e31\u0e19\u0e22\u0e31\u0e07\u0e21\u0e35\u0e43\u0e19\u0e2a\u0e48\u0e27\u0e19\u0e02\u0e2d\u0e07 TableModel \u0e0b\u0e36\u0e48\u0e07\u0e2d\u0e32\u0e08\u0e08\u0e30\u0e21\u0e35\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19\u0e2a\u0e25\u0e31\u0e1a\u0e01\u0e31\u0e19\u0e44\u0e1b\u0e21\u0e32\u0e44\u0e14\u0e49 \u0e14\u0e31\u0e07\u0e19\u0e31\u0e49\u0e19\u0e21\u0e35 container \u0e0b\u0e31\u0e01\u0e2d\u0e31\u0e19\u0e04\u0e23\u0e2d\u0e1a\u0e21\u0e31\u0e19\u0e17\u0e31\u0e49\u0e07\u0e04\u0e39\u0e48 \u0e19\u0e48\u0e32\u0e08\u0e30\u0e14\u0e35\u0e01\u0e27\u0e48\u0e32 &#8211; \u0e41\u0e25\u0e30 JPanel \u0e19\u0e48\u0e32\u0e08\u0e30\u0e14\u0e35\u0e17\u0e35\u0e48\u0e2a\u0e38\u0e14<\/li>\n\n\n\n<li><\/li>\n<\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">tablePanel = new DrillTablePanel();\nplaceHolderPanel.add(tablePanel, BorderLayout.CENTER);<\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"402\" height=\"369\" src=\"https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-93.png\" alt=\"\" class=\"wp-image-296\" srcset=\"https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-93.png 402w, https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-93-300x275.png 300w\" sizes=\"auto, (max-width: 402px) 100vw, 402px\" \/><\/figure>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import javax.swing.*;\nimport javax.swing.event.TableModelEvent;\nimport javax.swing.event.TableModelListener;\nimport javax.swing.table.DefaultTableCellRenderer;\nimport javax.swing.table.DefaultTableModel;\nimport javax.swing.table.TableColumn;\nimport javax.swing.table.TableColumnModel;\nimport java.awt.*;\n\n\/**\n *\n * @author Thada\n *\/\npublic class DrillTablePanel extends JPanel {\n    \n    private JTable table;\n    private DefaultTableModel tableModel;\n\n    public DrillTablePanel() {\n        \/\/ \u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32 Layout \u0e02\u0e2d\u0e07 Panel \u0e19\u0e35\u0e49\n        super(new BorderLayout());\n\n        \/\/ 1. \u0e01\u0e33\u0e2b\u0e19\u0e14\u0e0a\u0e37\u0e48\u0e2d\u0e04\u0e2d\u0e25\u0e31\u0e21\u0e19\u0e4c\u0e41\u0e25\u0e30\u0e2a\u0e23\u0e49\u0e32\u0e07 TableModel\n        String[] columnNames = {\"Id\", \"Column Id\", \"Drill Type\", \"Quantity\"};\n        tableModel = new DefaultTableModel(columnNames, 0);\n\n        \/\/ 2. \u0e2a\u0e23\u0e49\u0e32\u0e07 JTable\n        table = new JTable(tableModel);\n        table.setRowHeight(30);\n        \/\/ 3. \u0e40\u0e23\u0e35\u0e22\u0e01\u0e43\u0e0a\u0e49\u0e40\u0e21\u0e18\u0e2d\u0e14\u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e15\u0e48\u0e32\u0e07\u0e46 \u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\n        addEmptyRow();\n        setupCategoryColumn();\n        setSingleClickEditing();\n        setupTableModelListener();\n        applyStyles();\n\n        \/\/ 4. \u0e2a\u0e23\u0e49\u0e32\u0e07 JScrollPane \u0e41\u0e25\u0e30\u0e43\u0e2a\u0e48\u0e15\u0e32\u0e23\u0e32\u0e07\u0e40\u0e02\u0e49\u0e32\u0e44\u0e1b\n        JScrollPane scrollPane = new JScrollPane(table);\n        scrollPane.setBorder(BorderFactory.createLineBorder(new Color(200, 200, 200)));\n\n        \/\/ 5. \u0e40\u0e1e\u0e34\u0e48\u0e21 scrollPane \u0e40\u0e02\u0e49\u0e32\u0e44\u0e1b\u0e43\u0e19 Panel \u0e19\u0e35\u0e49\n        this.add(scrollPane, BorderLayout.CENTER);\n    }\n\n    \/\/ --- Public methods (\u0e40\u0e1c\u0e37\u0e48\u0e2d\u0e04\u0e25\u0e32\u0e2a\u0e02\u0e49\u0e32\u0e07\u0e19\u0e2d\u0e01\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25) ---\n    public JTable getTable() {\n        return table;\n    }\n\n    public DefaultTableModel getTableModel() {\n        return tableModel;\n    }\n\n\n    \/\/ --- Private helper methods (Logic \u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e16\u0e39\u0e01\u0e0b\u0e48\u0e2d\u0e19\u0e44\u0e27\u0e49\u0e17\u0e35\u0e48\u0e19\u0e35\u0e48) ---\n\n    private void applyStyles() {\n        \/\/ \u0e08\u0e31\u0e14\u0e02\u0e49\u0e2d\u0e04\u0e27\u0e32\u0e21\u0e01\u0e36\u0e48\u0e07\u0e01\u0e25\u0e32\u0e07\n        DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();\n        centerRenderer.setHorizontalAlignment(JLabel.CENTER);\n\n        TableColumnModel columnModel = table.getColumnModel();\n        for (int i = 0; i &lt; columnModel.getColumnCount(); i++) {\n            columnModel.getColumn(i).setCellRenderer(centerRenderer);\n        }\n\n        \/\/ \u0e15\u0e31\u0e49\u0e07\u0e04\u0e48\u0e32\u0e2a\u0e35\u0e1e\u0e37\u0e49\u0e19\u0e2b\u0e25\u0e31\u0e07\u0e41\u0e25\u0e30 Grid\n        table.setBackground(new Color(245, 245, 245));\n        table.setShowGrid(true);\n        table.setGridColor(new Color(220, 220, 220));\n    }\n\n    private void addEmptyRow() {\n        tableModel.addRow(new Object[tableModel.getColumnCount()]);\n    }\n    \n    private void setupCategoryColumn() {\n        TableColumn categoryColumn = table.getColumnModel().getColumn(2);\n        String[] categories = {\"\", \"Mechanical\", \"Laser\", \"Back Drill\"};\n        JComboBox&lt;String> comboBox = new JComboBox&lt;>(categories);\n        categoryColumn.setCellEditor(new DefaultCellEditor(comboBox));\n    }\n\n    private void setSingleClickEditing() {\n        DefaultCellEditor singleClickEditor = new DefaultCellEditor(new JTextField());\n        singleClickEditor.setClickCountToStart(1);\n\n        for (int i = 0; i &lt; table.getColumnCount(); i++) {\n            if (i != 2) {\n                table.getColumnModel().getColumn(i).setCellEditor(singleClickEditor);\n            }\n        }\n        ((DefaultCellEditor) table.getColumnModel().getColumn(2).getCellEditor()).setClickCountToStart(1);\n    }\n    \n    private boolean isRowEmpty(int rowIndex) {\n        for (int i = 0; i &lt; tableModel.getColumnCount(); i++) {\n            Object value = tableModel.getValueAt(rowIndex, i);\n            if (value != null &amp;&amp; !value.toString().trim().isEmpty()) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    private void setupTableModelListener() {\n        tableModel.addTableModelListener(e -> {\n            if (e.getType() != TableModelEvent.UPDATE) return;\n\n            SwingUtilities.invokeLater(() -> {\n                int row = e.getFirstRow();\n                if (row >= tableModel.getRowCount()) return;\n\n                if (row == tableModel.getRowCount() - 1) {\n                    if (!isRowEmpty(row)) addEmptyRow();\n                } else {\n                    if (isRowEmpty(row)) {\n                        int choice = JOptionPane.showConfirmDialog(\n                                this, \/\/ \u0e2d\u0e49\u0e32\u0e07\u0e2d\u0e34\u0e07\u0e16\u0e36\u0e07 Panel \u0e19\u0e35\u0e49\n                                \"Drill Information is empty, Do you want to remove row\",\n                                \"Remove Row?\",\n                                JOptionPane.YES_NO_OPTION);\n                        if (choice == JOptionPane.YES_OPTION) {\n                            tableModel.removeRow(row);\n                        }\n                    }\n                }\n            });\n        });\n    }\n}<\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"595\" height=\"280\" src=\"https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-91.png\" alt=\"\" class=\"wp-image-290\" srcset=\"https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-91.png 595w, https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-91-300x141.png 300w\" sizes=\"auto, (max-width: 595px) 100vw, 595px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"595\" height=\"374\" src=\"https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-92.png\" alt=\"\" class=\"wp-image-291\" srcset=\"https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-92.png 595w, https:\/\/iotnoob.com\/wordpress\/wp-content\/uploads\/2025\/08\/image-92-300x189.png 300w\" sizes=\"auto, (max-width: 595px) 100vw, 595px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>\u0e15\u0e49\u0e2d\u0e07\u0e01\u0e32\u0e23\u0e2a\u0e23\u0e49\u0e32\u0e07 JTable \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a \u0e01\u0e23\u0e2d\u0e01\u0e02\u0e49\u0e2d\u0e21\u0e39\u0e25 \u0e42\u0e14\u0e22<\/p>\n","protected":false},"author":1,"featured_media":292,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,2],"tags":[],"class_list":["post-289","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","category-programming"],"_links":{"self":[{"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/posts\/289","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/comments?post=289"}],"version-history":[{"count":3,"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/posts\/289\/revisions"}],"predecessor-version":[{"id":297,"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/posts\/289\/revisions\/297"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/media\/292"}],"wp:attachment":[{"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/media?parent=289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/categories?post=289"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iotnoob.com\/wordpress\/wp-json\/wp\/v2\/tags?post=289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}