How I can resize Pane in GridPane? I'm creating a GUI which is GridPane and a map in it. And when gui change it's size I want to map which is in another Pane to resize. So I've added listners to width and height property of scene and there are generaly working. When I do setTranslateX of map I can see that something changed, but resizing not works at all. It can be caused by fact that map contains from tiles which have their size set. Code of method which create the scene:
private Scene createScene(GridPane root){
Scene scene = new Scene(root, WIDTH_OF_SCENE, HEIGHT_OF_SCENE);
scene.widthProperty().addListener((observableValue, oldSceneWidth, newSceneWidth) -> {
WIDTH_OF_SCENE = newSceneWidth.intValue();
draw();
MAP_PANE.setPrefSize(200, 200); //it's not working
MAP_PANE.setTranslateX(0); //it's working
root.requestLayout();
});
scene.heightProperty().addListener((observableValue, oldSceneHeight, newSceneHeight) ->{
HEIGHT_OF_SCENE = newSceneHeight.intValue();
draw();
root.requestLayout();
});
return scene;
}
And here I'm creating MAP_PANE:
public Pane createContent() {
map = new Pane();
map.setStyle("-fx-background-color: #383838");
// dodawanie pojedynczych kafli do dwuwymiarowej tablicy
for (int y = 0; y < Y_TILES; y++) {
for (int x = 0; x < X_TILES; x++) {
Tile tile = new Tile(x, y);
grid[x][y] = tile;
map.getChildren().addAll(tile);
}
}
return map;
}
And start method:
#Override
public void start(Stage primaryStage) throws Exception{
Map map = new Map();
GridPane root = FXMLLoader.load(getClass().getResource("sample.fxml"));
MAP_PANE = map.createContent();
IMAGE_VIEW = new ImageView();
countScreenSize();
draw();
root.getChildren().addAll(IMAGE_VIEW);
root.getChildren().addAll(MAP_PANE);
primaryStage.setTitle(TITLE);
primaryStage.setScene(createScene(root));
primaryStage.show();
}
Related
Each stack pane is supposed to have two nodes. However the bottom node disappears outside the for loop for the first 2 indices in the stack pane array.
public class Main extends Application {
GridPane images;
StackPane[] stackPane;
ImageView cardBack;
ImageView[] cardImages;
#Override
public void start(Stage stage) throws FileNotFoundException {
images = new GridPane(); images.setAlignment(Pos.CENTER);
images.setVgap(5); images.setHgap(5);
cardBack = new ImageView(new Image(new FileInputStream("images/b1fv.gif")));
cardImages = new ImageView[]{
new ImageView(new Image(new FileInputStream("images/c1.gif"))),
new ImageView(new Image(new FileInputStream("images/c2.gif"))),
new ImageView(new Image(new FileInputStream("images/c3.gif")))
};
final Button[] flip = new Button[cardImages.length];
stackPane = new StackPane[cardImages.length];
for (int i = 0; i < cardImages.length; i++) {
stackPane[i] = new StackPane();
stackPane[i].getChildren().addAll(cardBack, cardImages[i]);
images.add(stackPane[i], i, 0, 1, 1);
flip[i] = new Button("Flip");
GridPane.setHalignment(flip[i], HPos.CENTER);
images.add(flip[i], i, 1, 1, 1);
// Debug
System.out.println(stackPane[i].getChildren().toString());
final int j = i;
flip[j].setOnAction(event -> doFlip(j));
}
// Debug
System.out.println("");
for (StackPane pane : stackPane)
System.out.println(pane.getChildren().toString());
stage.setTitle("Assignment 11");
stage.setScene(new Scene(images, 500,200));
stage.show();
}
void doFlip(int loc) {
// Debug
System.out.println("");
for (StackPane pane : stackPane)
System.out.println(pane.getChildren().toString());
ObservableList<Node> children = stackPane[loc].getChildren();
Node topNode = children.get(children.size()-1);
topNode.toBack();
}
public static void main(String[] args) {
launch(args);
}
}
[ImageView#5e1bc54a[styleClass=image-view], ImageView#25389181[styleClass=image-view]]
[ImageView#5e1bc54a[styleClass=image-view], ImageView#ff7cf97[styleClass=image-view]]
[ImageView#5e1bc54a[styleClass=image-view], ImageView#18b8669d[styleClass=image-view]]
[ImageView#25389181[styleClass=image-view]]
[ImageView#ff7cf97[styleClass=image-view]]
[ImageView#5e1bc54a[styleClass=image-view], ImageView#18b8669d[styleClass=image-view]]
[ImageView#25389181[styleClass=image-view]]
[ImageView#ff7cf97[styleClass=image-view]]
[ImageView#5e1bc54a[styleClass=image-view], ImageView#18b8669d[styleClass=image-view]]
Inside the for loop it displays all objects. However, outside the loop in does not display the bottom nodes except for the last element of array.
You cannot add the same Node instance to multiple parents!
In the top of your loop you have the following line:
stackPane[i].getChildren().addAll(cardBack, cardImages[i]);
The cardBack Node would be added to all StackPanes, but since it can only have one parent, it will be removed from the previous. Javafx has provided a way to reuse Image resources though (which is I imagine the thing you want to achieve). Instead of creating one ImageView, you can cache the Image instance passes in the ImageView constructor. E.g:
cardBack = new Image(new FileInputStream("images/b1fv.gif"));
// some stuff
for (int i = 0; i < cardImages.length; i++) {
stackPane[i] = new StackPane();
stackPane[i].getChildren().addAll(new ImageView(cardBack) , cardImages[i]);
// rest of the loop
}
If you use the Image and ImageView as described above, things will work correctly.
I am trying to implement a full press-drag-release gesture with JavaFX. I want to drag a rectangle from one VBox to another. On the MOUSE_DRAG_RELEASED event that happens on the target VBox, I'm trying to add the dragged rectangle as a child of the target VBox.
The problem is that when I release the mouse on the target VBox, the rectangle does not get into the expected position inside the VBox, but is always offset to the right by a fixed distance.
public class DragFromOneVBoxToAnother extends Application {
private Disk sourceDisk = new Disk();
private VBox targetVBox = new VBox();
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage stage) {
// Build the UI
GridPane root = getUI();
// Add the event handlers
this.addEventHandlers();
Scene scene = new Scene(root, 800, 600);
stage.setScene(scene);
stage.show();
}
private GridPane getUI() {
GridPane pane = new GridPane();
VBox sourceVBox = new VBox();
sourceDisk.setWidth(90);
sourceDisk.setHeight(20);
sourceVBox.setStyle(" -fx-border-color:red; -fx-border-width: 1; -fx-border-style: solid;");
targetVBox.setStyle(" -fx-border-color:green; -fx-border-width: 1; -fx-border-style: solid;");
sourceVBox.getChildren().add(sourceDisk);
targetVBox.getChildren().add(new Rectangle(200, 20));
pane.setHgap(200);
pane.addColumn(0, sourceVBox);
pane.addColumn(1, targetVBox);
pane.setPadding(new Insets(200, 100, 200, 100));
return pane;
}
private void addEventHandlers() {
sourceDisk.setOnMouseEntered(event -> sourceDisk.setCursor(Cursor.HAND));
sourceDisk.setOnMousePressed(event -> {
sourceDisk.setOrgSceneX(event.getSceneX());
sourceDisk.setOrgSceneY(event.getSceneY());
sourceDisk.setOrgTranslateX(sourceDisk.getTranslateX());
sourceDisk.setOrgTranslateY(sourceDisk.getTranslateY());
sourceDisk.setMouseTransparent(true);
sourceDisk.setCursor(Cursor.CLOSED_HAND);
});
sourceDisk.setOnDragDetected(event -> sourceDisk.startFullDrag());
sourceDisk.setOnMouseDragged(event -> {
double offsetX = event.getSceneX() - sourceDisk.getOrgSceneX();
double offsetY = event.getSceneY() - sourceDisk.getOrgSceneY();
double newTranslateX = sourceDisk.getOrgTranslateX() + offsetX;
double newTranslateY = sourceDisk.getOrgTranslateY() + offsetY;
sourceDisk.setTranslateX(newTranslateX);
sourceDisk.setTranslateY(newTranslateY);
});
sourceDisk.setOnMouseReleased(event -> {
sourceDisk.setMouseTransparent(false);
sourceDisk.setCursor(Cursor.DEFAULT);
});
targetVBox.setOnMouseDragReleased(event ->
targetVBox.getChildren().add(sourceDisk));
}
private class Disk extends Rectangle {
private double orgSceneX;
private double orgSceneY;
private double orgTranslateX;
private double orgTranslateY;
// below, the getters and setters for all the instance variables
// were removed for brevity
}
I have found that, even though the visual representation of the dragged rectangle seems to be offset when it's dropped, a child appears to actually be added to the target VBox (this can be seen because the border of the VBox expands after the MOUSE_DRAG_RELEASED event).
What could be the issue?
During the mouse drag gesture you modify the translateX/translateY properties of the node. This results in the dragged node being offset from the position where the new parent places it by this transformation. You need to reset those values to properly add the node to the bottom of the VBox:
targetVBox.setOnMouseDragReleased(event -> {
targetVBox.getChildren().add(sourceDisk);
// reset translate values
sourceDisk.setTranslateX(0);
sourceDisk.setTranslateY(0);
});
I'm trying to make TreeView with CheckBoxTreeItems. When I collapse/expand a CheckBoxTreeItems the image I set up does not display correctly. I googled but I couldn't find correct answer. On Stack Overflow, I found a similar problem, but I didn't get a valid answer.
E.g
JavaFX CheckBoxTreeItem graphic disappear when siblings collapse
JavaFX CheckBoxTreeItem: Graphic disappears if graph is extended
Any ideas?
public class ClientApplication extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(final Stage stage) {
ImageView folderIcon = new ImageView();
Image folderImage = new Image("image/folder.png");
folderIcon.setImage(folderImage);
folderIcon.setFitWidth(16);
folderIcon.setFitHeight(16);
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<String>("folder", folderIcon);
rootItem.setExpanded(true);
for (int i = 0; i < 4; i++) {
CheckBoxTreeItem<String> checkBoxTreeItem = new CheckBoxTreeItem<String>("Sample" + (i + 1), folderIcon);
rootItem.getChildren().add(checkBoxTreeItem);
}
final TreeView<String> tree = new TreeView<String>(rootItem);
tree.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
tree.setRoot(rootItem);
tree.setShowRoot(true);
StackPane root = new StackPane();
root.getChildren().add(tree);
stage.setScene(new Scene(root, 300, 250));
stage.show();
}
}
enter image description here
I tried to use the ideas provided by #Jai,But when I click the expand/collapse icon, there is still a problem.Attachment is a screenshot.Thanks in advance.
enter image description here
ImageView is a JavaFX control. This means that each instance represents a unique control you see on your screen. You should never use the same instance for multiple locations in your GUI.
On the other hand, Image represents an image (i.e. an array of pixel data), so it is reusable.
This should work:
#Override
public void start(final Stage stage) {
final Image folderImage = new Image("image/folder.png");
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<String>("folder", createImageView(folderImage));
rootItem.setExpanded(true);
for (int i = 0; i < 4; i++) {
CheckBoxTreeItem<String> checkBoxTreeItem = new CheckBoxTreeItem<String>("Sample" + (i + 1), createImageView(folderImage));
rootItem.getChildren().add(checkBoxTreeItem);
}
final TreeView<String> tree = new TreeView<String>(rootItem);
tree.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
tree.setRoot(rootItem);
tree.setShowRoot(true);
StackPane root = new StackPane();
root.getChildren().add(tree);
stage.setScene(new Scene(root, 300, 250));
stage.show();
}
private ImageView createImageView(Image folderImage) {
ImageView folderIcon = new ImageView();
folderIcon.setImage(folderImage);
folderIcon.setFitWidth(16);
folderIcon.setFitHeight(16);
return folderIcon;
}
Im working on a project for school and I'm having trouble adding a child pane to a parent pane. All the code compiles except when I get to the pane.getChildren().add(Matrix); . Im able to get the code to compile when I have all the code in main, but I really want to have main call a class and create the pane there then add it to the parent pane. Im not to worried about it looking pretty right now, just want to find a way to get it to work. If anyone could help get me going in the right direction I would really appreciate it.
The compiler gives me
Button1.java:34: error: identifier expected
pane.getChildren().add(Matrix);
Button1.java:34: error: ';' expected
pane.getChildren().add(Matrix);
public class Button1 extends Application {
public void start(Stage primaryStage) {
Scene scene = new Scene(pane, 700, 500);
primaryStage.setTitle("3 pains 1 window "); // Set the stage title
primaryStage.setScene(scene); // Place the scene in the stage
primaryStage.show(); // Display the stage
}
public static void main(String[] args) {
Application.launch(args);
}
GridPane pane = new GridPane();
MatrixPane Matrix = new MatrixPane();
pane.getChildren().add(Matrix);
}
class MatrixPane extends Pane {
double HEIGHT = 500;
double WIDTH = 200;
private GridPane pane = new GridPane();
public MatrixPane() {
}
public void fillpane() {
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
TextField text = new TextField(Integer.toString((int)(Math.random() * 2)));
text.setMinWidth(WIDTH / 8.0);
text.setMaxWidth(WIDTH / 10.0);
text.setMinHeight(HEIGHT / 8.0);
text.setMaxHeight(HEIGHT / 10.0);
pane.add(text, j, i);
}
}
}
}
That line have to be inside of a method, I suggest that it should be inside of start
public void start(Stage primaryStage) {
pane.getChildren().add(Matrix);
...
You have missed to include the following section inside a method().
I can trivially create a scroll pane in JavaFX that only scrolls horizontally like so:
ScrollPane scroll = new ScrollPane(lcp);
scroll.setPannable(true);
scroll.setFitToHeight(true);
scroll.setVbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
However, the mouse scroll wheel still tries to scroll vertically rather than horizontally in this case (unless I specifically scroll over the horizontal scroll bar.)
How can I set up the scroll pane so that the mouse wheel pans horizontally?
Here is the example application that I wrote for you and does exactly what you want:
public class Test extends Application {
ScrollPane scrollPane;
int pos = 0;
final int minPos = 0;
final int maxPos = 100;
#Override
public void start(Stage primaryStage) {
Label label = new Label("TEXT!!!!!!!TEXT!!!!!!!TEXT!!!!!!!TEXT!!!!!!!TEXT!!!!!!!TEXT");
label.setPrefSize(500, 100);
label.setOnScroll(new EventHandler<ScrollEvent>() {
#Override
public void handle(ScrollEvent event) {
if (event.getDeltaY() > 0)
scrollPane.setHvalue(pos == minPos ? minPos : pos--);
else
scrollPane.setHvalue(pos == maxPos ? maxPos : pos++);
}
});
scrollPane = new ScrollPane();
scrollPane.setHmin(minPos);
scrollPane.setHmax(maxPos);
scrollPane.setVbarPolicy(ScrollBarPolicy.NEVER);
scrollPane.setHbarPolicy(ScrollBarPolicy.ALWAYS);
scrollPane.setPannable(true);
scrollPane.setFitToHeight(true);
scrollPane.setContent(label);
BorderPane root = new BorderPane();
root.setPrefSize(200, 100);
root.setCenter(scrollPane);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I have also been looking for a solution and found this one from Ugurcan Yildirim but didn't like the fact that the natural scroll bar length and speed is modified also. This one worked for me:
scrollPane.setOnScroll(event -> {
if(event.getDeltaX() == 0 && event.getDeltaY() != 0) {
scrollPane.setHvalue(scrollPane.getHvalue() - event.getDeltaY() / this.allComments.getWidth());
}
});
event.getDeltaX() == 0 just to be sure that the user is only using the mouse wheel and nothing is adding up
this.allComments is the content of the scrollPane (a HBox in my case). By dividing the delta y value by it's content width the scroll speed is natural according to the amount of content to scroll.