Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.control; 027 028import javafx.beans.InvalidationListener; 029import javafx.beans.Observable; 030import javafx.beans.property.ReadOnlyIntegerProperty; 031import javafx.beans.property.ReadOnlyIntegerWrapper; 032import javafx.beans.property.ReadOnlyObjectProperty; 033import javafx.beans.property.ReadOnlyObjectWrapper; 034 035/** 036 * The abstract base class for FocusModel implementations. 037 */ 038public abstract class FocusModel<T> { 039 040 /*********************************************************************** 041 * * 042 * Constructors * 043 * * 044 **********************************************************************/ 045 046 /** 047 * Creates a default FocusModel instance. 048 */ 049 public FocusModel() { 050 focusedIndexProperty().addListener(new InvalidationListener() { 051 @Override public void invalidated(Observable valueModel) { 052 // we used to lazily retrieve the focused item, but now we just 053 // do it when the focused index changes. 054 setFocusedItem(getModelItem(getFocusedIndex())); 055 } 056 }); 057 } 058 059 060 061 /*************************************************************************** 062 * * 063 * Focus Properties * 064 * * 065 **************************************************************************/ 066 067 /** 068 * The index of the current item in the FocusModel which has the focus. It 069 * is possible that this will be -1, but only if the control is empty. 070 * If the control is not itself focused, this property will still 071 * reference the row index that would receive the keyboard focus if the control 072 * itself were focused. 073 */ 074 private ReadOnlyIntegerWrapper focusedIndex = new ReadOnlyIntegerWrapper(this, "focusedIndex", -1); 075 public final ReadOnlyIntegerProperty focusedIndexProperty() { return focusedIndex.getReadOnlyProperty(); } 076 public final int getFocusedIndex() { return focusedIndex.get(); } 077 final void setFocusedIndex(int value) { focusedIndex.set(value); } 078 079 080 081 /** 082 * The current item in the FocusModel which has the focus. It 083 * is possible that this will be null, but only if the control is empty. 084 * If the control is not itself focused, this property will still 085 * reference the item that would receive the keyboard focus if the control 086 * itself were focused. 087 */ 088 private ReadOnlyObjectWrapper<T> focusedItem = new ReadOnlyObjectWrapper<T>(this, "focusedItem"); 089 public final ReadOnlyObjectProperty<T> focusedItemProperty() { return focusedItem.getReadOnlyProperty(); } 090 public final T getFocusedItem() { return focusedItemProperty().get(); } 091 final void setFocusedItem(T value) { focusedItem.set(value); } 092 093 094 095 /*********************************************************************** 096 * * 097 * Public Focus API * 098 * * 099 **********************************************************************/ 100 101 102 /** 103 * Returns the number of items in the data model that underpins the control. 104 * An example would be that a ListView focus model would likely return 105 * <code>listView.getItems().size()</code>. The valid range of focusable 106 * indices is between 0 and whatever is returned by this method. 107 */ 108 protected abstract int getItemCount(); 109 110 /** 111 * Returns the item at the given index. An example using ListView would be 112 * <code>listView.getItems().get(index)</code>. 113 * 114 * @param index The index of the item that is requested from the underlying 115 * data model. 116 * @return Returns null if the index is out of bounds, or an element of type 117 * T that is related to the given index. 118 */ 119 protected abstract T getModelItem(int index); 120 121 /** 122 * <p>Convenience method to inform if the given index is currently focused 123 * in this SelectionModel. Is functionally equivalent to calling 124 * <pre><code>getFocusedIndex() == index</code></pre>. 125 * 126 * @param index The index to check as to whether it is currently focused 127 * or not. 128 * @return True if the given index is focused, false otherwise. 129 */ 130 public boolean isFocused(int index) { 131 if (index < 0 || index >= getItemCount()) return false; 132 133 return getFocusedIndex() == index; 134 } 135 136 /** 137 * Causes the item at the given index to receive the focus. This does not 138 * cause the current selection to change. Updates the focusedItem and 139 * focusedIndex properties such that <code>focusedIndex = -1</code> unless 140 * <code>0 <= index < model size</code>. 141 * 142 * @param index The index of the item to get focus. 143 */ 144 public void focus(int index) { 145 if (index < 0 || index >= getItemCount()) { 146 setFocusedIndex(-1); 147 } else { 148 setFocusedIndex(index); 149 } 150 } 151 152 /** 153 * Attempts to give focus to the row previous to the currently focused row. 154 * If the current focus owner is the first row, or is -1 (representing that 155 * there is no current focus owner), calling this method will have no result. 156 */ 157 public void focusPrevious() { 158 if (getFocusedIndex() == -1) { 159 focus(0); 160 } else if (getFocusedIndex() > 0) { 161 focus(getFocusedIndex() - 1); 162 } 163 } 164 165 /** 166 * Attempts to give focus to the row after to the currently focused row. 167 * If the current focus owner is the last row, calling this method will have 168 * no result. 169 */ 170 public void focusNext() { 171 if (getFocusedIndex() == -1) { 172 focus(0); 173 } else if (getFocusedIndex() != getItemCount() -1) { 174 focus(getFocusedIndex() + 1); 175 } 176 } 177}