Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javafx.scene.control;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import com.sun.javafx.scene.control.Properties;
import com.sun.javafx.scene.control.behavior.ListCellBehavior;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.WeakInvalidationListener;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ObjectPropertyBase;
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
import javafx.css.StyleableDoubleProperty;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.geometry.Orientation;
import javafx.scene.layout.Region;
import javafx.util.Callback;
import javafx.css.StyleableObjectProperty;
import javafx.css.CssMetaData;
import javafx.css.converter.EnumConverter;
import javafx.collections.WeakListChangeListener;
import javafx.css.converter.SizeConverter;
import javafx.scene.control.skin.ListViewSkin;
import java.lang.ref.WeakReference;
import javafx.css.PseudoClass;
import javafx.beans.DefaultProperty;
import javafx.css.Styleable;
import javafx.css.StyleableProperty;
import javafx.scene.AccessibleAttribute;
import javafx.scene.AccessibleRole;
import javafx.scene.Node;
import javafx.util.Pair;
/**
* A ListView displays a horizontal or vertical list of items from which the
* user may select, or with which the user may interact. A ListView is able to
* have its generic type set to represent the type of data in the backing model.
* Doing this has the benefit of making various methods in the ListView, as well
* as the supporting classes (mentioned below), type-safe. In addition, making
* use of the generic type supports substantially simplified development of applications
* making use of ListView, as all modern IDEs are able to auto-complete far
* more successfully with the additional type information.
*
*
Populating a ListView
*
A simple example of how to create and populate a ListView of names (Strings)
* is shown here:
*
*
The elements of the ListView are contained within the
* {@link #itemsProperty() items} {@link ObservableList}. This
* ObservableList is automatically observed by the ListView, such that any
* changes that occur inside the ObservableList will be automatically shown in
* the ListView itself. If passing the ObservableList in to the
* ListView constructor is not feasible, the recommended approach for setting
* the items is to simply call:
*
*
The end result of this is, as noted above, that the ListView will automatically
* refresh the view to represent the items in the list.
*
*
Another approach, whilst accepted by the ListView, is not the
* recommended approach:
*
*
{@code List content = ...
* getItems().setAll(content);}
*
* The issue with the approach shown above is that the content list is being
* copied into the items list - meaning that subsequent changes to the content
* list are not observed, and will not be reflected visually within the ListView.
*
*
ListView Selection / Focus APIs
*
To track selection and focus, it is necessary to become familiar with the
* {@link SelectionModel} and {@link FocusModel} classes. A ListView has at most
* one instance of each of these classes, available from
* {@link #selectionModelProperty() selectionModel} and
* {@link #focusModelProperty() focusModel} properties respectively.
* Whilst it is possible to use this API to set a new selection model, in
* most circumstances this is not necessary - the default selection and focus
* models should work in most circumstances.
*
*
The default {@link SelectionModel} used when instantiating a ListView is
* an implementation of the {@link MultipleSelectionModel} abstract class.
* However, as noted in the API documentation for
* the {@link MultipleSelectionModel#selectionModeProperty() selectionMode}
* property, the default value is {@link SelectionMode#SINGLE}. To enable
* multiple selection in a default ListView instance, it is therefore necessary
* to do the following:
*
*
The visuals of the ListView can be entirely customized by replacing the
* default {@link #cellFactoryProperty() cell factory}. A cell factory is used to
* generate {@link ListCell} instances, which are used to represent an item in the
* ListView. See the {@link Cell} class documentation for a more complete
* description of how to write custom Cells.
*
*
Warning: Nodes should not be inserted directly into the items list
* {@code ListView} allows for the items list to contain elements of any type, including
* {@link Node} instances. Putting nodes into
* the items list is strongly discouraged, as it can
* lead to unexpected results.
*
Important points to note:
*
*
Avoid inserting {@code Node} instances directly into the items list or its data model.
*
The recommended approach is to put the relevant information into the items list, and
* provide a custom {@link #cellFactoryProperty() cell factory} to create the nodes for a
* given cell and update them on demand using the data stored in the item for that cell.
*
Avoid creating new {@code Node}s in the {@code updateItem} method of a custom {@link #cellFactoryProperty() cell factory}.
*
*
The following minimal example shows how to create a custom cell factory for {@code ListView} containing {@code Node}s:
*
*
This example has an anonymous custom {@code ListCell} class in the custom cell factory.
* Note that the {@code Rectangle} ({@code Node}) object needs to be created in the instance initialization block
* or the constructor of the custom {@code ListCell} class and updated/used in its {@code updateItem} method.
*
*
Editing
*
This control supports inline editing of values, and this section attempts to
* give an overview of the available APIs and how you should use them.
*
*
Firstly, cell editing most commonly requires a different user interface
* than when a cell is not being edited. This is the responsibility of the
* {@link Cell} implementation being used. For ListView, this is the responsibility
* of the {@link #cellFactoryProperty() cell factory}. It is your choice whether the cell is
* permanently in an editing state (e.g. this is common for {@link CheckBox} cells),
* or to switch to a different UI when editing begins (e.g. when a double-click
* is received on a cell).
*
*
To know when editing has been requested on a cell,
* simply override the {@link javafx.scene.control.Cell#startEdit()} method, and
* update the cell {@link javafx.scene.control.Cell#textProperty() text} and
* {@link javafx.scene.control.Cell#graphicProperty() graphic} properties as
* appropriate (e.g. set the text to null and set the graphic to be a
* {@link TextField}). Additionally, you should also override
* {@link Cell#cancelEdit()} to reset the UI back to its original visual state
* when the editing concludes. In both cases it is important that you also
* ensure that you call the super method to have the cell perform all duties it
* must do to enter or exit its editing mode.
*
*
Once your cell is in an editing state, the next thing you are most probably
* interested in is how to commit or cancel the editing that is taking place. This is your
* responsibility as the cell factory provider. Your cell implementation will know
* when the editing is over, based on the user input (e.g. when the user presses
* the Enter or ESC keys on their keyboard). When this happens, it is your
* responsibility to call {@link Cell#commitEdit(Object)} or
* {@link Cell#cancelEdit()}, as appropriate.
*
*
When you call {@link Cell#commitEdit(Object)} an event is fired to the
* ListView, which you can observe by adding an {@link EventHandler} via
* {@link ListView#setOnEditCommit(javafx.event.EventHandler)}. Similarly,
* you can also observe edit events for
* {@link ListView#setOnEditStart(javafx.event.EventHandler) edit start}
* and {@link ListView#setOnEditCancel(javafx.event.EventHandler) edit cancel}.
*
*
By default the ListView edit commit handler is non-null, with a default
* handler that attempts to overwrite the property value for the
* item in the currently-being-edited row. It is able to do this as the
* {@link Cell#commitEdit(Object)} method is passed in the new value, and this
* is passed along to the edit commit handler via the
* {@link EditEvent} that is fired. It is simply a matter of calling
* {@link EditEvent#getNewValue()} to retrieve this value.
*
*
It is very important to note that if you call
* {@link ListView#setOnEditCommit(javafx.event.EventHandler)} with your own
* {@link EventHandler}, then you will be removing the default handler. Unless
* you then handle the writeback to the property (or the relevant data source),
* nothing will happen. You can work around this by using the
* {@link ListView#addEventHandler(javafx.event.EventType, javafx.event.EventHandler)}
* method to add a {@link ListView#editCommitEvent()} {@link EventType} with
* your desired {@link EventHandler} as the second argument. Using this method,
* you will not replace the default implementation, but you will be notified when
* an edit commit has occurred.
*
*
Hopefully this summary answers some of the commonly asked questions.
* Fortunately, JavaFX ships with a number of pre-built cell factories that
* handle all the editing requirements on your behalf. You can find these
* pre-built cell factories in the javafx.scene.control.cell package.
*
* @see ListCell
* @see MultipleSelectionModel
* @see FocusModel
* @param This type is used to represent the type of the objects stored in
* the ListViews {@link #itemsProperty() items} ObservableList. It is
* also used in the {@link #selectionModelProperty() selection model}
* and {@link #focusModelProperty() focus model}.
* @since JavaFX 2.0
*/
// TODO add code examples
@DefaultProperty("items")
public class ListView extends Control {
/* *************************************************************************
* *
* Static properties and methods *
* *
**************************************************************************/
/**
* An EventType that indicates some edit event has occurred. It is the parent
* type of all other edit events: {@link #editStartEvent()},
* {@link #editCommitEvent()} and {@link #editCancelEvent()}.
* @param the type of the objects stored in this ListView
* @return the event type
*/
@SuppressWarnings("unchecked")
public static EventType> editAnyEvent() {
return (EventType>) EDIT_ANY_EVENT;
}
private static final EventType> EDIT_ANY_EVENT =
new EventType<>(Event.ANY, "LIST_VIEW_EDIT");
/**
* An EventType used to indicate that an edit event has started within the
* ListView upon which the event was fired.
* @param the type of the objects stored in this ListView
* @return the event type
*/
@SuppressWarnings("unchecked")
public static EventType> editStartEvent() {
return (EventType>) EDIT_START_EVENT;
}
private static final EventType> EDIT_START_EVENT =
new EventType<>(editAnyEvent(), "EDIT_START");
/**
* An EventType used to indicate that an edit event has just been canceled
* within the ListView upon which the event was fired.
* @param the type of the objects stored in this ListView
* @return the event type
*/
@SuppressWarnings("unchecked")
public static EventType> editCancelEvent() {
return (EventType>) EDIT_CANCEL_EVENT;
}
private static final EventType> EDIT_CANCEL_EVENT =
new EventType<>(editAnyEvent(), "EDIT_CANCEL");
/**
* An EventType used to indicate that an edit event has been committed
* within the ListView upon which the event was fired.
* @param the type of the objects stored in this ListView
* @return the event type
*/
@SuppressWarnings("unchecked")
public static EventType> editCommitEvent() {
return (EventType>) EDIT_COMMIT_EVENT;
}
private static final EventType> EDIT_COMMIT_EVENT =
new EventType<>(editAnyEvent(), "EDIT_COMMIT");
/* *************************************************************************
* *
* Fields *
* *
**************************************************************************/
// by default we always select the first row in the ListView, and when the
// items list changes, we also reselect the first row. In some cases, such as
// for the ComboBox, this is not desirable, so it can be disabled here.
private boolean selectFirstRowByDefault = true;
/* *************************************************************************
* *
* Constructors *
* *
**************************************************************************/
/**
* Creates a default ListView which will display contents stacked vertically.
* As no {@link ObservableList} is provided in this constructor, an empty
* ObservableList is created, meaning that it is legal to directly call
* {@link #getItems()} if so desired. However, as noted elsewhere, this
* is not the recommended approach
* (instead call {@link #setItems(javafx.collections.ObservableList)}).
*
*
Refer to the {@link ListView} class documentation for details on the
* default state of other properties.
*/
public ListView() {
this(FXCollections.observableArrayList());
}
/**
* Creates a default ListView which will stack the contents retrieved from the
* provided {@link ObservableList} vertically.
*
*
Attempts to add a listener to the {@link ObservableList}, such that all
* subsequent changes inside the list will be shown to the user.
*
*
Refer to the {@link ListView} class documentation for details on the
* default state of other properties.
* @param items the list of items
*/
public ListView(ObservableList items) {
getStyleClass().setAll(DEFAULT_STYLE_CLASS);
setAccessibleRole(AccessibleRole.LIST_VIEW);
setItems(items);
// Install default....
// ...selection model
setSelectionModel(new ListView.ListViewBitSetSelectionModel<>(this));
// ...focus model
setFocusModel(new ListView.ListViewFocusModel<>(this));
// ...edit commit handler
setOnEditCommit(DEFAULT_EDIT_COMMIT_HANDLER);
// Fix for RT-36651, which was introduced by RT-35679 (above) and resolved
// by having special-case code to remove the listener when requested.
// This is done by ComboBoxListViewSkin, so that selection is not done
// when a ComboBox is shown.
getProperties().addListener((MapChangeListener