JTable更改鼠标光标

时间:2012-03-05 12:48:08

标签: java swing cursor jtable

我的课程中有以下方法,它扩展了JTable:

  protected void setTableCursor(Cursor cursor) {
// data gathering
cursor = (cursor != null) ? cursor : Cursor.getDefaultCursor();
JTableHeader header = getTableHeader();

// set
header.setCursor(cursor);
setCursor(cursor);
}

当从DB更新表时,会不时调用此方法来显示WAIT游标。

问题在于,现在当我尝试调整列的大小时,我看不到默认的SPLIT游标。如何解决这个问题?所以我需要添加一些代码,以便当鼠标靠近列的边缘时鼠标光标始终显示分割光标。

请同时查看以下示例。要重现问题,只需在列分隔符上完全双击表格标题:

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;
abstract public class DemoTable extends JTable
{
protected DemoTable() {
    super();
    compose(false);
}
private void compose(boolean allowMultipleSelection) {
    setModel(new DefaultTableModel(getColumnNames(), 0));
    setColumnSelectionAllowed(false);
    getSelectionModel().setSelectionMode(allowMultipleSelection ? ListSelectionModel.MULTIPLE_INTERVAL_SELECTION : ListSelectionModel.SINGLE_SELECTION);
    getTableHeader().setReorderingAllowed(false);
    getTableHeader().addMouseListener(new ColumnResizeListener(this));
}

protected void setTableCursor(Cursor cursor) {
    // data gathering
    cursor = (cursor != null) ? cursor : null;
    JTableHeader header = getTableHeader();
    // set
    header.setCursor(cursor);
    setCursor(cursor);
}

public void adjustColumnWidth(int column) {
    setPreferredColumnWidth(column, getPreferredSizeForColumn(column));
}

private int getPreferredSizeForColumn(int columnIndex) {
    // base setup
    int preferredWidth = 0;
    int rowCount = getRowCount();
    TableColumnModel columnModel = getColumnModel();
    TableColumn column = columnModel.getColumn(columnIndex);

    TableCellRenderer renderer;
    Component rendererComponent = null;

    // header
    renderer = column.getHeaderRenderer();
    if (renderer != null) {
        rendererComponent = renderer.getTableCellRendererComponent(this, column.getHeaderValue(), false, false, 0, 0);
        if (rendererComponent != null) {
            preferredWidth = rendererComponent.getPreferredSize().width;
        }
    }

    // rendered values
    Object value;
    for (int row = 0; row < rowCount; row++) {
        // base setup
        value = getValueAt(row, columnIndex);

        // renderer lookup
        renderer = getCellRenderer(row, columnIndex);
        if (renderer != null)
            rendererComponent = renderer.getTableCellRendererComponent(this, value, false, false, row, columnIndex);
        rendererComponent = (rendererComponent == null) ? new JLabel((value == null) ? "" : value.toString()) : rendererComponent;

        // calculate the preferred size
        preferredWidth = Math.max(preferredWidth, rendererComponent.getPreferredSize().width);
    }

    // exit
    return (preferredWidth <= 0) ? 25 : (preferredWidth + 15);
}

public void adjustColumnWidths() {

    Thread updateThread = new Thread()
    {
        public void run() {
            try {
                SwingUtilities.invokeAndWait(new Runnable()
                {
                    public void run() {
                        int columns = getModel().getColumnCount();
                        Map<Integer, Integer> preferredWidths = new HashMap<Integer, Integer>();
                        for (int column = 0; column < columns; column++)
                            preferredWidths.put(column, getPreferredSizeForColumn(column));

                        // run the sets
                        for (Map.Entry<Integer, Integer> column : preferredWidths.entrySet())
                            setPreferredColumnWidth(column.getKey(), column.getValue());
                    }
                });

                // pause momentarily to let the cursor update take place
                sleep(75);
            }
            catch (Exception e) {
                // ignore
            }
            finally {
                setTableCursor(null);
            }
        }
    };

    // execute the thread
    updateThread.start();
    if (updateThread.isAlive())
        setTableCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
}

private void setPreferredColumnWidth(int column, int preferredWidth) {
    getColumnModel().getColumn(column).setPreferredWidth(preferredWidth);
}

abstract protected String[] getColumnNames();

@Override
public boolean isCellEditable(int row, int column) {
    return false;
}

private static class ColumnResizeListener extends MouseAdapter
{
    DemoTable table;
    public ColumnResizeListener(DemoTable table) {
        super();

        // attribute initialization
        this.table = table;
    }
    @Override
    public void mouseClicked(MouseEvent e) {
        if (e.getSource() instanceof JTableHeader) {
            // data gathering
            int clicks = e.getClickCount();

            // single click
            if (clicks == 1) {
                int column = table.getColumnModel().getColumnIndexAtX(e.getX());
                table.adjustColumnWidth(column);
            }

            // double-click
            else if (clicks == 2)
                table.adjustColumnWidths();
        }
    }
}

public static void main(String args[]) {
    final DemoTable table = new DemoTable() {
        @Override
        protected String[] getColumnNames() {
            return new String[]{"one","two"};
        }
    };
    JFrame frame = new JFrame("Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ((DefaultTableModel)table.getModel()).addRow(new String[]{"1", "2"});
    ((DefaultTableModel)table.getModel()).addRow(new String[]{"1","2"});
    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout());
    panel.add(table.getTableHeader(), BorderLayout.NORTH);
    panel.add(table, BorderLayout.CENTER);
    frame.add(panel);
    frame.pack();
    panel.setSize(new Dimension(200, 100));
    frame.setVisible(true);
}
}

1 个答案:

答案 0 :(得分:2)

当不需要显示WAIT游标时,而不是默认游标将两个游标(用于标题和表)设置为null。