I would like to disable the default animation when I create new Tab.
Tab tabA = new Tab();
tabA.setText("Tab A");
tabPane.getTabs().add(tabA);
Is this possible?
Now, when Java 8 is finally out, one has the possibility to disable the animation, using CSS:
tabPane.setStyle("-fx-open-tab-animation: NONE; -fx-close-tab-animation: NONE;");
The default setting is "GROW".
Not easily. The animation logic is part of the TabPaneSkin:
From TabPane.java:
#Override protected Skin<?> createDefaultSkin() {
return new TabPaneSkin(this);
}
But as far as I know, there is no way to make small adjustments to the default skin (which is hidden in the com.sun.javafx.scene.control.skin package) but you'd have to implement a whole new skin.
Related
I am writing a small chat application in Kotlin with TornadoFX that works so far.
I am currently trying to make it more visually appealing when receiving new messages.
The messages are in a TableView (sender - message) but scrolling to new messages isn't smooth like I would like.
The snippet where I need help is relatively short:
addEventHandler(ScrollToEvent.ANY) {
it.consume()
timeline {
val keyValue = KeyValue(/* property to change */, /* target value */, Interpolator.EASE_OUT)
keyframe(0.25.seconds) {
this.plusAssign(keyValue)
}
}
}
In general I need help figuring out which property to change and what the target should be in this line:
KeyValue(/* property to change */, /* target value */, Interpolator.EASE_OUT)
Ok, I found the solution.
One needs to lookup the ScrollBar the TableView provides, once enough rows are present (and when scrolling actually does anything).
From TornadoFX JavaFX Sync Scroll across tableviews, I adapted the lookup and came up with this, working, code:
addEventHandler(ScrollToEvent.ANY) {
it.consume()
timeline {
val scrollBar = lookupAll(".scroll-bar").first() as ScrollBar
val keyValue = KeyValue(scrollBar.valueProperty(), scrollBar.max, Interpolator.EASE_OUT)
keyframe(0.5.seconds) {
this.plusAssign(keyValue)
}
}
}
I am using a SuggestBox in GWT.I also inherit the Standard theme from SuggestionBox.gwt.xml as
<inherits name='com.google.gwt.user.theme.standard.Standard'/>
so this are using default standard css for widget Suggestbox and it is making border through image as hborder.png,vborder.png etc..I want to remove this but my css is not working.
.gwt-SuggestBoxPopup{
border : 1px solid #000000;
}
so how can i solve this issue.Please help me.
Thanks Rahul
The class used for the popup is a DefaultSuggestionDisplay for default SuggestBox. It uses a DecoratedPopupPanel as you can see in SuggestBox.java around line 392.
To avoid "heavy" border, you have to create/override a SuggestionDisplay that uses a non-decorated popupPanel and pass it to your SuggestBox trough constructor
public SuggestBox(SuggestOracle oracle, TextBoxBase box,SuggestionDisplay suggestDisplay);
Say, "border" is not sufficient, because DecoratedPopupPanel uses multiple cells to set borders, as you seen in the CSS. So you probably can update CSS directly but it will apply to all project, as SuggestBox does not seems to handle resource bundle directly.
Create a customSuggestionDisplay class
public static class CustomSuggestionDisplay extends SuggestBox.DefaultSuggestionDisplay {
private PopupPanel suggestionPopupRef;
public CustomSuggestionDisplay() {
suggestionPopupRef = getPopupPanel();
}
public void removeBorder() {
((Element)suggestionPopupRef.getElement().getChild(0)).getStyle().setBackgroundColor("white");
NodeList<com.google.gwt.dom.client.Element> tdList = suggestionPopupRef.getElement().getElementsByTagName("td");
for (int tdIndex = 0; tdIndex < tdList.getLength(); ++tdIndex) {
Element tdElement = (Element) tdList.getItem(tdIndex);
if (tdElement.getClassName().startsWith("suggestPopup"))
tdElement.removeClassName(tdElement.getClassName());
}
}
}
Create a suggestBox object
SuggestOracle oracle = new RestSuggestOracle();
CustomSuggestionDisplay suggestionDisplay = new CustomSuggestionDisplay();
TextBox textfield = new TextBox();
SuggestBox m_field = new SuggestBox(oracle, textfield, suggestionDisplay);
Call removeBorder when the suggestion is displaying
if (m_field.isSuggestionListShowing())
suggestionDisplay.removeBorder();
I have the following (pseudo) code
root = _iface.createRoot(...)
Label l = new Label("hello world");
anim = Animator.create();
anim.delay(1500).then().add(root.layer, l.layer);
anim.delay(1000).then().action(new Runnable() {
public void run() {
// root.add(l);
System.out.println("it works");
}
});
the it work's line gets printed ok, so I assume I'm updating the animation right, but the label is never added to the scene!
If I uncomment the root.add(l) inside the Runnable it works as expected (the label is added after 1 second), but it doesn't get added with anim.delay(1500).then().add(root.layer, l.layer);
any idea whay I'm doing wrong?
You can't just add the layer of a TPUI Widget to another layer and expect the Widget to render properly. A widget must be added to its parent via Group.add.
The animation code you are using is more designed for animating raw PlayN layer's than UI elements. UI elements are generally laid out using a LayoutManager which controls where the layer is positioned. If you tried to animate the layer directly, you would confuse the layout manager and generally mess everything up.
That said, it's pretty safe to animate the Root of the interface, because that anchors a whole UI into the PlayN scene graph.
If you really want to try what you're doing above, don't use Animator.add use:
action(new Runnable() {
root.add(l);
});
(like you have above) which properly adds the Label to the Root, and triggers validation and rendering of the Label.
i want to add UIComponent inside a spite. here is the code:
private function make() : void {
var circle : Sprite = new Sprite();
circle.graphics.beginFill(0xFF0000, 0.2);
circle.graphics.drawCircle(0, 0, 20);
var button : Button = new Button();
button.label = "testing...";
var wrapper : UIComponent = new UIComponent();
circle.addChild( button );
wrapper.addChild( circle );
addChild( wrapper );
}
the problem is that button is added, but is not displayed. if i do reversed - add sprite to uicomponent - everything works fine, but this way it doesn't work. i tried to use invalidate functions for button etc... even tried making "circle" as UIMovieClip, but no luck - button is still invisible. also if i simply do "addChild( button );" - it is shown, what the... please help, what i am doing wrong? how can i add a button inside a sprite?
Short answer, you can't. What you CAN do is instead of using Sprite, you use UIComponent for your circle.
The reason for this is that UIComponent has A LOT of code that changes how it behaves, including how to add and layout children. You could essentially take the same code to a Sprite since UIComponent does extend it, however that would be VERY redundant. This works great for me:
private function make() : void {
var circle : UIComponent= new UIComponent();
circle.graphics.beginFill(0xFF0000, 0.2);
circle.graphics.drawCircle(0, 0, 20);
var button : Button = new Button();
button.label = "testing...";
var wrapper : UIComponent = new UIComponent();
circle.addChild( button );
wrapper.addChild( circle );
addChild( wrapper );
}
Unfortunately, in order to use Sprite the way you are trying to do it, you would have to extend Sprite and implement IUIComponent.
Taken from the Flex 3 Language Reference:
Note: While the child argument to the
method is specified as of type
DisplayObject, the argument must
implement the IUIComponent interface
to be added as a child of a container.
All Flex components implement this
interface.
Sprite does not implement IUIComponent, so you are experiencing a pretty typical issue. UIComponent's don't typically have speed issues when compared to Sprites, so I would recommend just drawing on your UIComponent.
As stated before, you /could/ extend Sprite to implement IUIComponent, but it's a pain.
Hope this helps!
I embed SVG graphics in my Flex application using
package MyUI
{
public class Assets
{
[Embed(source="/assets/pic.svg"]
[Bindable]
public static var svgPic:Class;
}
}
and then extending the Tree class with some of my own code, setting the icon upon adding a node to the data provider:
public class MyTree extends Tree
{
public function MyTree()
{
// ...
this.iconField = "svgIcon";
// ...
this.dataProvider = new ArrayCollection;
this.dataProvider.addItem({ /* ... */ svgIcon: MyUI.Assets.svgPic /* ... */ });
// ...
}
}
Now I have two things I want to do:
use the SVG graphics in multiple places in the app, scaling them to the appropriate size for each appearance, i. e. scale them to a proper icon size when using them in the tree
change the size of the icon at runtime, e. g. display a slightly larger icon for selected items or let an icon "pulse" as a response to some event
I read the Flex documentation on the 9-slice scaling properties in the Embed tag, but I think that's not what I want.
Edit:
I unsuccessfully checked the "similar questions" suggested by SO, among others this one:
Flex: Modify an embedded icon and use it in a button?
Subclass mx.controls.treeClasses.TreeItemRenderer and make it resize the icon to your desired dimensions, or create your own item renderer implementation by using the same interfaces as TreeItemRenderer. Set a custom item renderer with the itemRenderer property:
exampleTree.itemRenderer = new ClassFactory( ExampleCustomItemRendererClass );
The answer to this question might point you in the right direction, without knowing more about the trouble you're having:
Flex: Modify an embedded icon and use it in a button?
Hope it helps!