Gần đây tôi đã muốn tạo một nền động trong JavaFX, tương tự như ví dụ Swing được xem here. Tôi đã sử dụng Canvas
để vẽ, như được hiển thị trong Working with the Canvas API và AnimationTimer
cho vòng vẽ, như được hiển thị trong Animation Basics. Thật không may, tôi không chắc chắn làm thế nào để thay đổi kích thước các Canvas
tự động như là kèm theo Stage
được thay đổi kích cỡ. Cách tiếp cận tốt là gì?Tự động thay đổi kích cỡ Canvas để điền vào các phụ huynh kèm theo
Trả lời
Trong ví dụ dưới đây, các tĩnh lồng lớp CanvasPane
kết thúc tốt đẹp một thể hiện của Canvas
trong một Pane
và ghi đè layoutChildren()
để làm cho kích thước vải phù hợp với kèm theo Pane
. Lưu ý rằng Canvas
trả về false
từ isResizable()
, vì vậy "cha mẹ không thể thay đổi kích thước trong bố cục" và Pane
"không thực hiện bố cục ngoài việc định lại kích thước các trẻ có thể thay đổi thành kích thước ưa thích của chúng". width
và height
được sử dụng để xây dựng canvas trở thành kích thước ban đầu của nó. Cách tiếp cận tương tự được sử dụng trong mô phỏng hạt Ensemble, Fireworks.java
, để chia tỷ lệ hình nền trong khi vẫn giữ tỷ lệ khung hình.
Là một sang một bên, hãy lưu ý sự khác biệt khi sử dụng các màu bão hòa hoàn toàn so với bản gốc. Các liên quan examples này minh họa cách đặt điều khiển trên nền hoạt ảnh.
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* @see https://stackoverflow.com/a/31761362/230513
* @see https://stackoverflow.com/a/8616169/230513
*/
public class Baubles extends Application {
private static final int MAX = 64;
private static final double WIDTH = 640;
private static final double HEIGHT = 480;
private static final Random RND = new Random();
private final Queue<Bauble> queue = new LinkedList<>();
private Canvas canvas;
@Override
public void start(Stage stage) {
CanvasPane canvasPane = new CanvasPane(WIDTH, HEIGHT);
canvas = canvasPane.getCanvas();
BorderPane root = new BorderPane(canvasPane);
CheckBox cb = new CheckBox("Animate");
cb.setSelected(true);
root.setBottom(cb);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
for (int i = 0; i < MAX; i++) {
queue.add(randomBauble());
}
AnimationTimer loop = new AnimationTimer() {
@Override
public void handle(long now) {
GraphicsContext g = canvas.getGraphicsContext2D();
g.setFill(Color.BLACK);
g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
for (Bauble b : queue) {
g.setFill(b.c);
g.fillOval(b.x, b.y, b.d, b.d);
}
queue.add(randomBauble());
queue.remove();
}
};
loop.start();
cb.selectedProperty().addListener((Observable o) -> {
if (cb.isSelected()) {
loop.start();
} else {
loop.stop();
}
});
}
private static class Bauble {
private final double x, y, d;
private final Color c;
public Bauble(double x, double y, double r, Color c) {
this.x = x - r;
this.y = y - r;
this.d = 2 * r;
this.c = c;
}
}
private Bauble randomBauble() {
double x = RND.nextDouble() * canvas.getWidth();
double y = RND.nextDouble() * canvas.getHeight();
double r = RND.nextDouble() * MAX + MAX/2;
Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
return new Bauble(x, y, r, c);
}
private static class CanvasPane extends Pane {
private final Canvas canvas;
public CanvasPane(double width, double height) {
canvas = new Canvas(width, height);
getChildren().add(canvas);
}
public Canvas getCanvas() {
return canvas;
}
@Override
protected void layoutChildren() {
super.layoutChildren();
final double x = snappedLeftInset();
final double y = snappedTopInset();
final double w = snapSize(getWidth()) - x - snappedRightInset();
final double h = snapSize(getHeight()) - y - snappedBottomInset();
canvas.setLayoutX(x);
canvas.setLayoutY(y);
canvas.setWidth(w);
canvas.setHeight(h);
}
}
public static void main(String[] args) {
launch(args);
}
}
Không thể bạn làm điều này với một Binding
không? Sau đây dường như để sản xuất các kết quả tương tự mà không cần phải thêm lớp dẫn xuất.
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.DoubleBinding;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/**
* @see http://stackoverflow.com/a/31761362/230513
* @see http://stackoverflow.com/a/8616169/230513
*/
public class Baubles extends Application {
private static final int MAX = 64;
private static final double WIDTH = 640;
private static final double HEIGHT = 480;
private static final Random RND = new Random();
private final Queue<Bauble> queue = new LinkedList<>();
private Canvas canvas;
@Override
public void start(Stage stage) {
canvas = new Canvas(WIDTH, HEIGHT);
BorderPane root = new BorderPane(canvas);
CheckBox cb = new CheckBox("Animate");
cb.setSelected(true);
root.setBottom(cb);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
// Create bindings for resizing.
DoubleBinding heightBinding = root.heightProperty()
.subtract(root.bottomProperty().getValue().getBoundsInParent().getHeight());
canvas.widthProperty().bind(root.widthProperty());
canvas.heightProperty().bind(heightBinding);
for (int i = 0; i < MAX; i++) {
queue.add(randomBauble());
}
AnimationTimer loop = new AnimationTimer() {
@Override
public void handle(long now) {
GraphicsContext g = canvas.getGraphicsContext2D();
g.setFill(Color.BLACK);
g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
for (Bauble b : queue) {
g.setFill(b.c);
g.fillOval(b.x, b.y, b.d, b.d);
}
queue.add(randomBauble());
queue.remove();
}
};
loop.start();
cb.selectedProperty().addListener((Observable o) -> {
if (cb.isSelected()) {
loop.start();
} else {
loop.stop();
}
});
}
private static class Bauble {
private final double x, y, d;
private final Color c;
public Bauble(double x, double y, double r, Color c) {
this.x = x - r;
this.y = y - r;
this.d = 2 * r;
this.c = c;
}
}
private Bauble randomBauble() {
double x = RND.nextDouble() * canvas.getWidth();
double y = RND.nextDouble() * canvas.getHeight();
double r = RND.nextDouble() * MAX + MAX/2;
Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
return new Bauble(x, y, r, c);
}
public static void main(String[] args) {
launch(args);
}
}
Cảm ơn bạn đã đề xuất 'Ràng buộc'. Tôi có đúng để suy ra rằng ràng buộc sẽ phải thay đổi cho một bố cục 'root' khác không? Tôi chỉ kiểm tra 'CanvasPane' trong' BorderPane' và 'StackPane'. – trashgod
Các chi tiết sẽ cần phải thay đổi, nhưng một cái gì đó tương tự nên làm việc. Ngoài ra, ví dụ này không hoàn toàn chung cho một 'BorderPane' vì một số chi tiết sẽ cần thay đổi nếu bạn có các nút ở vị trí trên cùng, bên trái hoặc bên phải. – clartaq
Ah, tôi hiểu; trong một 'StackPane', tôi có thể' bind() '' canvas.heightProperty() 'trực tiếp vào' root.heightProperty() '. Cho đến nay tôi nghĩ rằng 'CanvasPane' là linh hoạt hơn, nhưng cộng với một cho một sự thay thế hữu ích và một ví dụ cụ thể về số học 'Binding'. – trashgod
- 1. WPF: Làm thế nào để làm cho canvas tự động thay đổi kích cỡ?
- 2. TextView "fill_parent" không điền vào phụ huynh
- 3. cách tự động thay đổi kích cỡ bootstrap-wysihtml5
- 4. CSS Điền phụ huynh div 100% sạch
- 5. Nội dung SwingNode không thay đổi kích thước khi phụ huynh của SwingNode đổi kích thước
- 6. Facebook Canvas APP (Iframed) Tự động thay đổi kích thước chiều cao
- 7. tự động thay đổi kích thước văn bản (cỡ chữ) khi thay đổi kích thước cửa sổ?
- 8. Kích thước thay đổi kích cỡ tinym dọc chỉ
- 9. thay đổi kích thước hộp tự động theo các nội dung
- 10. Thay đổi kích thước phông chữ để điền vào UITextView?
- 11. Tự động thay đổi kích thước chế độ xem phụ được tạo theo chương trình
- 12. Thay đổi kích cỡ hình ảnh động giữa NSView
- 13. Thay đổi kích cỡ vector của STL
- 14. Biểu tượng JButton tự động thay đổi kích thước
- 15. Thay đổi kích cỡ khung hình bằng vải js
- 16. Thay đổi chi nhánh phụ huynh
- 17. Làm thế nào để thay đổi kích cỡ WorldWind Panel?
- 18. Thay đổi kích cỡ mảng bằng C
- 19. thay đổi phụ huynh của quá trình
- 20. C# Tự động đổi kích cỡ biểu mẫu thành kích thước của DataGridView
- 21. Cannnot thay đổi kích cỡ Child Controls trong FlowLayoutPanel Control
- 22. Raphael JS thay đổi kích thước Canvas
- 23. Thay đổi kích cỡ UIImage bằng các cạnh cứng
- 24. Tự động điền của Chrome không kích hoạt xác thực. Sự kiện tự động điền chuẩn?
- 25. Thay đổi kích cỡ các điều khiển Khi chạy
- 26. Cách thay đổi kích thước CKEditor để phù hợp với phụ huynh div
- 27. Thay đổi kích cỡ UIImage và thay đổi kích thước của UIImageView
- 28. Qt & Qt Designer - Làm phụ tùng điền phụ huynh mà không cần đệm
- 29. Tự động thay đổi vị trí của cửa sổ phụ thuộc vào vị trí hiển thị
- 30. Tải lên thay đổi kích cỡ ảnh để S3
Bản trình diễn hay .. + 1 .. – Reimeus