/* * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package javafx.scene.control; import javafx.beans.property.ReadOnlyIntegerProperty; import javafx.beans.property.ReadOnlyIntegerWrapper; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectWrapper; /** * The abstract base class for FocusModel implementations. * @since JavaFX 2.0 */ public abstract class FocusModel { /*********************************************************************** * * * Constructors * * * **********************************************************************/ /** * Creates a default FocusModel instance. */ public FocusModel() { focusedIndexProperty().addListener(valueModel -> { // we used to lazily retrieve the focused item, but now we just // do it when the focused index changes. setFocusedItem(getModelItem(getFocusedIndex())); }); } /*************************************************************************** * * * Focus Properties * * * **************************************************************************/ /** * The index of the current item in the FocusModel which has the focus. It * is possible that this will be -1, but only if the control is empty. * If the control is not itself focused, this property will still * reference the row index that would receive the keyboard focus if the control * itself were focused. */ private ReadOnlyIntegerWrapper focusedIndex = new ReadOnlyIntegerWrapper(this, "focusedIndex", -1); public final ReadOnlyIntegerProperty focusedIndexProperty() { return focusedIndex.getReadOnlyProperty(); } public final int getFocusedIndex() { return focusedIndex.get(); } final void setFocusedIndex(int value) { focusedIndex.set(value); } /** * The current item in the FocusModel which has the focus. It * is possible that this will be null, but only if the control is empty. * If the control is not itself focused, this property will still * reference the item that would receive the keyboard focus if the control * itself were focused. */ private ReadOnlyObjectWrapper focusedItem = new ReadOnlyObjectWrapper(this, "focusedItem"); public final ReadOnlyObjectProperty focusedItemProperty() { return focusedItem.getReadOnlyProperty(); } public final T getFocusedItem() { return focusedItemProperty().get(); } final void setFocusedItem(T value) { focusedItem.set(value); } /*********************************************************************** * * * Public Focus API * * * **********************************************************************/ /** * Returns the number of items in the data model that underpins the control. * An example would be that a ListView focus model would likely return * listView.getItems().size(). The valid range of focusable * indices is between 0 and whatever is returned by this method. */ protected abstract int getItemCount(); /** * Returns the item at the given index. An example using ListView would be * listView.getItems().get(index). * * @param index The index of the item that is requested from the underlying * data model. * @return Returns null if the index is out of bounds, or an element of type * T that is related to the given index. */ protected abstract T getModelItem(int index); /** *

Convenience method to inform if the given index is currently focused * in this SelectionModel. Is functionally equivalent to calling *

getFocusedIndex() == index
. * * @param index The index to check as to whether it is currently focused * or not. * @return True if the given index is focused, false otherwise. */ public boolean isFocused(int index) { if (index < 0 || index >= getItemCount()) return false; return getFocusedIndex() == index; } /** * Causes the item at the given index to receive the focus. This does not * cause the current selection to change. Updates the focusedItem and * focusedIndex properties such that focusedIndex = -1 unless * 0 <= index < model size. * * @param index The index of the item to get focus. */ public void focus(int index) { if (index < 0 || index >= getItemCount()) { setFocusedIndex(-1); } else { int oldFocusIndex = getFocusedIndex(); setFocusedIndex(index); if (oldFocusIndex == index) { // manually update the focus item to ensure consistency setFocusedItem(getModelItem(index)); } } } /** * Attempts to give focus to the row previous to the currently focused row. * If the current focus owner is the first row, or is -1 (representing that * there is no current focus owner), calling this method will have no result. */ public void focusPrevious() { if (getFocusedIndex() == -1) { focus(0); } else if (getFocusedIndex() > 0) { focus(getFocusedIndex() - 1); } } /** * Attempts to give focus to the row after to the currently focused row. * If the current focus owner is the last row, calling this method will have * no result. */ public void focusNext() { if (getFocusedIndex() == -1) { focus(0); } else if (getFocusedIndex() != getItemCount() -1) { focus(getFocusedIndex() + 1); } } }