如何在 Java 中选择标题时选择 JTable 列

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20265858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 00:42:12  来源:igfitidea点击:

How to select a JTable column on selection of header in Java

javaswinguser-interfacejtable

提问by user1709952

I found a code to select a column on click of JTable header by applying a mouse listener on the header. But unfortunately, on click of a table cell whole JTable column is selected and the selection strategy is not reversed as before. Instead it selects the whole column on selection of a cell.

我找到了一个代码,通过在标题上应用鼠标侦听器,在单击 JTable 标题时选择一列。但不幸的是,单击表格单元格时会选择整个 JTable 列,并且选择策略并没有像以前那样颠倒。相反,它在选择单元格时选择整列。

enter image description here

在此处输入图片说明

Code:-

代码:-

import java.awt.Component;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;

public class HeaderLocation {  
    private JTable getTable() {  
        int rows = 32, cols = 4;  
        String[] colIds = { "column 1", "column 2", "column 3", "column 4" };  
        Object[][] data = new Object[rows][cols];  
        for(int row = 0; row < rows; row++) {  
            for(int col = 0; col < cols; col++) {  
                data[row][col] = "item " + (row*cols+col+1);  
            }  
        }  
        DefaultTableModel model = new DefaultTableModel(data, colIds);  
        final JTable table = new JTable(model);  
        final JTableHeader header = table.getTableHeader();  
        table.setCellEditor(new CustomCellEditor());
        header.setReorderingAllowed(false);  
        header.addMouseListener(new MouseAdapter() {  
            public void mouseClicked(MouseEvent e) {  
                int col = header.columnAtPoint(e.getPoint());  
                System.out.printf("click cursor = %d%n",  
                                   header.getCursor().getType());  
                if(header.getCursor().getType() == Cursor.E_RESIZE_CURSOR)  
                    e.consume();  
                else {  
                    //System.out.printf("sorting column %d%n", col); 
                    table.setColumnSelectionAllowed(true);
                    table.setRowSelectionAllowed(false);
                    table.clearSelection();
                    table.setColumnSelectionInterval(col,col);
                    //tableModel[selectedTab].sortArrayList(col);  
                }  
            }  
        });  


        return table;  
    }  

    private JMenuBar getMenuBar() {  
        final JMenu view = new JMenu("view");  
        ActionListener l = new ActionListener() {  
            public void actionPerformed(ActionEvent e) {  
                JMenuItem item = (JMenuItem)e.getSource();  
                String className = item.getActionCommand();  
                changePLAF(className, view.getTopLevelAncestor());  
            }  
        };  
        UIManager.LookAndFeelInfo[] info = UIManager.getInstalledLookAndFeels();  
        for(int j = 0; j < info.length; j++) {  
            JMenuItem item = new JMenuItem(info[j].getName());  
            item.setActionCommand(info[j].getClassName());  
            item.addActionListener(l);  
            view.add(item);  
        }  
        JMenuBar menuBar = new JMenuBar();  
        menuBar.add(view);  
        return menuBar;  
    }  

    private void changePLAF(String className, Component c) {  
        try {  
            UIManager.setLookAndFeel(className);  
        } catch(ClassNotFoundException cnfe) {  
            System.err.println("class not found: " + cnfe.getMessage());  
        } catch(InstantiationException ie) {  
            System.err.println("instantiation: " + ie.getMessage());  
        } catch(IllegalAccessException iae) {  
            System.err.println("illegal access: " + iae.getMessage());  
        } catch(UnsupportedLookAndFeelException ulafe) {  
            System.err.println("unsupported laf: " + ulafe.getMessage());  
        }  
        SwingUtilities.updateComponentTreeUI(c);  
    }  

    public static void main(String[] args) {  
        HeaderLocation test = new HeaderLocation();  
        JFrame f = new JFrame();  
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        f.setJMenuBar(test.getMenuBar());  
        f.getContentPane().add(new JScrollPane(test.getTable()));  
        f.pack();  
        f.setLocation(200,200);  
        f.setVisible(true);  
    }  
}

CustomCellEditor.java

自定义单元编辑器.java

import java.awt.Component;

import javax.swing.DefaultCellEditor;
import javax.swing.JTable;
import javax.swing.JTextField;

public class CustomCellEditor extends DefaultCellEditor {

    public CustomCellEditor() {
        super(new JTextField());
        // TODO Auto-generated constructor stub
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        table.clearSelection();
        table.setColumnSelectionAllowed(false);
        table.setRowSelectionAllowed(true);
        return super.getTableCellEditorComponent(table, value, isSelected, row, column);
        }

}  

From the above code:-

从上面的代码: -

1.) On click of header column is properly selected. 2.) But on click of a cell whole column is selected not only one cell as expected. I tried to invert Column selection but it's not working as expected.

1.) 点击标题栏被正确选择。2.) 但是在单击一个单元格时,整个列被选中,而不是按预期选择一个单元格。我试图反转列选择,但它没有按预期工作。

Any help related with this would be greatly appreciated.

任何与此相关的帮助将不胜感激。

Thanks

谢谢

回答by alex2410

Your selection switching beetween columns and rows works. Your problem that you don't set your editor to table columns, because setCellEditor()method of JTabledo another thing, read about it.

您的选择在列和行之间切换有效。您没有将编辑器设置为表格列的问题,因为做另一件事的setCellEditor()方法,JTable阅读它

For adding your editor to columns, you need to replace table.setCellEditor(new CustomCellEditor());with :

要将编辑器添加到列,您需要替换table.setCellEditor(new CustomCellEditor());为:

    Enumeration<TableColumn> columns = table.getColumnModel().getColumns();
    while(columns.hasMoreElements()){
        columns.nextElement().setCellEditor(new CustomCellEditor());
    }

EDIT:

编辑:

Now selectionMode switching when you select header, or start editing your table cell. You can add a mouseListenr to your table or change click count to start editing cell, for switching every time :

当您选择标题或开始编辑表格单元格时,现在选择模式切换。您可以在表格中添加一个 mouseListenr 或更改点击次数以开始编辑单元格,以便每次切换:

  table.addMouseListener(new MouseAdapter() {
          public void mouseClicked(MouseEvent e) {  
              table.setColumnSelectionAllowed(false);
              table.setRowSelectionAllowed(true);
          }  
    });

setClickCountToStart()

setClickCountToStart()

回答by mKorbel

you would need to reverse code lines declared inside header.addMouseListener(new MouseAdapter() {back

你需要扭转的代码行声明中header.addMouseListener(new MouseAdapter() {

from

table.setColumnSelectionAllowed(true);
table.setRowSelectionAllowed(false);

to

table.setColumnSelectionAllowed(false);
table.setRowSelectionAllowed(true);

in 1st mouse eventsoutside of JTableHeader

在第一个mouse events外面JTableHeader

回答by Nitz Exe

I created a method setColumnSelect having a parameter - JTable.
This method adds addMouseListener to JTable and JTableHeader.
If first column header is clicked then all table cells are selected.
If any other column header is clicked then entire column is selected.
If any cell is clicked then only that cell is selected.
If any cell of first column is clicked / double -clicked then only that entire row is selected.
After selecting the entire column and dragging the mouse over the cells of other columns makes those columns entirely selected.
After selecting a single row and dragging mouse over rows makes other rows entirely selected.

我创建了一个方法 setColumnSelect 有一个参数 - JTable。
此方法将 addMouseListener 添加到 JTable 和 JTableHeader。
如果单击第一个列标题,则选择所有表格单元格。
如果单击任何其他列标题,则会选择整个列。
如果单击任何单元格,则仅选择该单元格。
如果单击/双击第一列的任何单元格,则仅选择整行。
选择整列并将鼠标拖到其他列的单元格上后,将完全选择这些列。
选择单行并在行上拖动鼠标后,其他行将被完全选中。

public void setColumnSelect(JTable table) {
    final JTable finalTable = table;
    final JTableHeader columnHeader = finalTable.getTableHeader();

    //For Row Selection

    finalTable.addMouseListener(new MouseAdapter() {

        public void mouseClicked(MouseEvent mouseEvent) {
            finalTable.setColumnSelectionAllowed(true);
            finalTable.setRowSelectionAllowed(true);

            if (finalTable.isCellSelected(finalTable.getSelectedRow(), 0)) {
                finalTable.setColumnSelectionAllowed(false);
                finalTable.setRowSelectionAllowed(true);                    
            }

        }
    });

    //For Column Selection

    columnHeader.addMouseListener(new MouseAdapter() {

        public void mouseClicked(MouseEvent mouseEvent) {
            columnPoint =  columnHeader.columnAtPoint(mouseEvent.getPoint());

            columnCursorType = columnHeader.getCursor().getType();

            if (columnCursorType == Cursor.E_RESIZE_CURSOR)
                mouseEvent.consume();
            else {

                if (columnPoint == 0) //the very first column header
                    finalTable.selectAll(); //will select all table cells
                else {
                    finalTable.setColumnSelectionAllowed(true);
                    finalTable.setRowSelectionAllowed(false);
                    finalTable.clearSelection();
                    finalTable.setColumnSelectionInterval(columnPoint, columnPoint);
                }

            }
        }
    });

}

回答by Morgan

Use this easy solution. I think this is what you're looking for.

使用这个简单的解决方案。我想这就是你要找的。

table.getTableHeader().addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        int clickedIndex = table.convertColumnIndexToModel(table.columnAtPoint(e.getPoint()));
        table.setColumnSelectionInterval(clickedIndex, clickedIndex); //selects which column will have all its rows selected
        table.setRowSelectionInterval(0, table.getRowCount() - 1); //once column has been selected, select all rows from 0 to the end of that column
    }
});

回答by Jay Yang

Add a mouse adapter to your JTable in main function:

在主函数中向 JTable 添加鼠标适配器:

tableSet.getTableHeader().addMouseListener(getTableHeaderMouseAdapter(tableSet));

The mouse adapter could be:

鼠标适配器可以是:

protected static MouseAdapter getTableHeaderMouseAdapter(final JTable tableSet) {return new MouseAdapter(){
        public void mouseClicked(MouseEvent e) {
            int c = tableSet.columnAtPoint(e.getPoint());
            tableSet.setColumnSelectionInterval(c, c);
            if(tableSet.getRowCount() > 0){
                tableSet.setRowSelectionInterval(0, tableSet.getRowCount()-1);
            }
        }
    };
}