Hallo,
ich stehe aktuell vor einem JavaFX Problem, das ich nicht gelöst bekomme und suche deshalb hier nach Unterstützung.
Ich habe eine Scrollpane, in der mehrere Borderpanes befinden. In diesen Borderpanes werden Thumbnails von Bildern angezeigt. Klickt man auf ein Thumbnail, so erscheint das Bild in einer großen Imageview rechts neben der Scrollpane.
Nun soll man nicht nur per Mausklick auf das Thumbnail das Bild sehen können, sondern auch durch Buttons oder dem Drücken der Pfeiltasten. Wenn auf den "nächstes Bild"-Button gedrückt wird, wird das nächste Thumbnail "ausgewählt" (Es wird ein Rahmen darum gezeichnet) und erscheint in groß auf dem großen Imageview. Ist man mit der Auswahl am untersten Rand der Scrollpane angekommen sollte die Scrollpane so weit nach unten scrollen, dass am unteren rand des Viewports das ausgewählte Thumbnail zu sehen ist und entsprechend analog, wenn man nach oben geht.
Das Verhalten soll exakt dasselbe wie beim Adobe Reader sein, wenn man ein mehrseitiges PDF anschaut:

Dies möchte ich so auch gerne in meinem Programm haben, kämpfe allerdings mit dem Scrollen.
Die Scrolllogik sollte in zoomToActualThumbnail() passieren, allerdings komme ich nicht dahinter. So wie ich es aktuell hab mit HIlfe von JavaFX ScrollPane programmatically moving the viewport - centering content scrollt es immer nur teilweise und in einem "Bogen". Das unterste Thumbnail ist nie vollständig zu sehen.
SSCCE:
view.fxml (Hier müssten entsprechend die Bilder in den Zeilen 24, 33, 42, 53 und 60 ausgetauscht werden oder ein Bild mit dem namen "Aufkleber_Trollface.jpg" im src Ordner gespeichert werden)
Main.java
Ich bin für jede Hilfe dankbar!
Viele Grüße
Woggle
Edit: Projekt zum Download angehängt
ich stehe aktuell vor einem JavaFX Problem, das ich nicht gelöst bekomme und suche deshalb hier nach Unterstützung.
Ich habe eine Scrollpane, in der mehrere Borderpanes befinden. In diesen Borderpanes werden Thumbnails von Bildern angezeigt. Klickt man auf ein Thumbnail, so erscheint das Bild in einer großen Imageview rechts neben der Scrollpane.
Nun soll man nicht nur per Mausklick auf das Thumbnail das Bild sehen können, sondern auch durch Buttons oder dem Drücken der Pfeiltasten. Wenn auf den "nächstes Bild"-Button gedrückt wird, wird das nächste Thumbnail "ausgewählt" (Es wird ein Rahmen darum gezeichnet) und erscheint in groß auf dem großen Imageview. Ist man mit der Auswahl am untersten Rand der Scrollpane angekommen sollte die Scrollpane so weit nach unten scrollen, dass am unteren rand des Viewports das ausgewählte Thumbnail zu sehen ist und entsprechend analog, wenn man nach oben geht.
Das Verhalten soll exakt dasselbe wie beim Adobe Reader sein, wenn man ein mehrseitiges PDF anschaut:

Dies möchte ich so auch gerne in meinem Programm haben, kämpfe allerdings mit dem Scrollen.
Die Scrolllogik sollte in zoomToActualThumbnail() passieren, allerdings komme ich nicht dahinter. So wie ich es aktuell hab mit HIlfe von JavaFX ScrollPane programmatically moving the viewport - centering content scrollt es immer nur teilweise und in einem "Bogen". Das unterste Thumbnail ist nie vollständig zu sehen.
Java:
private void zoomToActualThumbnail() {
//Set Selection Border
this.setBorderForActualThumbnail();
double height = this.sp_thumbnailScrollPane.getContent().getBoundsInLocal().getHeight();
double y = this.vbox_thumbnailVBox.getChildren().get(this.selectedThumbnail).getBoundsInParent().getMinY();
this.sp_thumbnailScrollPane.setVvalue(this.sp_thumbnailScrollPane.getVmax() * (y / height));
}
SSCCE:
view.fxml (Hier müssten entsprechend die Bilder in den Zeilen 24, 33, 42, 53 und 60 ausgetauscht werden oder ein Bild mit dem namen "Aufkleber_Trollface.jpg" im src Ordner gespeichert werden)
Java:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-background-color: transparent;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Main">
<children>
<HBox maxHeight="1.7976931348623157E308" spacing="15.0" style="-fx-background-color: transparent;" VBox.vgrow="ALWAYS">
<children>
<VBox alignment="TOP_CENTER" fillWidth="false">
<children>
<ScrollPane fx:id="sp_thumbnailScrollPane" fitToWidth="true" hbarPolicy="NEVER" prefViewportHeight="383.0" prefViewportWidth="100.0" prefWidth="110.0" style="-fx-background-color: transparent;" styleClass="thumbnail-band" VBox.vgrow="ALWAYS">
<content>
<VBox fx:id="vbox_thumbnailVBox" maxHeight="1.7976931348623157E308" prefWidth="100.0" spacing="10.0" style="-fx-background-color: transparent;" styleClass="thumbnail-band">
<children>
<BorderPane layoutX="10.0" layoutY="10.0" maxWidth="100.0" prefHeight="150.0" prefWidth="59.0">
<center>
<ImageView fitHeight="150.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER">
<image>
<Image url="@Aufkleber_Trollface.jpg" />
</image>
</ImageView>
</center>
</BorderPane>
<BorderPane layoutX="10.0" layoutY="10.0" maxWidth="100.0" prefHeight="150.0" prefWidth="59.0">
<center>
<ImageView fitHeight="150.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER">
<image>
<Image url="@Aufkleber_Trollface.jpg" />
</image>
</ImageView>
</center>
</BorderPane>
<BorderPane layoutX="10.0" layoutY="170.0" maxWidth="100.0" prefHeight="150.0" prefWidth="59.0">
<center>
<ImageView fitHeight="150.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER">
<image>
<Image url="@Aufkleber_Trollface.jpg" />
</image>
</ImageView>
</center>
</BorderPane>
<BorderPane layoutX="10.0" layoutY="330.0" maxWidth="100.0" prefHeight="150.0" prefWidth="59.0">
<center>
<ImageView fitHeight="150.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER">
<image>
<Image url="@Aufkleber_Trollface.jpg" />
</image>
</ImageView>
</center>
</BorderPane>
<BorderPane layoutX="10.0" layoutY="490.0" maxWidth="100.0" prefHeight="150.0" prefWidth="59.0">
<center>
<ImageView fitHeight="150.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER">
<image>
<Image url="@Aufkleber_Trollface.jpg" />
</image>
</ImageView>
</center>
</BorderPane>
</children></VBox>
</content>
<VBox.margin>
<Insets />
</VBox.margin>
</ScrollPane>
<VBox alignment="TOP_CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" VBox.vgrow="NEVER">
<children>
<HBox alignment="BOTTOM_CENTER" spacing="5.0">
<children>
<Button mnemonicParsing="false" onAction="#goFirstPressed" text="<|" />
<Button layoutX="10.0" layoutY="10.0" mnemonicParsing="false" onAction="#previousPressed" text="<" />
<Button layoutX="43.0" layoutY="10.0" mnemonicParsing="false" onAction="#nextPressed" text=">" />
<Button layoutX="76.0" layoutY="10.0" mnemonicParsing="false" onAction="#goLastPressed" text="|>" />
</children>
</HBox>
</children>
<VBox.margin>
<Insets bottom="15.0" top="16.0" />
</VBox.margin>
</VBox>
</children>
</VBox>
<VBox maxHeight="1.7976931348623157E308" HBox.hgrow="NEVER">
<children>
<HBox fx:id="hbox_ivParent" maxHeight="1.7976931348623157E308" VBox.vgrow="ALWAYS">
<children>
<ScrollPane fx:id="scrollpane_imageviewScrollpane" fitToHeight="true" hbarPolicy="NEVER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" pannable="true" prefViewportHeight="381.4000015258789" prefViewportWidth="270.0" styleClass="scan-scrollpane" vbarPolicy="NEVER" HBox.hgrow="NEVER">
<content>
<ImageView fx:id="iv_imageview" fitHeight="382.0" fitWidth="270.0" pickOnBounds="true" preserveRatio="true" styleClass="scan-imageview">
<viewport>
<Rectangle2D />
</viewport>
</ImageView>
</content>
</ScrollPane>
</children>
</HBox>
</children>
</VBox>
</children>
<VBox.margin>
<Insets bottom="15.0" />
</VBox.margin>
</HBox>
</children>
<padding>
<Insets bottom="25.0" left="25.0" right="25.0" />
</padding>
</VBox>
Main.java
Java:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.net.URL;
import java.util.ResourceBundle;
public class Main extends Application {
@FXML
private ScrollPane sp_thumbnailScrollPane;
@FXML
private ImageView iv_imageview;
@FXML
private VBox vbox_thumbnailVBox;
private static final int MAX_INDEX = 5;
private int selectedThumbnail = 0;
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("view.fxml"));
VBox vbox = (VBox)loader.load();
stage.setScene(new Scene(vbox));
stage.show();
}
@FXML
void initialize(URL location, ResourceBundle bundle) {
this.zoomToActualThumbnail();
}
private void zoomToActualThumbnail() {
//Set Selection Border
this.setBorderForActualThumbnail();
double height = this.sp_thumbnailScrollPane.getContent().getBoundsInLocal().getHeight();
double y = this.vbox_thumbnailVBox.getChildren().get(this.selectedThumbnail).getBoundsInParent().getMinY();
this.sp_thumbnailScrollPane.setVvalue(this.sp_thumbnailScrollPane.getVmax() * (y / height));
}
private void setBorderForActualThumbnail() {
//remove all borders
for (Node node : this.vbox_thumbnailVBox.getChildren()) {
node.getStyleClass().clear();
node.setStyle("-fx-border-color: transparent");
}
this.vbox_thumbnailVBox.getChildren().get(this.selectedThumbnail).setStyle("-fx-border-color: rgb(61,105,156);-fx-border-insets: -1px;-fx-border-width: 3px;");
this.iv_imageview.setImage(((ImageView) ((BorderPane) this.vbox_thumbnailVBox.getChildren().get(this.selectedThumbnail)).getCenter()).getImage());
}
@FXML
void goFirstPressed(ActionEvent event) {
this.selectedThumbnail = 0;
this.zoomToActualThumbnail();
}
@FXML
void previousPressed(ActionEvent event) {
if(this.selectedThumbnail > 0) {
this.selectedThumbnail -= 1;
}
this.zoomToActualThumbnail();
}
@FXML
void nextPressed(ActionEvent event) {
if(this.selectedThumbnail < Main.MAX_INDEX-1) {
this.selectedThumbnail += 1;
}
this.zoomToActualThumbnail();
}
@FXML
void goLastPressed(ActionEvent event) {
this.selectedThumbnail = MAX_INDEX-1;
this.zoomToActualThumbnail();
}
public static void main(String[] args) {
launch(args);
}
}
Ich bin für jede Hilfe dankbar!
Viele Grüße
Woggle
Edit: Projekt zum Download angehängt
Anhänge
Zuletzt bearbeitet: