Jtable动态固定列问题
Jtable dynamical fixed columns problems
我创建了一个可以动态锁定和解锁列的 class。
在我的程序中,我创建了两个具有相同 table 模型的 table。
一个在滚动窗格的 Jviewport 中,另一个在 RowHeaderView 中。
问题是当您解锁所有锁定的列时
而你想重新开始锁定,是行不通的。没有错误,但好像事件没有响应。
产生问题的步骤:
- 尝试代码,
- 将所有列固定在 table、
- 然后右键双击解锁,
- 然后重新开始锁定,解锁
执行此过程,您可以看到鼠标事件不再响应
public class Prova extends JFrame{
private JTable mainTable,fixedTable;
private JScrollPane scrollPane;
private JTableHeader mainTableHeader;
private TableColumnModel originalColumnModel,mainColumnModel,fixedColumnModel;
private TableColumn[] columns;
private int ncols,counter;
public Prova(){
counter = 0;
TableModel mainTableModel = new DefaultTableModel(5, 10);
scrollPane = new JScrollPane();
mainTable = new JTable(mainTableModel);
mainColumnModel = mainTable.getColumnModel();
fixedTable = new JTable();
fixedTable.setAutoCreateColumnsFromModel(false);
fixedTable.setModel(mainTable.getModel() );
ncols = mainTableModel.getColumnCount();
columns = new TableColumn[ncols];
for (int i=0;i<ncols;i++){
columns[i] = mainColumnModel.getColumn(i);
}
mainColumnModel = mainTable.getColumnModel();
fixedColumnModel = fixedTable.getColumnModel();
mainTableHeader = mainTable.getTableHeader();
mainTableHeader.addMouseListener( new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent me){
if (SwingUtilities.isRightMouseButton(me)){
if (ncols - counter>1){
counter ++;
int col = mainTable.columnAtPoint(me.getPoint());
TableColumn column = mainColumnModel.getColumn(col);
mainColumnModel.removeColumn(column);
fixedTable.getColumnModel().addColumn(column);
scrollPane.setRowHeaderView(fixedTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
}
}
}
});
fixedTable.getTableHeader().addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent me){
if (SwingUtilities.isRightMouseButton(me) && me.getClickCount()== 2 ){
while (mainColumnModel.getColumnCount() > 0){
mainColumnModel.removeColumn(mainColumnModel.getColumn(0));
}
while (fixedColumnModel.getColumnCount() > 0){
fixedColumnModel.removeColumn(fixedColumnModel.getColumn(0));
}
for(int i=0;i<ncols;i++){
mainColumnModel.addColumn(columns[i]);
}
scrollPane.setRowHeaderView(null);
}
}
});
scrollPane.setViewportView(mainTable);
add(scrollPane, BorderLayout.CENTER);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Prova().setVisible(true);
}
});
}
}
发布 SSCCE 时的一些提示:
for (int i=0;i<ncols;i++){
不要害怕在您的代码中使用空格来分隔 for 语句的 3 个语句以使其更具可读性。
for (int i = 0; i < ncols; i++){
保持代码简单并与问题直接相关:
TableModel mainTableModel = new EmployeeTableModel(listEmployees);
您的问题是关于 "moving columns",而不是关于 table 中的数据,因此不需要特殊的 TableModel 和 Employee class。只需使用 DefaultTableModel:
TableModel mainTableModel = new DefaultTableModel(5, 10);
您当前的代码无法编译,因为您没有包含 Employee class。通过使用 JDK classes,代码更小且更易于阅读。
The problem is when you unlock all the locked columns and you want to start to lock again, doesnt work
你的循环代码是错误的。我懒得去弄清楚哪里出了问题。相反,我使代码更简单:
//for(int i=0;i<(ncols-counter);i++){
while (mainColumnModel.getColumnCount() > 0)
{
mainColumnModel.removeColumn(mainColumnModel.getColumn(0));
}
//for(int i=0;i<counter;i++){
while (fixedColumnModel.getColumnCount() > 0)
{
fixedColumnModel.removeColumn(fixedColumnModel.getColumn(0));
}
另一个问题是你的固定 table 没有 header 所以你不知道列是什么。这是通过使用修复的:
scrollPane.setRowHeaderView(fixedTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
现在您有了 header,您需要将 MouseListener 添加到 header,而不是滚动窗格:
//scrollPane.addMouseListener(new MouseAdapter() {
fixedTable.getTableHeader().addMouseListener(new MouseAdapter() {
编辑:
您遇到的问题与我上面解决的问题类似。那就是当您可以使用组件本身时,不要继续使用变量来跟踪值。
if (ncols - counter>1){
您永远不会重置计数器的值,因此 if 条件不会第二次为真。
正如我在上面所做的那样,只使用列模型中的值:
//if (ncols - counter>1){
if (mainColumnModel.getColumnCount() > 1) {
这只是基本的问题解决。在代码块中放一条显示语句,看你遇到问题时是否执行。
我创建了一个可以动态锁定和解锁列的 class。 在我的程序中,我创建了两个具有相同 table 模型的 table。 一个在滚动窗格的 Jviewport 中,另一个在 RowHeaderView 中。 问题是当您解锁所有锁定的列时 而你想重新开始锁定,是行不通的。没有错误,但好像事件没有响应。
产生问题的步骤:
- 尝试代码,
- 将所有列固定在 table、
- 然后右键双击解锁,
- 然后重新开始锁定,解锁
执行此过程,您可以看到鼠标事件不再响应
public class Prova extends JFrame{
private JTable mainTable,fixedTable;
private JScrollPane scrollPane;
private JTableHeader mainTableHeader;
private TableColumnModel originalColumnModel,mainColumnModel,fixedColumnModel;
private TableColumn[] columns;
private int ncols,counter;
public Prova(){
counter = 0;
TableModel mainTableModel = new DefaultTableModel(5, 10);
scrollPane = new JScrollPane();
mainTable = new JTable(mainTableModel);
mainColumnModel = mainTable.getColumnModel();
fixedTable = new JTable();
fixedTable.setAutoCreateColumnsFromModel(false);
fixedTable.setModel(mainTable.getModel() );
ncols = mainTableModel.getColumnCount();
columns = new TableColumn[ncols];
for (int i=0;i<ncols;i++){
columns[i] = mainColumnModel.getColumn(i);
}
mainColumnModel = mainTable.getColumnModel();
fixedColumnModel = fixedTable.getColumnModel();
mainTableHeader = mainTable.getTableHeader();
mainTableHeader.addMouseListener( new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent me){
if (SwingUtilities.isRightMouseButton(me)){
if (ncols - counter>1){
counter ++;
int col = mainTable.columnAtPoint(me.getPoint());
TableColumn column = mainColumnModel.getColumn(col);
mainColumnModel.removeColumn(column);
fixedTable.getColumnModel().addColumn(column);
scrollPane.setRowHeaderView(fixedTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
}
}
}
});
fixedTable.getTableHeader().addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent me){
if (SwingUtilities.isRightMouseButton(me) && me.getClickCount()== 2 ){
while (mainColumnModel.getColumnCount() > 0){
mainColumnModel.removeColumn(mainColumnModel.getColumn(0));
}
while (fixedColumnModel.getColumnCount() > 0){
fixedColumnModel.removeColumn(fixedColumnModel.getColumn(0));
}
for(int i=0;i<ncols;i++){
mainColumnModel.addColumn(columns[i]);
}
scrollPane.setRowHeaderView(null);
}
}
});
scrollPane.setViewportView(mainTable);
add(scrollPane, BorderLayout.CENTER);
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Prova().setVisible(true);
}
});
}
}
发布 SSCCE 时的一些提示:
for (int i=0;i<ncols;i++){
不要害怕在您的代码中使用空格来分隔 for 语句的 3 个语句以使其更具可读性。
for (int i = 0; i < ncols; i++){
保持代码简单并与问题直接相关:
TableModel mainTableModel = new EmployeeTableModel(listEmployees);
您的问题是关于 "moving columns",而不是关于 table 中的数据,因此不需要特殊的 TableModel 和 Employee class。只需使用 DefaultTableModel:
TableModel mainTableModel = new DefaultTableModel(5, 10);
您当前的代码无法编译,因为您没有包含 Employee class。通过使用 JDK classes,代码更小且更易于阅读。
The problem is when you unlock all the locked columns and you want to start to lock again, doesnt work
你的循环代码是错误的。我懒得去弄清楚哪里出了问题。相反,我使代码更简单:
//for(int i=0;i<(ncols-counter);i++){
while (mainColumnModel.getColumnCount() > 0)
{
mainColumnModel.removeColumn(mainColumnModel.getColumn(0));
}
//for(int i=0;i<counter;i++){
while (fixedColumnModel.getColumnCount() > 0)
{
fixedColumnModel.removeColumn(fixedColumnModel.getColumn(0));
}
另一个问题是你的固定 table 没有 header 所以你不知道列是什么。这是通过使用修复的:
scrollPane.setRowHeaderView(fixedTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
现在您有了 header,您需要将 MouseListener 添加到 header,而不是滚动窗格:
//scrollPane.addMouseListener(new MouseAdapter() {
fixedTable.getTableHeader().addMouseListener(new MouseAdapter() {
编辑:
您遇到的问题与我上面解决的问题类似。那就是当您可以使用组件本身时,不要继续使用变量来跟踪值。
if (ncols - counter>1){
您永远不会重置计数器的值,因此 if 条件不会第二次为真。
正如我在上面所做的那样,只使用列模型中的值:
//if (ncols - counter>1){
if (mainColumnModel.getColumnCount() > 1) {
这只是基本的问题解决。在代码块中放一条显示语句,看你遇到问题时是否执行。