在JavaFX中对图像进行侧面滚动

时间:2015-02-13 01:22:13

标签: java css user-interface javafx horizontal-scrolling

我已经把我的大脑包围了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;
    }   
}

0 个答案:

没有答案