I want to add several TreeViews into TitlePana.
private static TitledPane pane = new TitledPane("Connections", null);
public static void initTree(String name)
{
pane.setContent(tree(name));
}
pane.setContent(<node>);
But when I add TreeView the new node always replaces the old one. Is this a design problem. Any idea is this a code problem?
Set the content of the titled pane to some layout pane, and then add the tree views to the layout pane.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TitledPane;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TreesInATitledPane extends Application {
#Override
public void start(Stage primaryStage) {
final TitledPane titledPane = new TitledPane();
titledPane.setText("Trees");
final VBox forest = new VBox(5);
final int NUM_TREES = 4 ;
for (int i=1; i<= NUM_TREES; i++) {
forest.getChildren().add(createRandomTree("Tree "+i));
}
titledPane.setContent(forest);
final BorderPane root = new BorderPane();
root.setTop(titledPane);
final Scene scene = new Scene(root, 300, 600);
primaryStage.setTitle("Can't see the forest for the trees");
primaryStage.setScene(scene);
primaryStage.show();
}
public TreeView<String> createRandomTree(String prefix) {
final Random rng = new Random();
List<TreeItem<String>> nodes = new ArrayList<>();
TreeItem<String> root = new TreeItem<>(prefix + " Root");
root.setExpanded(true);
nodes.add(root);
for (int i=1 ; i < 15; i++) {
final TreeItem<String> treeItem = new TreeItem<>(prefix + " Item "+i);
treeItem.setExpanded(true);
nodes.get(rng.nextInt(i)).getChildren().add(treeItem);
nodes.add(treeItem);
}
TreeView<String> tree = new TreeView<>(root);
return tree ;
}
public static void main(String[] args) {
launch(args);
}
}
Related
I have a TreeTableView control with several items. The user can move with the side scroll bar to any part of the table. How can I know which is the first item that the table shows? I mean, the first item we see. I have been going through the methods offered by this control and I have seen that scrollTo shows an item according to an order number that we specify but I have not found anything that is something like getFirstItemShown. I imagine that for a TableView control it should work the same, right? I'm using JavaFX 8.
Just for fun:
(note that if there are cut lines it can choose the next row, and the first row is sometimes hidden under the Column)
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableView;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Tree View Sample");
TreeItem<String> rootItem = new TreeItem<String> ("Inbox");
rootItem.setExpanded(true);
for (int i = 1; i < 888; i++) {
TreeItem<String> item = new TreeItem<String> ("Message" + i);
rootItem.getChildren().add(item);
}
TreeTableColumn<String, String> column = new TreeTableColumn<>("Column");
column.setPrefWidth(150);
column.setCellValueFactory((CellDataFeatures<String, String> p) -> new ReadOnlyStringWrapper(
p.getValue().getValue()));
TreeTableView<String> treeTableView = new TreeTableView<>(rootItem);
treeTableView.getColumns().add(column);
primaryStage.setScene(new Scene(treeTableView, 300, 250));
primaryStage.show();
Platform.runLater(()->{
ScrollBar verticalBar = (ScrollBar) treeTableView.lookup(".scroll-bar");
verticalBar.valueProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
int currentRow = 0;
if(newValue.doubleValue()<1){
currentRow =(int)((newValue.doubleValue()*treeTableView.getExpandedItemCount())-(newValue.doubleValue()*verticalBar.getVisibleAmount())*treeTableView.getExpandedItemCount());
}else {
currentRow =(int)(treeTableView.getExpandedItemCount()-verticalBar.getVisibleAmount()*treeTableView.getExpandedItemCount());
}
System.out.println(currentRow);
}
});
});
}
public static void main(String[] args) {
launch(args);
}
}
I want to create a button event to create a list. On this list, the Scrollbar
should be moved. But I become an error because the lookup method is only usable after rendering.
HBox root = new HBox();
Button b = new Button("initList");
b.setOnAction(e->
{
ListView<String> list = new ListView<String>();
for (int i = 0; i < 20; i++)
{
list.getItems().add(i+"");
}
ScrollBar bar = (ScrollBar) list.lookup(".scroll-bar");
bar.setValue(0.5);
root.getChildren().add(list);
});
root.getChildren().add(b);
Scene scene = new Scene(root,400,400);
primaryStage.setScene(scene);
primaryStage.show();
To ensure to be called after the layout, you can queue the task using runLater:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class LookupTest extends Application {
#Override
public void start(Stage primaryStage) {
HBox root = new HBox();
Button b = new Button("initList");
b.setOnAction(e ->
{
ListView<String> list = new ListView<String>();
for (int i = 0; i < 20; i++) {
list.getItems().add(i + "");
}
Platform.runLater(() -> {
ScrollBar bar = (ScrollBar) list.lookup(".scroll-bar");
if (bar != null) bar.setValue(0.5);
});
root.getChildren().add(list);
});
root.getChildren().add(b);
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Is there anyway I can do a for loop to create multiple textfields. Say I want like 20 text fields...do I have to create them individually?
It's not really clear what your question is. Just write a for loop and create each TextField inside it.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TwentyTextFields extends Application {
#Override
public void start(Stage primaryStage) {
final int numTextFields = 20 ;
TextField[] textFields = new TextField[numTextFields];
VBox root = new VBox(5);
for (int i = 1; i <= numTextFields; i++) {
TextField tf = new TextField();
String name = "Text field "+i ;
tf.setOnAction(e -> {
System.out.println("Action on "+name+": text is "+tf.getText());
});
root.getChildren().add(tf);
textFields[i-1] = tf ;
}
Scene scene = new Scene(new ScrollPane(root), 250, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
package javafx;
import java.util.ArrayList;
import java.util.List;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class ImageSlide extends Application {
// Width and height of image in pixels
private final double IMG_WIDTH = 600;
private final double IMG_HEIGHT = 300;
private final int NUM_OF_IMGS = 3;
private final int SLIDE_FREQ = 4; // in secs
#Override
public void start(Stage stage) throws Exception {
//root code
StackPane root = new StackPane();
Pane clipPane = new Pane();
// To center the slide show incase maximized
clipPane.setMaxSize(IMG_WIDTH, IMG_HEIGHT);
clipPane.setClip(new Rectangle(IMG_WIDTH, IMG_HEIGHT));
HBox imgContainer = new HBox();
//image view
ImageView imgGreen = new ImageView(new Image(getClass()
.getResourceAsStream("\\Merged1.pngg")));
ImageView imgBlue = new ImageView(new Image(getClass()
.getResourceAsStream("\\Merged2.png")));
ImageView imgRose = new ImageView(new Image(getClass()
.getResourceAsStream("\\Merged3.png")));
imgContainer.getChildren().addAll(imgGreen, imgBlue, imgRose);
clipPane.getChildren().add(imgContainer);
root.getChildren().add(clipPane);
Scene scene = new Scene(root, IMG_WIDTH, IMG_HEIGHT);
stage.setTitle("Image Slider");
stage.setScene(scene);
startAnimation(imgContainer);
stage.show();
}
//start animation
private void startAnimation(final HBox hbox) {
//error occured on (ActionEvent t) line
//slide action
EventHandler<ActionEvent> slideAction = (ActionEvent t) {
TranslateTransition trans = new TranslateTransition(Duration.seconds(1.5), hbox);
trans.setByX(-IMG_WIDTH);
trans.setInterpolator(Interpolator.EASE_BOTH);
trans.play();
};
//eventHandler
EventHandler<ActionEvent> resetAction = (ActionEvent t) {
TranslateTransition trans = new TranslateTransition(Duration.seconds(1), hbox);
trans.setByX((NUM_OF_IMGS - 1) * IMG_WIDTH);
trans.setInterpolator(Interpolator.EASE_BOTH);
trans.play();
};
List<KeyFrame> keyFrames = new ArrayList<>();
for (int i = 1; i <= NUM_OF_IMGS; i++) {
if (i == NUM_OF_IMGS) {
keyFrames.add(new KeyFrame(Duration.seconds(i * SLIDE_FREQ), resetAction));
} else {
keyFrames.add(new KeyFrame(Duration.seconds(i * SLIDE_FREQ), slideAction));
}
}
//add timeLine
Timeline anim = new Timeline(keyFrames.toArray(new KeyFrame[NUM_OF_IMGS]));
anim.setCycleCount(Timeline.INDEFINITE);
anim.playFromStart();
}
//call main function
public static void main(String[] args) {
launch(args);
}
}
The lines
EventHandler<ActionEvent> slideAction = (ActionEvent t) {
TranslateTransition trans = new TranslateTransition(Duration.seconds(1.5), hbox);
trans.setByX(-IMG_WIDTH);
trans.setInterpolator(Interpolator.EASE_BOTH);
trans.play();
};
should be
EventHandler<ActionEvent> slideAction = (ActionEvent t) -> {
TranslateTransition trans = new TranslateTransition(Duration.seconds(1.5), hbox);
trans.setByX(-IMG_WIDTH);
trans.setInterpolator(Interpolator.EASE_BOTH);
trans.play();
};
Note the only addition ->. Which IDE are you using?
I have a scrollPane which has various TitledPane into this, each TitledPane has various textfield's as children. When i navigate throughout textfield's using Tab key, the scrollpane do not autoscroll to ensure visible the control gaining focus. This is a program demonstrating the problem.
import java.util.Random;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class ScrollPaneEnsureVisible extends Application {
private static final Random random = new Random();
#Override
public void start(Stage primaryStage) {
VBox root = new VBox();
ScrollPane scrollPane = new ScrollPane();
Pane content = new Pane();
scrollPane.setContent(content);
for (int i = 0; i < 3; i++) {
TitledPane pane = new TitledPane();
AnchorPane paneContent = new AnchorPane();
for (int j = 0; j < 2; j++) {
TextField text = new TextField();
paneContent.getChildren().add(text);
text.setLayoutX(8);
text.setLayoutY(j*30);
}
pane.setCollapsible(false);
pane.setContent(paneContent);
pane.setLayoutY(i*100);
content.getChildren().add(pane);
}
root.getChildren().add(scrollPane);
scrollPane = new ScrollPane();
content = new Pane();
scrollPane.setContent(content);
for (int i = 0; i < 3; i++) {
TitledPane pane = new TitledPane();
AnchorPane paneContent = new AnchorPane();
pane.setContent(paneContent);
pane.setPrefWidth(200);
pane.setPrefHeight(80);
pane.setCollapsible(false);
pane.setLayoutY(i*100);
content.getChildren().add(pane);
}
root.getChildren().add(scrollPane);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) { launch(); }
}
For the second titledpane all is fine, but for first not. i need to sensure visible (autoscroll the scrollpane) that controls when they gain focus.