編集されないセルにカーソルを移動しないテープル(Cursor跳过不可编辑的单元格的JTable)

近日为Cursor在JTable的单元格中移动问题,颇为苦恼,终于解决了。
但是有点遗憾,在把TabEditTable应用到JScrollPane上的时候,按下Tab键将Cursor移动到JTable的不可视区域时,
JScrollPane不能自动滚动了。

2004/12/09  不幸的消息:如果把这个table类放到滚动面板上,按下tab键当光标移动到不可见区域时,滚动条不
能自动滚动了。应该是FocusManager的问题。 
解决中.........................................

/* パッケージの指定 */
package common.table;
/* パッケージのimport */
import javax.swing.*;
import javax.swing.FocusManager;
import javax.swing.table.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/**
 * 編集されないセルにカーソルを移動しないテープル
 * @version $Revision: 1.4 $ $Date: 2004/10/23 03:23:10 $
 */
public class TabEditTable extends JTable
{
 protected boolean inTabbingEditor;
 //protected FocusManager focusManager;
 protected int[] editingColumns; // Model columns
 protected int[] viewEditingColumns; // View columns
 protected TabKeyListener tabKeyListener = new TabKeyListener();
 /**デフォルトコンストラクタ*/
 public TabEditTable()
 {
  super();
 }
 /**
  * データモデル dm、デフォルト列モデル、デフォルト選択モデルで初期化される JTable を構築します。
  * @param dm テーブルのデータモデル
  */
 public TabEditTable(TableModel dm)
 {
  super(dm);
 }
 /**
  * デフォルト選択モデルで初期化される JTable を構築します。
  * @param dm テーブルのデータモデル
  * @param cm テーブルの列モデル
  */
 public TabEditTable(TableModel dm, TableColumnModel cm)
 {
  super(dm, cm);
 }
 /**
  * 初期化される JTable を構築します。
  * パラメータのどれかが null の場合、このメソッドは対応するデフォルトモデルでテーブルを初期化します。
  * @param dm テーブルのデータモデル
  * @param cm テーブルの列モデル
  * @param sm テーブルの行選択モデル
  */
 public TabEditTable(
  TableModel dm,
  TableColumnModel cm,
  ListSelectionModel sm)
 {
  super(dm, cm, sm);
 }
 /**
  * DefaultTableModel を使って、空のセルの numRows と numColumns で JTable を構築します。
  * 列は、「A」、「B」、「C」といった形式の名前を持ちます。
  * @param numRows テーブルが保持する行数
  * @param numColumns テーブルが保持する列数
  */
 public TabEditTable(int numRows, int numColumns)
 {
  super(numRows, numColumns);
 }
 /**
  * Vectors の Vector の値を表示する JTable、つまり rowData を、列名 columnNames で構築します。
  * rowData に格納された Vectors は、その行の値を保持しなければなりません。
  * つまり、行 1、列 5 に位置するセルの値は次のコードで取得できます。
  * @param rowData 新しいテーブルのデータ
  * @param columnNames 各列の名前
  */
 public TabEditTable(final Vector rowData, final Vector columnNames)
 {
  super(rowData, columnNames);
 }
 /**
  * 2 次元配列 rowData の値を表示する JTable を、列名 columnNames で構築します。
  * rowData は行の配列なので、行 1、列 5 に位置するセルの値は次のコードで取得できます。
  * rowData[1][5]; すべての行は、columnNames と同じ長さでなければなりません。
  * @param rowData 新しいテーブルのデータ
  * @param columnNames 各列の名前
  */
 public TabEditTable(final Object[][] rowData, final Object[] columnNames)
 {
  super(rowData, columnNames);
 }
 /**
  * editingColumns 変数を設定します。
  * @param columns
  */
 public void setEditingColumns(int[] columns)
 {
  editingColumns = columns;
  convertEditableColumnsToView();
 }
 /**
  * editingColumns 変数を取得します。
  * @return
  */
 public int[] getEditingColumns()
 {
  return editingColumns;
 }
    /**
     * Overrides of JTable methods
     * row および column に位置するセルが編集可能な場合は、編集をプログラムに基づいて開始します。
     * @param row 編集する行
     * @param column 編集する列
     * @param evt イベント
     */
 public boolean editCellAt(int row, int column, EventObject evt)
 {
  if (super.editCellAt(row, column, evt) == false)
  {
   return false;
  }
  if (viewEditingColumns != null)
  {
   // Note: column is specified in terms
   // of the column model
   int length = viewEditingColumns.length;
   for (int i = 0; i < length; i++)
   {
    if (column == viewEditingColumns[i])
    {
     Component comp = getEditorComponent();
     comp.addKeyListener(tabKeyListener);
     this.addKeyListener(tabKeyListener);
     //focusManager = FocusManager.getCurrentManager();
     
     //FocusManager.disableSwingFocusManager();
     inTabbingEditor = true;
     comp.requestFocus();
     break;
    }
   }
  }
  return true;
 }
 /**
  * 編集が完了したときに呼び出されます。変更は保存され、エディタは破棄されます。
  * @param evt 受け取ったイベント
  */
 public void editingStopped(ChangeEvent evt)
 {
  if (inTabbingEditor == true)
  {
   Component comp = getEditorComponent();
   comp.removeKeyListener(tabKeyListener);
   this.removeKeyListener(tabKeyListener);
   //FocusManager.setCurrentManager(focusManager);
   inTabbingEditor = false;
  }
  super.editingStopped(evt);
 }
 /**
  * フォーカスを移動処理を制御
  */
 protected void convertEditableColumnsToView()
 {
  // Convert the editable columns to view column numbers
  if (editingColumns == null)
  {
   viewEditingColumns = null;
   return;
  }
  // Create a set of editable columns in terms of view
  // column numbers in ascending order. Note that not all
  // editable columns in the data model need be visible.
  int length = editingColumns.length;
  viewEditingColumns = new int[length];
  int nextSlot = 0;
  for (int i = 0; i < length; i++)
  {
   int viewIndex = convertColumnIndexToView(editingColumns[i]);
   if (viewIndex != -1)
   {
    viewEditingColumns[nextSlot++] = viewIndex;
   }
  }
  // Now create an array of the right length
  // to hold the view indices
  if (nextSlot < length)
  {
   int[] tempArray = new int[nextSlot];
   System.arraycopy(viewEditingColumns, 0, tempArray, 0, nextSlot);
   viewEditingColumns = tempArray;
  }
  // Finally, sort the view columns into order
  TableUtilities.sort(viewEditingColumns);
 }
 /**
  * 後ろのエディタへフォーカスを移動する
  * @param row
  * @param column
  * @param forward
  */
 protected void moveToNextEditor(int row, int column, boolean forward)
 {
  // Column is specified in terms of the column model
  if (viewEditingColumns != null)
  {
   int length = viewEditingColumns.length;
   // Move left-to-right or right-to-left
   // across the table
   for (int i = 0; i < length; i++)
   {
    if (viewEditingColumns[i] == column)
    {
     // Select the next column to edit
     if (forward == true)
     {
      if (++i == length)
      {
       // Reached end of row - wrap
       i = 0;
       row++;
       if (row == getRowCount())
       {
        // End of table - wrap
        row = 0;
       }
      }
     } else
     {
      if (--i < 0)
      {
       i = length - 1;
       row--;
       if (row < 0)
       {
        row = getRowCount() - 1;
       }
      }
     }
     final int newRow = row;
     final int newColumn = viewEditingColumns[i];
     // Start editing at new location
     SwingUtilities.invokeLater(new Runnable()
     {
      public void run()
      {
       editCellAt(newRow, newColumn);
       ListSelectionModel rowSel = getSelectionModel();
       ListSelectionModel columnSel =
        getColumnModel().getSelectionModel();
       rowSel.setSelectionInterval(newRow, newRow);
       columnSel.setSelectionInterval(
        newColumn,
        newColumn);
      }
     });
     break;
    }
   }
  }
 }
 // Catch changes to the table column model
 public void columnAdded(TableColumnModelEvent e)
 {
  super.columnAdded(e);
  convertEditableColumnsToView();
 }
 public void columnRemoved(TableColumnModelEvent e)
 {
  super.columnRemoved(e);
  convertEditableColumnsToView();
 }
 public void columnMoved(TableColumnModelEvent e)
 {
  super.columnMoved(e);
  convertEditableColumnsToView();
 }
 /**
  * タプキーリスナー
  * 後ろのエディタへフォーカスを移動する
  */
 public class TabKeyListener extends KeyAdapter
 {
  public void keyPressed(KeyEvent evt)
  {
   if (evt.getKeyCode() == KeyEvent.VK_TAB)
   {
    if (inTabbingEditor == true)
    {
     TableCellEditor editor = getCellEditor();
     int editRow = getEditingRow();
     int editColumn = getEditingColumn();
     if (editor != null)
     {
      boolean stopped = editor.stopCellEditing();
      if (stopped == true)
      {
       boolean forward = (evt.isShiftDown() == false);
       moveToNextEditor(editRow, editColumn, forward);
      }
     }
    }
   } else {
    
    if ( evt.getKeyCode() == KeyEvent.VK_RIGHT) {
              
     if (inTabbingEditor == true) {

      TableCellEditor editor = getCellEditor();
      int editRow = getEditingRow();
      int editColumn = getEditingColumn();

      if (editor != null) {

       boolean stopped = editor.stopCellEditing();

       if (stopped == true) {

        boolean forward = (evt.isShiftDown() == false);
        moveToNextEditor(editRow, editColumn, forward);
       }
      }
     }
    } else if ( evt.getKeyCode() == KeyEvent.VK_LEFT ) {
              
     if (inTabbingEditor == true) {

      TableCellEditor editor = getCellEditor();
      int editRow = getEditingRow();
      int editColumn = getEditingColumn();

      if (editor != null) {

       boolean stopped = editor.stopCellEditing();

       if (stopped == true) {

        boolean forward = (evt.isShiftDown() == true);
        moveToNextEditor(editRow, editColumn, forward);
       }
      }
     }
    }
   }
  }
 }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值