我已经把我的大脑包围了2天的挑战。我对这些想法都很空虚,所以我希望那里有人知道如何做到这一点。
我从Angela Caicedo的城市应用程序中获得灵感,来自网站https://blogs.oracle.com/acaicedo/entry/managing_multiple_screens_in_javafx,并尝试制作类似的应用程序,以显示我的大学的可用房间和演讲厅。
我正在使用Java FX来构建gui,并且我打印出整个GUI,这是一个带有图像的java fx窗格。然而,我想要的只是看到gui的一小部分(我使用的背景图像是w:1500px h:500,因此每个部分将是w:500px h:500px),然后能够按下按钮或箭头(或类似)将窗口移动到下一步。在图像的顶部有3个窗格,w:500px h:500px相互咬合。考虑到Java FX可用的所有窗格类型,这可能是一个糟糕的解决方案。
所以,我需要的是一种受限制的观察者。
我还使用FMXL构建GUI,有一个FMXL文档,一个Controller和一个css文件来处理设计。
我确信我现在已经无处不在互联网上,所以我真的希望有人在Java FX之前做过这样的事情:)
好的,这是一些代码示例。第一个示例很好用,但我想实现第二个示例。我正在阅读JavaFX的TranslateTransition,但我尝试切换代码的努力是没有希望的..
第1个示例(工作,并且正在淡入淡出fxml屏幕):
public boolean setScreen(final String name){
if (screens.get(name) != null) { //screen loaded
final DoubleProperty opacity = opacityProperty();
if (!getChildren().isEmpty()) { //if there is more than one screen
Timeline fade = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(opacity, 1.0)),
new KeyFrame(new Duration(2000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
getChildren().remove(0); //remove the displayed screen
getChildren().add(0, screens.get(name)); //add the screen
Timeline fadeIn = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)),
new KeyFrame(new Duration(2000), new KeyValue(opacity, 1.0)));
fadeIn.play();
}
}, new KeyValue(opacity, 0.0)));
fade.play();
} else {
setOpacity(0.0);
getChildren().add(screens.get(name)); //no one else been displayed, then just show
Timeline fadeIn = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(opacity, 0.0)),
new KeyFrame(new Duration(1000), new KeyValue(opacity, 1.0)));
fadeIn.play();
}
return true;
} else {
System.out.println("screen hasn't been loaded!!! \n");
return false;
}
}
第二个例子,我想要实现的TranslateTransition:
private final double IMG_WIDTH = 500;
private final double IMG_HEIGHT = 500;
private final int NUM_OF_IMGS = 3;
private final int SLIDE_FREQ = 4; // in secs
@Override
public void start(Stage stage) throws Exception {
stage.initStyle(StageStyle.UNDECORATED);
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();
ImageView imgGreen = new ImageView(new Image(getClass().getResourceAsStream("uib_01.jpg")));
ImageView imgBlue = new ImageView(new Image(getClass().getResourceAsStream("uib_02.jpg")));
ImageView imgRose = new ImageView(new Image(getClass().getResourceAsStream("uib_03.jpg")));
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();
}
private void startAnimation(final HBox hbox) {
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<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));
}
}
Timeline anim = new Timeline(keyFrames.toArray(new KeyFrame[NUM_OF_IMGS]));
anim.setCycleCount(Timeline.INDEFINITE);
anim.playFromStart();
}
点击按钮后屏幕应该会改变。我在一个单独的控制器类中有这个:
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
public class roomAppController implements Initializable, ScreenController {
private ScreenPane myScreenPane;
@FXML
public ImageView bldArw_1;
public ImageView rmArw_1;
@FXML
private void handleExitButtonEvent(MouseEvent e) {
System.out.println("Button is clicked");
System.exit(0);
}
@FXML
private void handleNextPageEvent(MouseEvent e) {
if((ImageView)e.getSource() == bldArw_1) {
myScreenPane.setScreen("buildingScreen");
}
if((ImageView)e.getSource() == rmArw_1) {
myScreenPane.setScreen("roomScreen");
}
System.out.println("Clicked");
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
@Override
public void setScreenPane(ScreenPane screenPage) {
myScreenPane = screenPage;
}
}