2012-03-05 56 views
2

我有以下方法延伸的JTable:的JTable改变鼠标在我的课光标

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

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

这种方法被称为不时显示等待光标时,表从数据库更新。

它的问题是,现在当我尝试和调整列大小,我看不到默认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

有两个/三个原因,为什么可以更快地提供更好的帮助,请使用[SSCCE](http://sscce.org/) – mKorbel 2012-03-05 12:53:25

+0

@mKorbel编辑您的文章:添加SSCCE。 – GrayR 2012-03-05 13:50:58

+1

游标重置逻辑错误 - 根据鼠标的位置(有一个位于调整大小区域内而另一个位于外部时),有两个“默认”游标。您可以通过检查调整大小列来区分这两者。 – kleopatra 2012-03-05 13:55:47

回答

2

而不是默认设置光标两个光标(用于头和表)为null时不需要显示等待光标。

+0

谢谢!不幸的是没有为我的代码工作,但我同意你的建议比初始代码更好。 – GrayR 2012-03-05 13:48:18

+0

原来的问题也是在设置面板包含表格setEnabled(false):(修复后,并使用本主题中的评论和答案,我能够解决它。 – GrayR 2012-03-16 01:17:02