在 JTable 中使用 Search Filter 和 mouseClicked Event 时出现的问题
Issues when Search Filter and mouseClicked Event used in JTable
此代码提供了带有 SearchFilter 的员工详细信息 JTable。
在 Employee Processing 和 Employee Processed Columns 上使用鼠标单击,它应该被定向到与当前行中的员工相关的 url。
下面的代码工作正常,除非使用搜索过滤器。
当我使用搜索过滤器并在过滤行上单击鼠标时,它会指向 JTable 第一行中与员工详细信息相关的 URL,而不是当前过滤行的员工详细信息。
有人可以帮我解决这个问题吗?
package Test;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import EmployeeDAO;
import EmployeeDTO;
import common.UIConstants;
public class EmpDataWin extends JFrame {
private static final String EMPLOYEE_NAME = "Employee Name";
private static final String DEPARTMENT = "Department";
private static final String DETAILS = "Details";
private static final String EMPLOYEE_PROCESSING = "Employee Processing";
private static final String EMPLOYEE_PROCESSED = "Employee Processed";
private final int DETAILS_COLUMN_INDEX = 2;
private final int EMPLOYEE_PROCESSING_COLUMN_INDEX = 3;
private final int EMPLOYEE_PROCESSED_COLUMN_INDEX = 4;
DefaultTableModel model = new DefaultTableModel();
Container cont = this.getContentPane();
JTable tab = new JTable(model);
private TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(model);
private final JTextField searchFilter = new JTextField();
public EmpDataWin(List<EmployeeDTO> pEmployeeDTO) {
initialize(pEmployeeDTO);
}
public void initialize(List<EmployeeDTO> pEmployeeDTOList) {
JPanel panelParent = new JPanel(new BorderLayout());
// Add Header
model.addColumn(EMPLOYEE_NAME);
model.addColumn(DEPARTMENT);
model.addColumn(DETAILS);
model.addColumn(EMPLOYEE_PROCESSING);
model.addColumn(EMPLOYEE_PROCESSED);
// Add data row to table
for (EmployeeDTO aEmployeeDTO : pEmployeeDTOList) {
model.addRow(new Object[] { aEmployeeDTO.getEmployee_Name(), aEmployeeDTO.getDepartment(),
aEmployeeDTO.getDetails(), aEmployeeDTO.getEmployee_Processing(),
aEmployeeDTO.getEmployee_Processed()
});
}
tab.setRowSorter(rowSorter);
tab.setAutoCreateRowSorter(true);
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel(UIConstants.SEARCH), BorderLayout.WEST);
JTextField searchFilter = SearchFilter.createRowFilter(tab);
panel.add(searchFilter, BorderLayout.CENTER);
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
tab.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// Mouse listener part
tab.addMouseListener(new MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent e) {
int col = tab.getSelectedColumn();
int row = tab.getSelectedRow();
// Employee Processing columnindex is
if (EMPLOYEE_PROCESSING_COLUMN_INDEX == col) {
String employeeName = (String) tab.getModel().getValueAt(row, col);
System.out.println("employeeName = " + employeeName);
if (employeeName != null && !employeeName.trim().equals("")) {
OpenURL open = new OpenURL();
open.openEmployeeProcessing(employeeName);
} else {
System.out.println("ERROR : Invalid Client name ....");
}else if(EMPLOYEE_PROCESSED_COLUMN_INDEX == col) {
String employeeName = (String) tab.getModel().getValueAt(row, col);
System.out.println("employeeName = " + employeeName);
if (employeeName != null && !employeeName.trim().equals("")) {
OpenURL open = new OpenURL();
open.openEmployeeProcessed(employeeName);
} else {
System.out.println("ERROR : Invalid Client name ....");
} else if (DETAILS_COLUMN_INDEX == col) {
String CD = (String) tab.getModel().getValueAt(row, col);
OpenDrive od = new OpenDrive();
osd.openDetails(CD);
}
}
});
tab.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
JScrollPane sp = new JScrollPane(tab,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
panelParent.add(panel,BorderLayout.NORTH);
panelParent.add(sp,BorderLayout.CENTER);
panelParent.setBorder(BorderFactory.createEmptyBorder(10 , 10, 10, 10));
cont.add(panelParent);
this.pack();
}
public static void main(String[] args) {
EmployeeDAO dao = new EmployeeDAO();
List<EmployeeDTO> dto = dao.getemployeeData();
JFrame frame = new EmpDataWin(dto);
frame.setTitle("Employee Data");
frame.setLocationRelativeTo(null);
frame.setSize(1200, 600);
frame.setVisible(true);
}
}
int col = tab.getSelectedColumn();
int row = tab.getSelectedRow();
// Employee Processing columnindex is
if (EMPLOYEE_PROCESSING_COLUMN_INDEX == col) {
String employeeName = (String) tab.getModel().getValueAt(row, col);
当您在 table 上使用 Sorter/Filter 时,数据不是来自 TableModel
的 sorted/removed。您只能看到数据的 sorted/filtered 视图。因此,您不再具有 "table row" 和 "model row".
的一对一映射
因此您需要使用 JTable
:
的方法访问数据
//String employeeName = (String) tab.getModel().getValueAt(row, col);
String employeeName = (String) tab.getValueAt(row, col);
JTable
的 getValueAt(...)
方法将自动转换 row/column 索引以映射到 TableModel
中的适当数据,然后它将调用 getValueAt(...)
方法TableModel
给你。
阅读 JTable
API 您会发现 4 个 convert???(...)
方法可以在模型和视图之间转换 row/column 索引,如果您需要进行这种转换手动。
您还需要修复您尝试从 TableModel
访问数据的其他地方。
此代码提供了带有 SearchFilter 的员工详细信息 JTable。 在 Employee Processing 和 Employee Processed Columns 上使用鼠标单击,它应该被定向到与当前行中的员工相关的 url。 下面的代码工作正常,除非使用搜索过滤器。 当我使用搜索过滤器并在过滤行上单击鼠标时,它会指向 JTable 第一行中与员工详细信息相关的 URL,而不是当前过滤行的员工详细信息。 有人可以帮我解决这个问题吗?
package Test;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.BevelBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import EmployeeDAO;
import EmployeeDTO;
import common.UIConstants;
public class EmpDataWin extends JFrame {
private static final String EMPLOYEE_NAME = "Employee Name";
private static final String DEPARTMENT = "Department";
private static final String DETAILS = "Details";
private static final String EMPLOYEE_PROCESSING = "Employee Processing";
private static final String EMPLOYEE_PROCESSED = "Employee Processed";
private final int DETAILS_COLUMN_INDEX = 2;
private final int EMPLOYEE_PROCESSING_COLUMN_INDEX = 3;
private final int EMPLOYEE_PROCESSED_COLUMN_INDEX = 4;
DefaultTableModel model = new DefaultTableModel();
Container cont = this.getContentPane();
JTable tab = new JTable(model);
private TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(model);
private final JTextField searchFilter = new JTextField();
public EmpDataWin(List<EmployeeDTO> pEmployeeDTO) {
initialize(pEmployeeDTO);
}
public void initialize(List<EmployeeDTO> pEmployeeDTOList) {
JPanel panelParent = new JPanel(new BorderLayout());
// Add Header
model.addColumn(EMPLOYEE_NAME);
model.addColumn(DEPARTMENT);
model.addColumn(DETAILS);
model.addColumn(EMPLOYEE_PROCESSING);
model.addColumn(EMPLOYEE_PROCESSED);
// Add data row to table
for (EmployeeDTO aEmployeeDTO : pEmployeeDTOList) {
model.addRow(new Object[] { aEmployeeDTO.getEmployee_Name(), aEmployeeDTO.getDepartment(),
aEmployeeDTO.getDetails(), aEmployeeDTO.getEmployee_Processing(),
aEmployeeDTO.getEmployee_Processed()
});
}
tab.setRowSorter(rowSorter);
tab.setAutoCreateRowSorter(true);
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JLabel(UIConstants.SEARCH), BorderLayout.WEST);
JTextField searchFilter = SearchFilter.createRowFilter(tab);
panel.add(searchFilter, BorderLayout.CENTER);
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
tab.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// Mouse listener part
tab.addMouseListener(new MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent e) {
int col = tab.getSelectedColumn();
int row = tab.getSelectedRow();
// Employee Processing columnindex is
if (EMPLOYEE_PROCESSING_COLUMN_INDEX == col) {
String employeeName = (String) tab.getModel().getValueAt(row, col);
System.out.println("employeeName = " + employeeName);
if (employeeName != null && !employeeName.trim().equals("")) {
OpenURL open = new OpenURL();
open.openEmployeeProcessing(employeeName);
} else {
System.out.println("ERROR : Invalid Client name ....");
}else if(EMPLOYEE_PROCESSED_COLUMN_INDEX == col) {
String employeeName = (String) tab.getModel().getValueAt(row, col);
System.out.println("employeeName = " + employeeName);
if (employeeName != null && !employeeName.trim().equals("")) {
OpenURL open = new OpenURL();
open.openEmployeeProcessed(employeeName);
} else {
System.out.println("ERROR : Invalid Client name ....");
} else if (DETAILS_COLUMN_INDEX == col) {
String CD = (String) tab.getModel().getValueAt(row, col);
OpenDrive od = new OpenDrive();
osd.openDetails(CD);
}
}
});
tab.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
JScrollPane sp = new JScrollPane(tab,ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
panelParent.add(panel,BorderLayout.NORTH);
panelParent.add(sp,BorderLayout.CENTER);
panelParent.setBorder(BorderFactory.createEmptyBorder(10 , 10, 10, 10));
cont.add(panelParent);
this.pack();
}
public static void main(String[] args) {
EmployeeDAO dao = new EmployeeDAO();
List<EmployeeDTO> dto = dao.getemployeeData();
JFrame frame = new EmpDataWin(dto);
frame.setTitle("Employee Data");
frame.setLocationRelativeTo(null);
frame.setSize(1200, 600);
frame.setVisible(true);
}
}
int col = tab.getSelectedColumn();
int row = tab.getSelectedRow();
// Employee Processing columnindex is
if (EMPLOYEE_PROCESSING_COLUMN_INDEX == col) {
String employeeName = (String) tab.getModel().getValueAt(row, col);
当您在 table 上使用 Sorter/Filter 时,数据不是来自 TableModel
的 sorted/removed。您只能看到数据的 sorted/filtered 视图。因此,您不再具有 "table row" 和 "model row".
因此您需要使用 JTable
:
//String employeeName = (String) tab.getModel().getValueAt(row, col);
String employeeName = (String) tab.getValueAt(row, col);
JTable
的 getValueAt(...)
方法将自动转换 row/column 索引以映射到 TableModel
中的适当数据,然后它将调用 getValueAt(...)
方法TableModel
给你。
阅读 JTable
API 您会发现 4 个 convert???(...)
方法可以在模型和视图之间转换 row/column 索引,如果您需要进行这种转换手动。
您还需要修复您尝试从 TableModel
访问数据的其他地方。