I want to draw red borders around arbitrary javafx.scene.text.Text nodes in my JavaFX scenegraph, for example those in a Button object.
It is easy to retrieve all the Text nodes but not to find where they are in the scene, they have an x and y property which doesn't seem to get set properly but they do not have a width and height.
So far I have tried to add rectangles with a red stroke to a stack pane but the x and y are always wrong and I can't get the size.
One solution is to wrap the text nodes in layout pane (such as an HBox) and use CSS on the layout pane:
import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class TextBorderExample extends Application {
#Override
public void start(Stage primaryStage) {
final HBox root = new HBox(5);
root.getChildren().addAll(
new Text("This"), new Text("Is"), new Text("A"), createBorderedText("Red"), new Text("Bordered"), new Text("Text")
);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
private Node createBorderedText(String text) {
final HBox hbox = new HBox();
hbox.getChildren().add(new Text(text));
hbox.setStyle("-fx-border-color: red;");
return hbox ;
}
public static void main(String[] args) {
launch(args);
}
}
Another way is to use a Rectangle, as follows:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class TextBorderExample extends Application {
#Override
public void start(Stage primaryStage) {
final HBox root = new HBox(5);
final Text red = new Text("Red");
final Rectangle redBorder = new Rectangle(0, 0, Color.TRANSPARENT);
redBorder.setStroke(Color.RED);
redBorder.setManaged(false);
red.boundsInParentProperty().addListener(new ChangeListener<Bounds>() {
#Override
public void changed(ObservableValue<? extends Bounds> observable,
Bounds oldValue, Bounds newValue) {
redBorder.setLayoutX(red.getBoundsInParent().getMinX());
redBorder.setLayoutY(red.getBoundsInParent().getMinY());
redBorder.setWidth(red.getBoundsInParent().getWidth());
redBorder.setHeight(red.getBoundsInParent().getHeight());
}
});
root.getChildren().addAll(new Text("This"), new Text("Is"), new Text("A"), red, new Text("Bordered"), new Text("Text"));
root.getChildren().add(redBorder);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Related
i am using javafx and working on a application CRUD. i nedd data in a combobox and when i select any of the data from one combobox the related data should be display on another combobox. the data source is mysql.
This is just a simple example you need to add data form mysql to combo box see this ? code post a comment if any ?s.
Example
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Table extends Application {
private Stage primaryStage;
private AnchorPane pane;
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
VBox v = new VBox(10);
ComboBox<String> c = new ComboBox<String>();
ComboBox<String> c1 = new ComboBox<String>();
ObservableList<String> sList = FXCollections.observableArrayList();
sList.addAll("b", "c", "dd", "dcd", "dddf");
c.setItems(sList);
c1.setItems(sList);
// c1.valueProperty().bind(c.valueProperty());
c1.valueProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
c.setValue(newValue);
}
});
v.getChildren().addAll(c, c1);
Scene Scene = new Scene(v);
primaryStage.setScene(Scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I did a try with effect of the framework, but it has some weird behaviour when I blur a textfield into a Parent, the textfield is positioned at a different place, please take a look :
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextField;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class BlurTest extends Application {
CTextView subPane = new CTextView(100,100);
#Override
public void start(Stage stage) throws Exception {
VBox myBox = new VBox();
CheckBox chkBlur = new CheckBox("Show");
chkBlur.selectedProperty().addListener(new ChangeListener<Boolean>(){
#Override
public void changed(ObservableValue<? extends Boolean> v,
Boolean oldValue, Boolean newValue) {
if(oldValue)
subPane.getTxt().setEffect(new GaussianBlur());
else
subPane.getTxt().setEffect(null);
}
});
myBox.getChildren().addAll(new TextField("Not blur"), subPane, new TextField("Not blur"), chkBlur);
myBox.setPrefSize(250, 500);
Scene scene = new Scene(myBox);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
And my custom textview :
import javafx.scene.Parent;
import javafx.scene.control.TextField;
public class CTextView extends Parent {
private TextField txt;
public CTextView(double w, double h) {
super();
this.txt = new TextField("Default");
this.txt.setLayoutX(20);
this.txt.setLayoutY(20);
this.getChildren().add(this.txt);
}
public TextField getTxt() {
return txt;
}
}
I don't understand why the textfield is repositioned in the Parent after blur effect.. :/
Thanks for your help
> Why is the textfield repositioned?
The GaussianBlur's default radius value is 10. When this effect applied to the node, that node's local bounds expands extra these blurring radii, but the node's width and height remains the same. The Parent does not apply CSS style and does not layout its children, however as seen in your example, it takes into account the local bounds and repositioned the node.
> Why do the textfield's setLayoutX and setLayoutY not worked?
The Parent does consider the local bounds of its child but it does not layout them according the child's layout values. Use a Region (or its subclasses) which takes care its children layout values.
public class CTextView extends Region {
private TextField txt;
public CTextView(double w, double h) {
super();
this.txt = new TextField("Default");
this.txt.setLayoutX(20);
this.txt.setLayoutY(20);
this.getChildren().add(this.txt);
}
public TextField getTxt() {
return txt;
}
}
I want to implement this example: http://docs.oracle.com/javafx/2/ui_controls/toggle-button.htm#
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class test extends Application
{
private void init(Stage primaryStage)
{
Group root = new Group();
primaryStage.setScene(new Scene(root));
String pillButtonCss = DX57DC.class.getResource("PillButton.css").toExternalForm();
// create 3 toggle buttons and a toogle group for them
ToggleButton tb1 = new ToggleButton("Left Button");
tb1.setId("pill-left");
ToggleButton tb2 = new ToggleButton("Center Button");
tb2.setId("pill-center");
ToggleButton tb3 = new ToggleButton("Right Button");
tb3.setId("pill-right");
final ToggleGroup group = new ToggleGroup();
tb1.setToggleGroup(group);
tb2.setToggleGroup(group);
tb3.setToggleGroup(group);
// select the first button to start with
group.selectToggle(tb1);
//////////////////////////////////////////
tb1.setUserData(Color.LIGHTGREEN);
tb2.setUserData(Color.LIGHTBLUE);
tb3.setUserData(Color.SALMON);
final Rectangle rect = new Rectangle(300, 300);
group.selectedToggleProperty().addListener(new ChangeListener<Toggle>()
{
#Override
public void changed(ObservableValue<? extends Toggle> ov,
Toggle toggle, Toggle new_toggle)
{
if (new_toggle == null)
{
rect.setFill(Color.WHITE);
}
else
{
rect.setFill(
(Color) group.getSelectedToggle().getUserData());
}
}
});
///////////////////////////////////////////
rect.setArcHeight(10);
rect.setArcWidth(10);
HBox hBox = new HBox();
hBox.getChildren().addAll(tb1, tb2, tb3);
hBox.setPadding(new Insets(20, 20, 260, 20));
hBox.getStylesheets().add(pillButtonCss);
VBox vbox = new VBox();
vbox.getChildren().add(hBox);
vbox.getChildren().add(rect);
root.getChildren().add(vbox);
}
#Override
public void start(Stage primaryStage) throws Exception
{
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
But for some reason I can see the buttons but the rectangle is not displayed when I try to switch the buttons. Can you help me to find where is my mistake? And also how I can implement this example with several rectangles holding different content?
You have to add rect to your scene graph :
root.getChildren().addAll(hBox, rect);
Also, think of using an appropriate layout for your root, BorderPane instead of Group for example.
Need to show an example in which you show and hide a window in JavaFX 2.
A stage is a window in javafx-2. It provide the hide and show methods:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class HideShowApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
final Stage window = new Stage();
window.setX(10);
Scene innerScene = new Scene(new Label("inner window"));
window.setScene(innerScene);
HBox root = new HBox(10d);
Button showButton = new Button("show");
showButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
window.show();
}
});
Button hideButton = new Button("hide");
hideButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
window.hide();
}
});
root.getChildren().add(showButton);
root.getChildren().add(hideButton);
stage.setScene(new Scene(root));
stage.show();
}
}
I want to create a borderpane what is transparent.I tried setting background color to transparent but it appears white. plz let me know if there is a way.
Code i tried.
BorderPane root=new BorderPane();
root.setStyle("-fx-background-color:transparent");
Scene scene=new Scene(root);
stage.setScene(scene);
stage.show();
Thank you...
Try setting the stage to transparent:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class TransparentStage extends Application {
#Override
public void start(Stage stage) {
// important line
stage.initStyle(StageStyle.TRANSPARENT);
Text text = new Text("Transparent!");
text.setFont(new Font(40));
VBox box = new VBox();
box.getChildren().add(text);
final Scene scene = new Scene(box,300, 250);
scene.setFill(null);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}