每个人。在绞尽脑汁之后,我决定为这个话题做贡献。
我得到的大部分过滤代码来自:
- 使用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:
- 我们将在其中放置3个JTextFields("txtId"、"txtName"one_answers"txtBirthdate"(
- 我们将把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(行,列编号,此处(
我希望这将帮助很多人。如果有人觉得有什么值得改变的地方,出于任何原因,请考虑周全地回答。谢谢