20241121(四) :::success [TOC] ::: <span style=color:orange>本文可能存在偏誤或不確定的部分為此色</span> --- ### <p style="color: #00CCDD;">Table、Model</p> #### <p style="color: #DA8359;">屬性、介面、方法</p> javax.swing.JTable extends JComponent #### <p style="color: #DA8359;">視窗頁面</p> ```java= import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import tw.Issac.apis.FoodTable; public class MyFood extends JFrame{ // 宣告將使用到的物件 private FoodTable foodTable; private JButton del; public MyFood() { // 視窗介面 setLayout(new BorderLayout()); foodTable = new FoodTable(); JScrollPane jsp = new JScrollPane(foodTable); add(jsp, BorderLayout.CENTER); // 按鈕介面 JPanel top = new JPanel(new FlowLayout()); del = new JButton("Delete"); top.add(del); add(top, BorderLayout.NORTH); // 視窗規格 setSize(640, 480); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); initEvent(); } // 程式執行指令 private void initEvent() { del.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { foodTable.delRow(); } }); } // 程式進入點,new出本程式物件給其他兩隻使用 public static void main(String[] args) { new MyFood(); } } ``` --- #### <p style="color: #DA8359;">自訂類別api</p> ```java= import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class FoodTable extends JTable{ private FoodModel model; private FoodDB db; public FoodTable() { try { db = new FoodDB(); db.query(); }catch(Exception e) { System.out.println(e); } model = new FoodModel(); setModel(model); model.setColumnIdentifiers(db.getFieldNames()); } public void delRow() { // System.out.println(getSelectedRow()); //確認一下刪掉的是哪一列,可以看到這裡是從0匴起,而DB是從1算起,需要特別注意 db.delData(getSelectedRow()); repaint(); } private class FoodModel extends DefaultTableModel{ @Override public int getRowCount() { return db.getRows(); } @Override public int getColumnCount() { return db.getCols(); } @Override public Object getValueAt(int row, int column) { return db.getData(row, column); } @Override public boolean isCellEditable(int row, int column) { return column != 0; } @Override public void setValueAt(Object aValue, int row, int column) { db.updateData((String)aValue, row, column); } } } ``` --- #### <p style="color: #DA8359;">串接DB與資料呈現</p> 使用的資料是前一個筆記中導入的[opendata](https://hackmd.io/V0wW2wTlSDyYH2EqXN-HHA#opendata-%E5%B0%8E%E5%85%A5-database) ```java= import java.sql.*; import java.util.Properties; public class FoodDB { private final static String URL = "jdbc:mysql://localhost/issac"; private final static String USER = "root"; private final static String PASSWORD = ""; private final static String SQL_QUERY = "SELECT id 編號, name 商家名稱, addr 地址, tel 電話 from food"; private Connection conn; private ResultSet rs; private String[] fieldNames; public FoodDB() throws Exception { Properties prop = new Properties(); prop.put("user", USER); prop.put("password", PASSWORD); conn = DriverManager.getConnection(URL, prop); } public void query() throws Exception { query(SQL_QUERY); } public void query(String sql) throws Exception { Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); rs = stmt.executeQuery(sql); ResultSetMetaData rsmd = rs.getMetaData(); fieldNames = new String[rsmd.getColumnCount()]; for (int i = 0; i < fieldNames.length; i++) { fieldNames[i] = rsmd.getColumnLabel(i + 1); } } public int getRows() { try { rs.last(); return rs.getRow(); } catch (Exception e) { return 0; } } public int getCols() { return fieldNames.length; } // row, col => 0-base public String getData(int row, int col) { try { rs.absolute(row + 1); return rs.getString(fieldNames[col]); } catch (Exception e) { return "ERROR"; } } public String[] getFieldNames() { return fieldNames; } // 0-base public void delData(int row) { try { rs.absolute(row + 1); rs.deleteRow(); } catch (Exception e) { System.out.println(e); } } public void updateData(String newData, int row, int col) { try { rs.absolute(row + 1); rs.updateString(col + 1, newData); rs.updateRow(); } catch (Exception e) { System.out.println(e); } } } ```