如果我使用 VO 和 DAO,如何在 JTable 中实现数据库搜索?



每个人。在绞尽脑汁之后,我决定为这个话题做贡献。

我得到的大部分过滤代码来自:

  • 使用JTextfield文本重复搜索JTable
  • http://swingdepot.blogspot.com.br/2010/08/text-search-in-jtable.html

使用的软件:

  • MySQL 14.14
  • JDK 7
  • NetBeans 7.1.2

假设我们有以下名为">table"的示例表:

+-----------+-------------+------+-----+---------+----------------+
| Field     | Type        | Null | Key | Default | Extra          |
+-----------+-------------+------+-----+---------+----------------+
| id        | int(11)     | NO   | PRI | NULL    | auto_increment |
| name      | varchar(50) | YES  |     | NULL    |                |
| phone     | varchar(20) | YES  |     | NULL    |                |
| birthdate | datetime    | YES  |     | NULL    |                |
| status    | int(1)      | YES  |     | NULL    |                |
+-----------+-------------+------+-----+---------+----------------+

创建一个名为">vTable"的视图,考虑只显示ID、姓名和出生日期的列表:

CREATE VIEW vTable AS
SELECT id, name, birthdate FROM table WHERE status IS NOT NULL;

我使用的是MVC模式,所以有"模型"、"视图"one_answers"控制器"三个包。

创建数据访问对象TableDAO:

package model.DAO;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import model.VO.TableDAO;
import model.VO.VTableVO;
public class TableDAO extends ConnectionDAO {
    public List<VInstituicaoVO> List() throws ClassNotFoundException {
        List<VTableVO> listTable = new ArrayList<>();
        try {
            openConnection();
            con.setAutoCommit(false);
            PreparedStatement stmt = con.prepareCall(
                    "SELECT id, name, birthdate FROM vTable");
            ResultSet record = stmt.executeQuery();
            while(record.next()) {
               VTableVO  vo = new VTableVO();
               vo.setId(record.getInt(1));
               vo.setName(record.getString(2));
               vo.setBirthdate(record.getDate(3));
               listTable.add(vo);
            }
            closeConnection();
        } catch (SQLException ex) {
            Logger.getLogger(TableDAO.class.getName()).log(Level.SEVERE, null, ex);
        }
        return listTable;
}

创建值对象(不要忘记生成getter和setter(TableVO:

package model.VO;
import java.sql.Date;
public class TableVO {
    private Integer id;
    private String name;
    private String phone;
    private Date birthdate;
    private int status;
    public TableVO() {}
    public TableVO(ITableVO vo) {
        id = vo.getId();
        name = vo.getName();
        phone = vo.getPhone();
        birthdate = vo.getBirthdate();
        status = vo.getStatus();
    }
   // GENERATE GETTERS AND SETTERS
}

VTableVO类:

package model.VO;
import java.sql.Date;
public class VTableVO {
    private Integer id;
    private String name;
    private Date birthdate;
// GENERATE GETTERS AND SETTERS
}

ITableDAO接口:

package model.DAO;
import java.util.List;
import model.VO.TableVO;
public interface ITableDAO {
    public List<TableVO> List();
}

ITableVO接口:

package model.VO;
import java.sql.Date;
public interface ITableVO {
    public Integer getId();
    public void setId(Integer set_id);
    public String getName();
    public void setName(String set_nome);
    public String getPhone();
    public void setPhone(String set_phone);
    public Date getBirthdate();
    public void setBirthdate(Date set_birthdate);
    public Integer getStatus();
    public void setStatus(Integer set_status);
}

有了这种结构,我们如何在JTable中实现搜索功能?

在必须显示数据的表单中,我们创建了两个JPanel:

  1. 我们将在其中放置3个JTextFields("txtId"、"txtName"one_answers"txtBirthdate"(
  2. 我们将把JTable"TableExample"放在哪里

我只对第一个JTextField,即"txtId"执行此操作。

FrmExample表单(注意:末尾有一个名为CustomRenderer的内部类,用于为找到的单元格的边界上色(:

package view;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Date;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.table.*;
import model.DAO.TableDAO;
import model.VO.VTableVO;
public class FrmExample extends javax.swing.JInternalFrame {
    public FrmExample() throws SQLException, ClassNotFoundException {
        initComponents();
        getTableModel();
        getTable();
        txtId.addActionListener(new ActionListener() {      
            @Override
            public void actionPerformed(ActionEvent e) {
                searchId();
            }
        });
        TableExample.setAutoCreateRowSorter(true);
    }
    private  void getTableModel() {
        // Configure the columns of JTable
        TableColumnModel columnModel =
                this.TableExample.getColumnModel();
        columnModel.getColumn(0).setHeaderValue("ID");
        columnModel.getColumn(0).setPreferredWidth(60);
        columnModel.getColumn(1).setHeaderValue("Name");
        columnModel.getColumn(1).setPreferredWidth(180);
        columnModel.getColumn(2).setHeaderValue("Birth Date");
        columnModel.getColumn(2).setPreferredWidth(180);
    }
    private JTable getTable() throws ClassNotFoundException {
        String[] columnTitles = { "ID", "Name", "Birth Date" };
        List<VTableVO> listExample = new TableDAO().List();
        Object[][] data = new Object[listExample.size()][columnTitles.length];
        for(VTableVO vo : list) {
                    data[list.indexOf(vo)][0] = "" + vo.getId();
                    data[list.indexOf(vo)][1] =      vo.getName();
                    data[list.indexOf(vo)][2] = "" + vo.getBirthdate();
        } // Is there a way to code that so it become more dynamic? Writing 1 line instead of 3
        DefaultTableModel model = new DefaultTableModel(data, columnTitles) {
            @Override
            public Class getColumnClass(int col) {
                Object obj = getValueAt(0, col);
                if(obj == null)
                    return Object.class;
                else
                    return obj.getClass();
            }
        };
        TableExample.setDefaultRenderer(String.class, new CustomRenderer());
        TableExample.setRowSelectionAllowed(true);
        TableExample.setColumnSelectionAllowed(true);
        TableExample.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        TableExample.setModel(model);
        TableModel model = TableExample.getModel();
        final TableRowSorter<TableModel> sorter = new TableRowSorter<>(model);
        TableExample.setRowSorter(sorter);
        return TableExample;
    }
    private void searchId() {
        String target = txtId.getText();
        for(int row = 0; row < TableExample.getRowCount(); row++) {
            String next = (String)TableExample.getValueAt(row, 0); // First row only
                if(next.equals(target)) {
                    displayResultSearch(row, 0);
                    return;
                }
        }
        CustomRenderer renderer = (CustomRenderer)TableExample.getDefaultRenderer(String.class);
        renderer.setTargetCell(-1, -1);
        TableExample.repaint();
    }
    private void displayResultSearch(int row, int column) {
        CustomRenderer renderer = (CustomRenderer)TableExample.getCellRenderer(row, column);
        renderer.setTargetCell(row, column);
        Rectangle rect = TableExample.getCellRect(row, column, false);
        TableExample.scrollRectToVisible(rect);
        TableExample.repaint();
    }
class CustomRenderer implements TableCellRenderer {
    JLabel label;
    int targetRow, targetColumn;
    public CustomRenderer() {
        label = new JLabel();
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setOpaque(true);
        targetRow = -1;
        targetColumn = -1;
    }
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {
        if(isSelected) {
            label.setBackground(table.getSelectionBackground());
            label.setForeground(table.getSelectionForeground());
        } else {
            label.setBackground(table.getBackground());
            label.setForeground(table.getForeground());
        }
        if(row == targetRow && column == targetColumn) {
            label.setBorder(BorderFactory.createLineBorder(Color.red)); // Color it in RED!
            label.setFont(table.getFont().deriveFont(Font.BOLD)); // And BOLD!
        } else {
            label.setBorder(null);
            label.setFont(table.getFont());
        }
        label.setText((String)value);
        return label;
    }
    public void setTargetCell(int row, int column) {
        targetRow = row;
        targetColumn = column;
    }
  }
}

若要搜索必须在选定字段中键入的内容,请按ENTER键。在这个例子中,我没有使用JButton。

为了对其他列实现相同的功能,我给出的最大提示是更改以下行:

  • String next=(String(TableExample.getValueAt(行,列此处的数字(
  • displayResultSearch(行,列编号,此处(

我希望这将帮助很多人。如果有人觉得有什么值得改变的地方,出于任何原因,请考虑周全地回答。谢谢

最新更新