2016-09-16 3 views
2

Also ich erstelle eine Karte in JavaFX und ich möchte die ganze Karte zu Zeiten sichtbar haben. Das Problem ist jedoch, dass nachdem ich die Bildansicht auf die Bildschirmgröße eingestellt habe und sie dann zum scrollPane hinzufüge, funktioniert meine Zoom-Funktion gut, aber sobald ich heranzoome, darf ich nicht um das Bild schwenken. Unten ist der Code, den ich geschrieben habe.JavaFX setFitHeight()/setFitWidth() für ein Bild innerhalb eines scrollPanees deaktiviert schwenken

package gameaspects; 

import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.ScrollPane; 
import javafx.scene.control.ScrollPane.ScrollBarPolicy; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.input.ScrollEvent; 
import javafx.scene.layout.AnchorPane; 
import javafx.stage.Stage; 

public class SourceCodeVersion8 extends Application{ 

final double SCALE_DELTA = 1.1; 
public double SCALE_TOTAL = 1; 

public static void main(String[] args) { 
    launch(args); 
} 

@Override 
public void start(Stage primaryStage) throws Exception { 
    AnchorPane mapAnchorO = addMapAnchor(); 
    Scene mapScene = new Scene(mapAnchorO); 
    primaryStage.setScene(mapScene); 
    primaryStage.setFullScreen(true); 
    primaryStage.setResizable(false); 
    primaryStage.show(); 
} 

//Creates an AnchorPane for the map 
private AnchorPane addMapAnchor() 
{ 
    AnchorPane mapAnchor = new AnchorPane(); 
    ScrollPane mapScrollO = addMapScroll(); 
    mapAnchor.getChildren().add(mapScrollO); 
    AnchorPane.setLeftAnchor(mapScrollO, 0.0); 
    AnchorPane.setTopAnchor(mapScrollO, 0.0); 
    AnchorPane.setBottomAnchor(mapScrollO, 0.0); 
    AnchorPane.setRightAnchor(mapScrollO, 0.0); 
    return mapAnchor; 
} 

//Creates an ImageView for the map 
private ImageView addMapView() 
{ 
    Image mapImage = new Image("WorldProvincialMap-v1.01.png"); 
    ImageView mapView = new ImageView(mapImage); 
    GraphicsDevice gd =    GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); 
    int width = gd.getDisplayMode().getWidth(); 
    int height = gd.getDisplayMode().getHeight(); 
    mapView.setFitHeight(height); 
    mapView.setFitWidth(width); 
    return mapView; 
} 

//Creates a scrollPane for the map 
private ScrollPane addMapScroll() 
{ 
    ScrollPane mapScroll = new ScrollPane(); 
    ImageView mapViewO = addMapView(); 
    mapScroll.setContent(mapViewO); 
    mapScroll.setPannable(true); 
    mapScroll.setVbarPolicy(ScrollBarPolicy.NEVER); 
    mapScroll.setHbarPolicy(ScrollBarPolicy.NEVER); 
    mapScroll.addEventFilter(ScrollEvent.ANY, e ->{ 
     e.consume(); 
     if(e.getDeltaY() == 0) 
     { 
      return; 
     } 
     double scaleFactor = 
        (e.getDeltaY() > 0) 
        ? SCALE_DELTA 
        : 1/SCALE_DELTA; 

     if(scaleFactor * SCALE_TOTAL >= 1) 
     { 
      mapScroll.setScaleX(mapScroll.getScaleX() * scaleFactor); 
      mapScroll.setScaleY(mapScroll.getScaleY() * scaleFactor); 
      SCALE_TOTAL *= scaleFactor; 
     } 
    }); 
    return mapScroll; 
    } 
} 
+0

Ich habe nicht getestet, aber ich denke, Ich würde in Erwägung ziehen, keinen Bildlaufbereich zu verwenden und stattdessen das Ansichtsfenster der Bildansicht als Reaktion auf Mausereignisse zu bearbeiten. Nicht klar, was aber einfacher ist. –

Antwort

4

Sie die Skalierung der ScrollPane anstelle des Inhalts. Auch wenn Sie die Werte ImageView, scaleX und scaleY skalieren, werden diese bei der Berechnung der Inhaltsgröße nicht berücksichtigt. Deshalb sollte die ImageView auch in einem Group gewickelt werden:

private ScrollPane addMapScroll() { 
    ScrollPane mapScroll = new ScrollPane(); 
    ImageView mapViewO = addMapView(); 
    mapScroll.setContent(new Group(mapViewO)); 
    mapScroll.setPannable(true); 
    mapScroll.setVbarPolicy(ScrollBarPolicy.NEVER); 
    mapScroll.setHbarPolicy(ScrollBarPolicy.NEVER); 
    mapScroll.addEventFilter(ScrollEvent.ANY, e -> { 
     e.consume(); 
     if (e.getDeltaY() == 0) { 
      return; 
     } 
     double scaleFactor 
       = (e.getDeltaY() > 0) 
         ? SCALE_DELTA 
         : 1/SCALE_DELTA; 

     if (scaleFactor * SCALE_TOTAL >= 1) { 
      mapViewO.setScaleX(mapViewO.getScaleX() * scaleFactor); 
      mapViewO.setScaleY(mapViewO.getScaleY() * scaleFactor); 
      SCALE_TOTAL *= scaleFactor; 
     } 
    }); 
    return mapScroll; 
} 

Um „die Mitte zu halten zentriert“ Sie er Positionen entsprechend bewegen anpassen müssen:

if (scaleFactor * SCALE_TOTAL >= 1) { 
    Bounds viewPort = mapScroll.getViewportBounds(); 
    Bounds contentSize = mapViewO.getBoundsInParent(); 

    double centerPosX = (contentSize.getWidth() - viewPort.getWidth()) * mapScroll.getHvalue() + viewPort.getWidth()/2; 
    double centerPosY = (contentSize.getHeight() - viewPort.getHeight()) * mapScroll.getVvalue() + viewPort.getHeight()/2; 

    mapViewO.setScaleX(mapViewO.getScaleX() * scaleFactor); 
    mapViewO.setScaleY(mapViewO.getScaleY() * scaleFactor); 
    SCALE_TOTAL *= scaleFactor; 

    double newCenterX = centerPosX * scaleFactor; 
    double newCenterY = centerPosY * scaleFactor; 

    mapScroll.setHvalue((newCenterX - viewPort.getWidth()/2)/(contentSize.getWidth() * scaleFactor - viewPort.getWidth())); 
    mapScroll.setVvalue((newCenterY - viewPort.getHeight()/2)/(contentSize.getHeight() * scaleFactor -viewPort.getHeight())); 
} 
+0

Ich habe diese Lösung verwendet. Jetzt, wenn ich heranzoomen, bewegt es sich in die obere linke Ecke. Gibt es eine Möglichkeit, es in der Mitte des Bildschirms einzoomen zu lassen? –

+0

@AdamRen Tatsächlich gibt es, aber Sie müssen die Scroll-Positionen neu berechnen. Siehe meine Bearbeitung. – fabian

1

Ich verbesserte Ihre Version mit einem mouseDragHandler.

Dies sollte die richtige Lösung für Ihr Problem sein!

package test; 

import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.ScrollPane; 
import javafx.scene.control.ScrollPane.ScrollBarPolicy; 
import javafx.scene.image.Image; 
import javafx.scene.image.ImageView; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.input.ScrollEvent; 
import javafx.scene.layout.AnchorPane; 
import javafx.stage.Stage; 

public class test extends Application { 

final double SCALE_DELTA = 1.1; 
public double SCALE_TOTAL = 1; 

public double dragDeltay; 
public double dragDeltax; 


public static void main(String[] args) { 
    launch(args); 
} 

@Override 
public void start(Stage primaryStage) throws Exception { 
    AnchorPane mapAnchorO = addMapAnchor(); 
    Scene mapScene = new Scene(mapAnchorO); 
    primaryStage.setScene(mapScene); 
    primaryStage.setFullScreen(true); 
    primaryStage.setResizable(false); 
    primaryStage.show(); 
} 

// Creates an AnchorPane for the map 
private AnchorPane addMapAnchor() { 
    AnchorPane mapAnchor = new AnchorPane(); 
    ScrollPane mapScrollO = addMapScroll(); 
    mapAnchor.getChildren().add(mapScrollO); 
    AnchorPane.setLeftAnchor(mapScrollO, 0.0); 
    AnchorPane.setTopAnchor(mapScrollO, 0.0); 
    AnchorPane.setBottomAnchor(mapScrollO, 0.0); 
    AnchorPane.setRightAnchor(mapScrollO, 0.0); 
    return mapAnchor; 
} 

// Creates an ImageView for the map 
private ImageView addMapView() { 
    Image mapImage = new Image("WorldProvincialMap-v1.01.png"); 
    ImageView mapView = new ImageView(mapImage); 
    GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); 
    int width = gd.getDisplayMode().getWidth(); 
    int height = gd.getDisplayMode().getHeight(); 
    mapView.setFitHeight(height); 
    mapView.setFitWidth(width); 
    return mapView; 
} 

// Creates a scrollPane for the map 
private ScrollPane addMapScroll() { 
    ScrollPane mapScroll = new ScrollPane(); 
    ImageView mapViewO = addMapView(); 
    mapScroll.setContent(mapViewO); 

    mapViewO.setOnMousePressed(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
      dragDeltax = mapViewO.getX() - mouseEvent.getScreenX(); 
      dragDeltay = mapViewO.getY() - mouseEvent.getScreenY(); 
     } 
    }); 

    mapViewO.setOnMouseDragged(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
      mapScroll.setTranslateX(mouseEvent.getScreenX() + dragDeltax); 
      mapScroll.setTranslateY(mouseEvent.getScreenY() + dragDeltay); 
     } 
    }); 

    mapScroll.setVbarPolicy(ScrollBarPolicy.NEVER); 
    mapScroll.setHbarPolicy(ScrollBarPolicy.NEVER); 
    mapScroll.addEventFilter(ScrollEvent.ANY, e -> { 
     e.consume(); 
     if (e.getDeltaY() == 0) { 
      return; 
     } 
     double scaleFactor = (e.getDeltaY() > 0) ? SCALE_DELTA : 1/SCALE_DELTA; 

     if (scaleFactor * SCALE_TOTAL >= 1) { 
      mapScroll.setScaleX(mapScroll.getScaleX() * scaleFactor); 
      mapScroll.setScaleY(mapScroll.getScaleY() * scaleFactor); 
      SCALE_TOTAL *= scaleFactor; 
     } 
    }); 

    return mapScroll; 
} 

} 
+0

Dies behebt das Problem beim Verschieben, führt aber das Problem ein, das ich außerhalb der Karte sehen kann. Hast du eine Lösung dafür? –

Verwandte Themen