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

时间:2013-05-12 23:35:53

标签: java swing filter jtable value-objects

大家。在彻底绞尽脑汁之后,我决定为这个话题做出贡献。

我从中获得的过滤代码的大部分内容:

使用的软件:

  • MySQL 14.14
  • JDK 7
  • NetBeans 7.1.2

假设我们有以下示例表,名为" ":

+-----------+-------------+------+-----+---------+----------------+
| 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模式,所以有包" model"," view"和"控制器"。

创建数据访问对象 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中实现搜索功能?

1 个答案:

答案 0 :(得分:1)

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

  1. 我们将放置3个JTextFields(“txtId”,“txtName”和“txtBirthdate”)
  2. 我们将JTable“TableExample”
  3. 我只会为第一个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;
    
        }
    
      }
    
    }
    

    要搜索您必须在所选字段中输入的内容,请 HIT ENTER 。我在这个例子中没有使用JButton。

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

    • String next =(String)TableExample.getValueAt(row, column 这里的数字);
    • displayResultSearch(行,列号);

    我希望这会对很多人有所帮助。如果有人发现任何值得改变的东西,无论出于何种原因,请回答所有问题。谢谢!