ต้องการสร้าง JTable สำหรับ กรอกข้อมูล โดย
- ไม่ต้องมีปุ่ม เพื่อ add new row,
- ใช้วิธี detect ว่ามีการใส่ข้อมูลที่ row ว่างท้ายตารางหรือไม่ ถ้ามีให้เพิ่ม row ใหม่หลังจากนั้น
- ถ้ามีการลบข้อมูลจนกลายเป็น row ว่าง ก็ให้ลบ row ว่างนั้นทิ้งไป
- สร้าง table ด้วย TableModel
- ให้มี column ที่แก้ไขได้ด้วย drowdown list
- ให้ column ที่เหลือแก้ไขด้วย Text Field
- เวลาแก้ไข เพียง click ที่ cell นั้นครั้งเดียวก็สามารถเข้า edit mode ได้เลย
- สร้างเป็น JPanel เพื่อจะได้ Add ไปในตำแหน่งที่ต้องการ น่าจะดีกว่าสร้างเป็น JTable เพราะมันยังมีในส่วนของ TableModel ซึ่งอาจจะมีการใช้งานสลับกันไปมาได้ ดังนั้นมี container ซักอันครอบมันทั้งคู่ น่าจะดีกว่า – และ JPanel น่าจะดีที่สุด
tablePanel = new DrillTablePanel(); placeHolderPanel.add(tablePanel, BorderLayout.CENTER);

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.awt.*;
/**
*
* @author Thada
*/
public class DrillTablePanel extends JPanel {
private JTable table;
private DefaultTableModel tableModel;
public DrillTablePanel() {
// ตั้งค่า Layout ของ Panel นี้
super(new BorderLayout());
// 1. กำหนดชื่อคอลัมน์และสร้าง TableModel
String[] columnNames = {"Id", "Column Id", "Drill Type", "Quantity"};
tableModel = new DefaultTableModel(columnNames, 0);
// 2. สร้าง JTable
table = new JTable(tableModel);
table.setRowHeight(30);
// 3. เรียกใช้เมธอดตั้งค่าต่างๆ ทั้งหมด
addEmptyRow();
setupCategoryColumn();
setSingleClickEditing();
setupTableModelListener();
applyStyles();
// 4. สร้าง JScrollPane และใส่ตารางเข้าไป
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBorder(BorderFactory.createLineBorder(new Color(200, 200, 200)));
// 5. เพิ่ม scrollPane เข้าไปใน Panel นี้
this.add(scrollPane, BorderLayout.CENTER);
}
// --- Public methods (เผื่อคลาสข้างนอกต้องการข้อมูล) ---
public JTable getTable() {
return table;
}
public DefaultTableModel getTableModel() {
return tableModel;
}
// --- Private helper methods (Logic ทั้งหมดถูกซ่อนไว้ที่นี่) ---
private void applyStyles() {
// จัดข้อความกึ่งกลาง
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(JLabel.CENTER);
TableColumnModel columnModel = table.getColumnModel();
for (int i = 0; i < columnModel.getColumnCount(); i++) {
columnModel.getColumn(i).setCellRenderer(centerRenderer);
}
// ตั้งค่าสีพื้นหลังและ Grid
table.setBackground(new Color(245, 245, 245));
table.setShowGrid(true);
table.setGridColor(new Color(220, 220, 220));
}
private void addEmptyRow() {
tableModel.addRow(new Object[tableModel.getColumnCount()]);
}
private void setupCategoryColumn() {
TableColumn categoryColumn = table.getColumnModel().getColumn(2);
String[] categories = {"", "Mechanical", "Laser", "Back Drill"};
JComboBox<String> comboBox = new JComboBox<>(categories);
categoryColumn.setCellEditor(new DefaultCellEditor(comboBox));
}
private void setSingleClickEditing() {
DefaultCellEditor singleClickEditor = new DefaultCellEditor(new JTextField());
singleClickEditor.setClickCountToStart(1);
for (int i = 0; i < table.getColumnCount(); i++) {
if (i != 2) {
table.getColumnModel().getColumn(i).setCellEditor(singleClickEditor);
}
}
((DefaultCellEditor) table.getColumnModel().getColumn(2).getCellEditor()).setClickCountToStart(1);
}
private boolean isRowEmpty(int rowIndex) {
for (int i = 0; i < tableModel.getColumnCount(); i++) {
Object value = tableModel.getValueAt(rowIndex, i);
if (value != null && !value.toString().trim().isEmpty()) {
return false;
}
}
return true;
}
private void setupTableModelListener() {
tableModel.addTableModelListener(e -> {
if (e.getType() != TableModelEvent.UPDATE) return;
SwingUtilities.invokeLater(() -> {
int row = e.getFirstRow();
if (row >= tableModel.getRowCount()) return;
if (row == tableModel.getRowCount() - 1) {
if (!isRowEmpty(row)) addEmptyRow();
} else {
if (isRowEmpty(row)) {
int choice = JOptionPane.showConfirmDialog(
this, // อ้างอิงถึง Panel นี้
"Drill Information is empty, Do you want to remove row",
"Remove Row?",
JOptionPane.YES_NO_OPTION);
if (choice == JOptionPane.YES_OPTION) {
tableModel.removeRow(row);
}
}
}
});
});
}
}



