Вот пример того, как вы можете перемещать свои узлы в случайных местах:
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class RandomRelocateTest extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane box = new BorderPane();
AnchorPane mainPane = new AnchorPane();
addPanes(mainPane);
Button button = new Button("Randomize Location");
button.setOnAction(e -> {
randomizeLoc(mainPane);
});
box.setCenter(mainPane);
box.setBottom(button);
Scene scene = new Scene(box, 550, 450);
primaryStage.setScene(scene);
primaryStage.show();
}
// Add 15 rectangle to a specific location
private void addPanes(AnchorPane mainPane) {
for (int i = 0; i < 15; i++) {
Rectangle rec = new Rectangle();
rec.setStyle("-fx-border-color: black");
rec.setWidth(20);
rec.setHeight(20);
rec.relocate(50 + 20 * i + 5 * i, 10);
mainPane.getChildren().add(rec);
}
}
private void randomizeLoc(AnchorPane mainPane) {
double myMargins = 30;
double rectangleSize = 20;
double paneWidth = mainPane.getWidth() - myMargins - rectangleSize;
double paneHeight = mainPane.getHeight() - myMargins - rectangleSize;
// Get all the Nodes inside the AnchorPane
ObservableList<Node> childrens = mainPane.getChildren();
for (Node n : childrens) {
double x = myMargins + Math.random() * (paneWidth);
double y = myMargins + Math.random() * (paneHeight);
n.relocate(x, y);
}
}
}
Взгляните на randomizeLoc(), и я собираюсь добавить несколько изображений, объясняющих логику моих вычислений.
![введите здесь описание изображения](https://i.stack.imgur.com/0SGYG.png)
Изменить: выше приведен пример AnchorPane. Фактические размеры — это заполненный прямоугольник, а область, которую мы хотим нарисовать, — это пунктирный прямоугольник. Теперь Math.random даст вам число от 0,0 до 1,0. Прежде всего, мы хотим быть уверены, что находимся внутри пунктирной области, так что верхний левый угол находится на (20,20) (если мы установим marginValue = 20), а правый нижний угол находится на (ширина-20, высота- 20). Итак, если мы хотим быть точно внутри пунктирной области, нам нужно установить X и y следующим образом:
x = 20 + Math.random() * (width-20);
y = 20 + Math.random() * (height-20);
К сожалению, если мы получаем 1.0 (или близко к 1.0) из Math.random(), это означает, что начало прямоугольника будет равно x, y = (width-20, height-20), а прямоугольник имеет размер размером 20x20, поэтому прямоугольник (или его часть, в зависимости от значения random()) будет находиться за пределами пунктирной области. Поэтому нам нужно вычесть из ширины и высоты фактический размер прямоугольника. Таким образом, нам нужно иметь:
x = 20 + Math.random() * (width -20 - 20); // if we say the rect is 20x20
y = 20 + Math.random() * (height -20 - 20);
Таким образом, наша область теперь представляет собой пунктирную область, вычитаемую из пунктирной линии.
person
JKostikiadis
schedule
03.11.2017
50
и300
являются фактическими размерами AnchroPane? Если нет, то в чем их смысл? Я бы ожидал что-то вроде:x.addAndGet(paddingValue + Math.random() * (paneWidth - paddingValue));
и то же самое для высоты, конечно. - person JKostikiadis   schedule 03.11.2017y.addAndGet(paddingValue + Math.random() * (paneHeight - paddingValue));
- person JKostikiadis   schedule 03.11.2017addAndGet
и то, как вы на самом деле обновляете значения x и y узлов внутри AnchorPane. - person JKostikiadis   schedule 03.11.2017