Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 32 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
32
Dung lượng
1,28 MB
Nội dung
Sử dụng JTDS thay cho jdbc jTDS JDBC 3.0 driver Java (type 4) mã nguồn mở dành cho Microsoft SQL Server Sybase Hiện xem JDBC Driver nhanh cho SQL Server Sybase Như bạn biết, để kết nối phần mềm Java với database, cần sử dụng cầu nối trung gian biết đến driver Nó giống việc bạn cần cài đặt driver để giao tiếp với thiết bị ngoại vi Có loại driver thường sử dụng type (100% pure Java) Với MS SQL, driver phổ biến SqlJDBC Microsoft cung cấp Nó cài đặt dễ dàng khác biệt tốc độ không quan trọng Chúng ta thấy thứ có vấn đề gặp phải vấn đề với Sẽ chẳng có viết khơng gặp phải bug ngớ ngẩn với SqlJDBC phải tìm đến jTDS Số ngày đẹp trời định nâng cấp MS SQL Server lên (SQL Server 2008 R2) Sau nâng cấp, chạy thử ứng dụng Java làm trước báo khơng thể kết nối với database Mình vơ Netbeans run project lại Clean build build lại Cứ chạy Netbeans ok, mà ngồi click file jar khơng kết nối Mất nhiều thời gian tìm hiểu bug SqlJDBC với SQL Server 2008 R2 Tất giải dùng jTDS Ngồi việc mã nguồn mở chỉnh sửa dễ dàng khắp phục lỗi phát sinh so với SqlJDBC, jTDS tối ưu hóa để tăng tốc độ kết nối hiệu làm việc Trước hết, bạn tải jTDS Là driver type 4, việc cài đặt jTDS đơn giản, cần thêm vào thư viện project bạn, sau viết chuỗi kết nối dựa vào tên server, cổng kết nối, tên database Mình demo phương thức getConnection trả đối tượng Connection kết nối thành công đến SQL Server: 10 11 12 13 14 15 public static Connection getConnection(Server server) { String url = "jdbc:jtds:sqlserver://" + server.getServerName() + ":" + server.getPort() + "/" + server.getDatabaseName(); try { Class.forName("net.sourceforge.jtds.jdbc.Driver"); Connection cn = DriverManager.getConnection(url, server.getUserName(), server.getPassword()); return cn; } catch (ClassNotFoundException cnfe) { JOptionPane.showMessageDialog(null, "Did you forget to import the jdbc library?"); } catch (SQLException se) { System.out.println("Connection failed!"); } return null; } Cập nhật: Microsoft nâng cấp JDBC Driver lên 4.0 để hỗ trợ thêm SQL Server 2012 Mình khơng rõ khắp phục bug chưa Bạn tải DELETE MỘT ROW TRONG JTABLE Xóa chức mà thực JTable thao tác với sở liệu Xóa row JTable thường kèm với việc xóa ghi database Cách làm đơn giản Tuy nhiên để thực cách đắn hiệu quả, cần nắm rõ cấu trúc liệu JTable, hay nói cách khác data model JTable Có nhiều bạn làm theo cách sau: thực xóa row, bạn xóa ghi tương ứng database, sau setModel lại cho JTable Cách cho kết cách không thực tế nên tránh Trong trường hợp liệu bạn nhiều, việc setModel tốn nhiều thời gian cho việc truy xuất để lấy liệu từ database Có cách khác hay nhiều Trong data model, bạn tạo phương thức sau: public void removeRow(int row) { data.remove(row); fireTableDataChanged(); } Phương thức có nhiệm vụ remove đối tượng (tương ứng với row JTable) data model xác định tham số số hàng chọn để xóa bảng (trong code ví dụ, data ArrayList nên để xóa đối tượng, dùng phương thức remove nó) Khi phương thức gọi, JTable tự update giao diện để phù hợp với data model Chúng ta tạo JButton để thực xóa row chọn JTable Code xử lý kiện nút sau: 10 11 private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: if (myTable.getSelectedRowCount() > 0) { int realIndex = myTable.convertRowIndexToModel(myTable.getSelectedRow()); // delete record in database // // update table UI ((CustomTableModel) myTable.getModel()).removeRow(realIndex); myTable.repaint(); } } listselectionListener jtable Trong JTable thường sử dụng lắng nghe kiện làListSelectionListener TableModelListener để bắt kiện tương ứng có thay đổi ô chọn liệu bảng Nói cách sử dụng TableModelListener, viết chi tiết viết Chỉnh sửa liệu trực tiếp JTable, bạn tham khảo Trong viết này, đề cập đến ListSelectionListener Về bản, bạn sử dụng lắng nghe ListSelectionListener để bắt kiện JTable có thay đổi lựa chọn bảng Ví dụ bạn click chuột vào row khác row chọn kiện phát sinh Nhiều bạn nhập mơn dùng kiện mouseClicked để xử lý lựu chọn JTable Tuy nhiên, bạn nên nhớ lựu chọn bảng khơng tạo click chuột, mà phím lên xuống Khi đó, MouseClick event khơng xử lý JTable mặc định cho phép chọn nhiều row lúc vị trí khác (MULTIPLE_INTERVAL_SELECTION) Ngồi cung cấp chế độ khác làSINGLE_INTERVAL_SELECTION cho phép chọn nhiều row phải liên tiếp vàSINGLE_SELECTION cho phép chọn row thời điểm mà thơi Bạn thay đổi chế độ phương thức setSelectionMode Do tính chất viết, sử dụng chế độ chọn SINGLE_SELECTION Mình tạo demo mà sau hoàn thành sau: Một bảng liệu mà click vào row, liệu row viết vào cácJTextBox, JCheckBox phía Như thường lệ, bạn tạo data model kế thừa từ AbstractTableModel làm liệu cho bảng (chi tiết bạn xem source code file attach) Code xử lý sau: myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); final DateFormat df = new SimpleDateFormat("E MMM dd hh:mm:ss Z yyyy"); myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if(!e.getValueIsAdjusting()){ int selectedIndex = myTable.getSelectedRow(); int realIndex = myTable.convertRowIndexToModel(selectedIndex); 10 TableModel model = myTable.getModel(); 11 txtFirst.setText(model.getValueAt(realIndex, 0).toString()); 12 txtLast.setText(model.getValueAt(realIndex, 1).toString()); 13 txtBalance.setText(model.getValueAt(realIndex, 3).toString()); 14 String dateString = model.getValueAt(realIndex, 2).toString(); 15 try { 16 Date birth = df.parse(dateString); 17 txtBirth.setText(DateFormat.getInstance().format(birth)); 18 } catch (ParseException ex) { 19 Logger.getLogger(MyTable.class.getName()).log(Level.SEVERE, null, ex); 20 } 21 cbMale.setSelected(Boolean.parseBoolean(model.getValueAt(realIndex, 4).toString())); 22 } 23 } 24 }); Trong đoạn code trên, bạn lưu ý điểm sau: Luôn quy table model Nguyên nhân người dùng dễ dàng thay đổi vị trí cột cách kéo sang vị trí khác, hay thay đổi vị trí hàng thực xếp Nhưng model vị trí ln giữ nguyên Vì việc quy tất table model giúp xử lý dễ dàng JTable hỗ trợ sẵn phương thức nhưconvertRowIndexToModel hay ngược lại convertRowIndexToView để chuyển đổi qua lại vị trí View Model Sử dụng phương thức getValueIsAdjusting Bạn đặt câu lệnh System out để test trước khối lệnh if đoạn code trên, sau chạy ứng dụng Bạn để ý thây điều Khi bạn click chọn row bảng, bạn thấy cửa sổ output, lệnh System out chạy lần Điều có nghĩa khối code valueChanged xử lý lần bạn click chọn lần Tại lại vậy? Nguyên nhân bạn click chuột chọn row, có event phát sinh mousePressed mouseReleased, event gửi tới lắng nghe kiện ListSelectionListener Vì mà đoạn code xử lý đến lần Điều không xảy bạn chọn row JTable phím lên xuống Bởi có event gửi đến lắng nghe kiện làfocusGained Phương thức getValueIsAdjusting trả true kiện tiếp nhận chuỗi nhiều kiện mà kiện tiếp sau tạo thay đổi lựa chọn Nó trả false kiện cuối chuỗi kiện (trong trường hợp mouseReleased cuối cùng) Thường việc phải xử lý tất event chuỗi điều không mong muốn, nên kiểm tra getValueIsAdjusting trả false trước cho phép code thực thi tiếp CĂN GIỮA HEADER TRONG JTABLE Header JTable tiêu đề cột Trên hầu hết Look and Feel, header bảng lề bên trái Điều dẫn đến việc người kỹ tính (như chẳng hạn) thấy không đẹp mắt chút nào, đặc biệt cột có độ rộng lớn Đó lý muốn header JTable Cũng khơng có nhiều để chia sẻ với bạn Nó vài dòng code mà thơi, giúp bạn tiết kiệm thời gian tìm kiếm Google Để giữ header bảng, bạn code sau: 10 11 12 13 // center the table header TableColumnModel columnModel = myTable.getColumnModel(); myTable.setTableHeader(new JXTableHeader(columnModel) { @Override public void updateUI() { super.updateUI(); // need to in updateUI to survive toggling of LAF if (getDefaultRenderer() instanceof JLabel) { ((JLabel) getDefaultRenderer()).setHorizontalAlignment(JLabel.CENTER); } } }); Hoặc cách tương tự khác: // center title column TableCellRenderer myRenderer = myTable.getTableHeader().getDefaultRenderer(); JLabel label = (JLabel) myRenderer; label.setHorizontalAlignment(JLabel.CENTER); Hai cách code chung nguyên tắc Nhưng thực tế có vài trường hợp đặc biệt cách khơng hiệu Mình nêu cách để thêm phương án dự phòng cho bạn Các bạn để ý rằng, khơng có bảng, mà header vẽ nên renderer Nếu bạn sử dụng JXTable SwingX, cách làm hồn tồn giống Bạn thay JTableHeader JXTableHeader đoạn code trường hợp SỬ DỤNG JXTABLE TRONG SWING Như bạn biết, SwingX thư viện kế thừa từ Swing Các component SwingX kế thừa từ component tương ứng Swing, mà cụ thể đây,JXTable kế thừa từ JTable Do vậy, cách sử dụng JXTable hoàn toàn tương tự JTable Cũng lẽ đó, sau giới thiệu SwingX, có loạt cách sử dụng JTable để làm cho viết Sẽ chẳng có để viết thêm JXTable khơng có thêm số tính hay ho mà giới thiệu Bạn dành phút xem clip này: Rất hay phải không bạn Giờ tìm hiểu cụ thể tính JXTable hỗ trợ sẵn sorting Khi bạn click chuột vào header, row bảng xếp theo giá trị cột có header click Mỗi lần click, xếp tự động đảo chiều tăng dần hay giảm dần Bạn hỏi JXTable vào đâu để thực việc xếp giá trị? Khác với JTable, JXTable mặc định enableautoCreateRowSorter Do đó, tự động tạo sử dụng row sorter mặc định cung cấp phương thức createDefaultRowSorter Dĩ nhiên, bạn can thiệp vào q trình để tự comparatorso sánh giá trị để xếp, hay bạn disable sorting cột bảng Như bạn thấy clip, JXTable có nút nhỏ góc bên phải Đó Column Control Column Control tác dụng giúp cho người dùng ẩn cột không cần thiết, để có tầm nhìn tốt cột muốn tập trung Mặc định, Column Control ẩn Bạn làm xuất cáchsetColumnControlVisible(true) Theo mắt thẩm mỹ mình, Highlighter giúp cho giao diện bảng đẹp nhiều Có lẽ có viết riêng nói cách sử dụng Highlighter sau Trong clip demo, sử dụng highlighter đơn giản làm background cho bảng tạo cách: Highlighter simpleStripHL = HighlighterFactory.createSimpleStriping(); jxTable.setHighlighters(simpleStripHL); Rollover hiệu ứng mà bạn di chuột đến row bảng row đổi màu Đây cách hay để làm đẹp giao diện Bản chất highlighter Cách sử dụng sau: jxTable.addHighlighter(new ColorHighlighter(HighlightPredicate.ROLLOVER_ROW, null, new Color(255, 102, 0))); Phương thức dùng sử dụng constructor lớp ColorHighlighter Tham số kiểu rollover Bạn thay ROLLOVER_ROW ROLLOVER_CELL hayROLLOVER_COLUMN để có hiệu ứng rollover ô, cột bảng Tham số thứ màu background Mình khơng muốn để màu nên set null Và tham số thứ màu text, set mà màu da cam bạn thấy Cái search popup JXTable clip demo hoàn toàn support sẵn, khơng tốn dòng code để tạo Q tuyệt phải khơng bạn kiếm với đầy đủ tùy chọn case sensitive hay backward Một box tìm MỘT SỐ RENDERER HAY DUNG TRONG JTABLE Trong viết này, tổng hợp cho bạn vài mẫu renderer hay dùng JTable Mặc dù nhu cầu biểu diễn liệu JTable đa dạng, tổng hợp bao quát hết tất trường hợp, đừng lo, bạn làm nhiều, bạn nhanh chóng rút quy luật thơi Với cách biểu diễn đơn giản dùng checkbox cho liệu kiểu boolean, lề phải cho kiểu Number, biểu diễn ngày tháng, bạn lạ lẫm với khái niệm renderer, bạn xem lại viết giới thiệu cell renderer trước DefaultTableCellRenderer mặc định sử dụng JLabel để render ô bảng Để tạo renderer có tác dụng đổi màu text JTable đơn giản Bạn cần lợi dụng phương thức setForeground JLabel 10 public static class ColorRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean int column) { setForeground(new Color(153, 0, 0)); super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); return this; } } Bạn lề trái, giữa, phải cho cột JTable tùy ý 10 11 12 13 14 15 public static class AlignRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean int column) { // align center setHorizontalAlignment(SwingConstants.CENTER); // align left //setHorizontalAlignment(SwingConstants.LEFT); // align right //setHorizontalAlignment(SwingConstants.RIGHT); super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); return this; } } Lợi dụng khả biểu diễn hình ảnh JLabel thơng qua phương thức setIcon Trong demo, chèn ảnh khác vào cell JTable dựa vào giá trị đưa vào true hay false public static class ImageRenderer extends DefaultTableCellRenderer { @Override 10 11 12 13 14 15 16 17 18 19 public Component getTableCellRendererComponent(JTable table, Object value, boolean int column) { boolean bool = Boolean.parseBoolean(value.toString()); Image img = null; if(bool) { img = getToolkit().getImage(getClass().getResource("/images/male.png")); } else { img = getToolkit().getImage(getClass().getResource("/images/female.png")); } setSize(16, 16); setHorizontalAlignment(SwingConstants.CENTER); setIcon(new ImageIcon(img)); super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column); return this; } } Tương tự từ demo này, bạn tạo renderer biểu diễn text hình ảnh JTable 10 11 12 13 14 15 public static class CurrencyRenderer extends DefaultTableCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean int column) { if ((value != null) && (value instanceof Number)) { Number numberValue = (Number) value; NumberFormat formater = NumberFormat.getCurrencyInstance(); value = formater.format(numberValue.doubleValue()); } setHorizontalAlignment(javax.