diff --git a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TabPaneBehavior.java b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TabPaneBehavior.java --- a/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TabPaneBehavior.java +++ b/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TabPaneBehavior.java @@ -29,8 +29,9 @@ import javafx.collections.ObservableList; import javafx.event.Event; +import javafx.scene.Node; import javafx.scene.Parent; -import javafx.scene.Node; +import javafx.scene.control.SingleSelectionModel; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.input.KeyCode; @@ -38,7 +39,6 @@ import com.sun.javafx.scene.control.skin.TabPaneSkin; import com.sun.javafx.scene.traversal.Direction; -import javafx.scene.control.SingleSelectionModel; public class TabPaneBehavior extends BehaviorBase { @@ -270,7 +270,6 @@ return firstPopulatedEngine; } - /*************************************************************************** * * * Mouse event handling * @@ -295,6 +294,12 @@ getControl().getSelectionModel().select(tab); } + public boolean canCloseTab(Tab tab) { + Event event = new Event(tab,tab,Tab.TAB_CLOSE_REQUEST); + Event.fireEvent(tab, event); + return ! event.isConsumed(); + } + public void closeTab(Tab tab) { TabPane tabPane = getControl(); // only switch to another tab if the selected tab is the one we're closing diff --git a/javafx-ui-controls/src/javafx/scene/control/Tab.java b/javafx-ui-controls/src/javafx/scene/control/Tab.java --- a/javafx-ui-controls/src/javafx/scene/control/Tab.java +++ b/javafx-ui-controls/src/javafx/scene/control/Tab.java @@ -24,17 +24,26 @@ */ package javafx.scene.control; -import com.sun.javafx.css.Styleable; -import com.sun.javafx.css.StyleableProperty; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +import javafx.beans.DefaultProperty; import javafx.beans.property.BooleanProperty; +import javafx.beans.property.BooleanPropertyBase; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectPropertyBase; +import javafx.beans.property.ReadOnlyBooleanProperty; +import javafx.beans.property.ReadOnlyBooleanWrapper; +import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; +import javafx.collections.ObservableMap; import javafx.event.Event; import javafx.event.EventDispatchChain; import javafx.event.EventHandler; @@ -42,13 +51,9 @@ import javafx.event.EventType; import javafx.scene.Node; +import com.sun.javafx.css.Styleable; +import com.sun.javafx.css.StyleableProperty; import com.sun.javafx.event.EventHandlerManager; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import javafx.beans.DefaultProperty; -import javafx.beans.property.*; -import javafx.collections.ObservableMap; /** *

Tabs are placed within a {@link TabPane}, where each tab represents a single @@ -587,11 +592,52 @@ } return disabled; } - + private void updateDisabled() { setDisabled(isDisable() || (getTabPane() != null && getTabPane().isDisabled())); } + public static final EventType TAB_CLOSE_REQUEST = new EventType (Event.ANY, "TAB_CLOSE_REQUEST"); + + private ObjectProperty> onCloseRequest; + public final ObjectProperty> onCloseRequestProperty() { + if( onCloseRequest == null ) { + onCloseRequest = new ObjectPropertyBase>() { + @Override protected void invalidated() { + setEventHandler(TAB_CLOSE_REQUEST, get()); + } + + @Override + public Object getBean() { + return Tab.this; + } + + @Override + public String getName() { + return "onCloseRequest"; + } + }; + } + return onCloseRequest; + } + + /** + * Called when there is an external request to close this {@code Tab}. + * The installed event handler can prevent tab closing by consuming the + * received event. + */ + public EventHandler getOnCloseRequest() { + if( onCloseRequest == null ) { + return null; + } + return onCloseRequest.get(); + } + + public void setOnCloseRequest(EventHandler value) { + onCloseRequestProperty().set(value); + } + + // --- Properties private static final Object USER_DATA_KEY = new Object();