Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

how to add custom skin for textField in javafx using css?

b12b1ae3-a0ac-4103-8233-83e8a67c5408Feb 6 2015 — edited Feb 6 2015

I am trying to add a default skin to text Field using css but its not working as i expect it to.

I expect a right button in text Field like one's in Metro theme of Win8.

Here is fxml i am using


<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane prefHeight="300.0" prefWidth="400.0" stylesheets="@custom.css"  xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
  
<children>
  
<TextField layoutX="126.0" layoutY="138.0" />
  
</children>
</AnchorPane>


Here is css :

.text-field{ -fx-skin: "application.MetroTextFieldSkin"; }

And here are 2 skin classes i am using :

first one :

package application;

import com.sun.javafx.scene.control.skin.TextFieldSkin;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;

/**
* Created by pedro_000 on 12/5/13.
*/

public class MetroTextFieldSkin extends TextFieldWithButtonSkin{
  
public MetroTextFieldSkin(TextField textField) {
  
super(textField);
  
}

  
protected void rightButtonPressed()
  
{
  getSkinnable
().setText("");
  
}

}

2nd one :

package application;

import com.sun.javafx.scene.control.behavior.TextFieldBehavior;
import com.sun.javafx.scene.control.skin.TextFieldSkin;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.control.Skin;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;


public class TextFieldWithButtonSkin extends TextFieldSkin{
  
private StackPane rightButton;
  
private Region rightButtonGraphic;

  
protected TextField textField;

  
public TextFieldWithButtonSkin(TextField textField) {
  
super(textField);

  
this.textField = textField;

  rightButton
= new StackPane();
  rightButton
.getStyleClass().setAll("right-button");
  rightButton
.setFocusTraversable(false);

  rightButtonGraphic
= new Region();
  rightButtonGraphic
.getStyleClass().setAll("right-button-graphic");
  rightButtonGraphic
.setFocusTraversable(false);

  rightButtonGraphic
.setMaxWidth(Region.USE_PREF_SIZE);
  rightButtonGraphic
.setMaxHeight(Region.USE_PREF_SIZE);

  rightButton
.setVisible(false);
  rightButtonGraphic
.setVisible(false);

  rightButton
.getChildren().add(rightButtonGraphic);
  getChildren
().add(rightButton);

  setupListeners
();
  
}

  
private void setupListeners() {

  
final TextField textField = getSkinnable();
  rightButton
.setOnMousePressed(new EventHandler<MouseEvent>() {
  
@Override
  
public void handle(MouseEvent event) {
  rightButtonPressed
();
  
}
  
});
  rightButton
.setOnMouseReleased(new EventHandler<MouseEvent>() {
  
@Override
  
public void handle(MouseEvent event) {
  rightButtonReleased
();
  
}
  
});

  textField
.textProperty().addListener(new ChangeListener<String>() {
  
@Override
  
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
  textChanged
();
  
}
  
});
  textField
.focusedProperty().addListener(new ChangeListener<Boolean>() {
  
@Override
  
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
  focusChanged
();
  
}
  
});
  
}

  
protected void textChanged()
  
{
  
if (textField.getText() == null)
  
return;
  
System.out.println(textField.getText().isEmpty());
  rightButton
.setVisible(!textField.getText().isEmpty());
  rightButtonGraphic
.setVisible(!textField.getText().isEmpty());
  
}

  
protected void focusChanged()
  
{
  
if (textField.getText() == null)
  
return;

  rightButton
.setVisible(textField.isFocused() && !textField.getText().isEmpty());
  rightButtonGraphic
.setVisible(textField.isFocused() && !textField.getText().isEmpty());
  
}

  
@Override
  
protected void layoutChildren(double x, double y, double w, double h) {
  
super.layoutChildren(x, y, w, h);

  
final double clearGraphicWidth = snapSize(rightButtonGraphic.prefWidth(-1));
  
final double clearButtonWidth = rightButton.snappedLeftInset() + clearGraphicWidth + rightButton.snappedRightInset();

  rightButton
.resize(clearButtonWidth, h);
  positionInArea
(rightButton,
  
(x+w) - clearButtonWidth, y,
  clearButtonWidth
, h, 0, HPos.CENTER, VPos.CENTER);
  
}

  
protected void rightButtonPressed()
  
{
  
}

  
protected void rightButtonReleased()
  
{

  
}

}


Am i missing something which is necessary to make it work.

These are actualy created by pedro for his theme jMetro.

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 6 2015
Added on Feb 6 2015
0 comments
824 views