/* * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.ui; import com.intellij.util.PairFunction; import com.intellij.util.containers.Convertor; import javax.swing.*; import javax.swing.table.TableModel; import java.util.ListIterator; public class TableSpeedSearch extends SpeedSearchBase<JTable> { private static final PairFunction<Object, Cell, String> TO_STRING = new PairFunction<Object, Cell, String>() { public String fun(Object o, Cell cell) { return o == null ? "" : o.toString(); } }; private final PairFunction<Object, Cell, String> myToStringConvertor; public TableSpeedSearch(JTable table) { this(table, TO_STRING); } public TableSpeedSearch(JTable table, final Convertor<Object, String> toStringConvertor) { this(table, new PairFunction<Object, Cell, String>() { @Override public String fun(Object o, Cell c) { return toStringConvertor.convert(o); } }); } public TableSpeedSearch(JTable table, final PairFunction<Object, Cell, String> toStringConvertor) { super(table); myToStringConvertor = toStringConvertor; } protected boolean isSpeedSearchEnabled() { return !getComponent().isEditing() && super.isSpeedSearchEnabled(); } @Override protected ListIterator<Object> getElementIterator(int startingIndex) { return new MyListIterator(startingIndex); } protected int getElementCount() { final TableModel tableModel = myComponent.getModel(); return tableModel.getRowCount() * tableModel.getColumnCount(); } protected void selectElement(Object element, String selectedText) { final int index = ((Integer)element).intValue(); final TableModel model = myComponent.getModel(); final int row = index / model.getColumnCount(); final int col = index % model.getColumnCount(); myComponent.getSelectionModel().setSelectionInterval(row, row); myComponent.getColumnModel().getSelectionModel().setSelectionInterval(col, col); TableUtil.scrollSelectionToVisible(myComponent); } protected int getSelectedIndex() { final int row = myComponent.getSelectedRow(); final int col = myComponent.getSelectedColumn(); // selected row is not enough as we want to select specific cell in a large multi-column table return row > -1 && col > -1 ? row * myComponent.getModel().getColumnCount() + col : -1; } protected Object[] getAllElements() { throw new UnsupportedOperationException("Not implemented"); } protected String getElementText(Object element) { final int index = ((Integer)element).intValue(); final TableModel model = myComponent.getModel(); int row = myComponent.convertRowIndexToModel(index / model.getColumnCount()); int col = myComponent.convertColumnIndexToModel(index % model.getColumnCount()); Object value = model.getValueAt(row, col); return myToStringConvertor.fun(value, new Cell(row, col)); } private class MyListIterator implements ListIterator<Object> { private int myCursor; public MyListIterator(int startingIndex) { final int total = getElementCount(); myCursor = startingIndex < 0 ? total : startingIndex; } public boolean hasNext() { return myCursor < getElementCount(); } public Object next() { return myCursor++; } public boolean hasPrevious() { return myCursor > 0; } public Object previous() { return (myCursor--) - 1; } public int nextIndex() { return myCursor; } public int previousIndex() { return myCursor - 1; } public void remove() { throw new AssertionError("Not Implemented"); } public void set(Object o) { throw new AssertionError("Not Implemented"); } public void add(Object o) { throw new AssertionError("Not Implemented"); } } }