2016-09-19 5 views
0

Ich versuche, ein SVG-Bild in einem Button in einem JavaFX-Programm zu verwenden. Ich verwende ein Programm von question I asked a while back, um das SVG-Bild unter Verwendung SVGPath zu laden.SVGPath wird nicht korrekt skaliert in Button

import javafx.application.Application; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.HBox; 
import javafx.scene.shape.SVGPath; 
import javafx.stage.Stage; 

public class TestSVGPath2 extends Application { 

    private final static String OLD_SVG = "M87.5,50.002C87.5,29.293,70.712,12.5,50,12.5c-20.712,0-37.5,16.793-37.5,37.502C12.5,70.712,29.288,87.5,50,87.5" 
      + "c6.668,0,12.918-1.756,18.342-4.809c0.61-0.22,1.049-0.799,1.049-1.486c0-0.622-0.361-1.153-0.882-1.413l0.003-0.004l-6.529-4.002" 
      + "L61.98,75.79c-0.274-0.227-0.621-0.369-1.005-0.369c-0.238,0-0.461,0.056-0.663,0.149l-0.014-0.012" 
      + "C57.115,76.847,53.64,77.561,50,77.561c-15.199,0-27.56-12.362-27.56-27.559c0-15.195,12.362-27.562,27.56-27.562" 
      + "c14.322,0,26.121,10.984,27.434,24.967C77.428,57.419,73.059,63,69.631,63c-1.847,0-3.254-1.23-3.254-3.957" 
      + "c0-0.527,0.176-1.672,0.264-2.111l4.163-19.918l-0.018,0c0.012-0.071,0.042-0.136,0.042-0.21c0-0.734-0.596-1.33-1.33-1.33h-7.23" 
      + "c-0.657,0-1.178,0.485-1.286,1.112l-0.025-0.001l-0.737,3.549c-1.847-3.342-5.629-5.893-10.994-5.893" 
      + "c-10.202,0-19.877,9.764-19.877,21.549c0,8.531,5.101,14.775,13.632,14.775c4.75,0,9.587-2.727,12.665-7.035l0.088,0.527" 
      + "c0.615,3.342,9.843,7.576,15.121,7.576c7.651,0,16.617-5.156,16.617-19.932l-0.022-0.009C87.477,51.13,87.5,50.569,87.5,50.002z" 
      + "M56.615,56.844c-1.935,2.727-5.101,5.805-9.763,5.805c-4.486,0-7.212-3.166-7.212-7.738c0-6.422,5.013-12.754,12.049-12.754" 
      + "c3.958,0,6.245,2.551,7.124,4.486L56.615,56.844z"; 
    private final static String NEW_SVG = "M10,304v26.8h190.8V304H10z M227.8,304v26.8h271.8c0,0-27.8-26.8-64.5-26.8H227.8z M552.9,304v26.8h164.5l-9.8-26.8H552.9z M835.3,304l-9.8,26.8h163V304H835.3z M10,356.2V383h190.8v-26.8H10z M227.8,356.2V383h303.4c0,0-3.5-20.6-9.7-26.8H227.8z M552.9,356.2V383h182.5l-9-26.8H552.9z M815.8,356.2l-9,26.8h181.8v-26.8H815.8z M64.8,408.3v26.9h82.6v-26.9H64.8z M282.6,408.3v26.9h82.6v-26.9H282.6z M445.6,408.3v26.9h82.6c0,0,5.2-14.2,5.2-26.9H445.6z M607.8,408.3v26.9h146.5l-9.8-26.9H607.8z M797.8,408.3l-9.8,26.9h147.2v-26.9H797.8z M64.8,460.5v26.8h82.6v-26.8H64.8z M282.6,460.5v26.8h211c0,0,17.7-13.8,23.3-26.8H282.6z M607.8,460.5v26.8h82.6v-14.9l5.2,14.9h151.3l5.6-14.9v14.9h82.6v-26.8H780.1l-8.2,22.7l-8.3-22.7H607.8z M64.8,512.7v26.8h82.6v-26.8H64.8z M282.6,512.7v26.8h234.3c-5.6-13-23.3-26.8-23.3-26.8H282.6z M607.8,512.7v26.8h82.6v-26.8H607.8z M705.4,512.7l10,26.8h113.5l9.5-26.8H705.4z M852.6,512.7v26.8h82.6v-26.8H852.6z M64.8,564.8v26.8h82.6v-26.8H64.8z M282.6,564.8v26.8h82.6v-26.8H282.6z M445.6,564.8v26.8h87.9c0-12.7-5.2-26.8-5.2-26.8H445.6z M607.8,564.8v26.8h82.6v-26.8H607.8z M724.1,564.8l9.7,26.8h76.1l9.8-26.8H724.1z M852.6,564.8v26.8h82.6v-26.8H852.6z M11.5,617v26.9h190.8V617H11.5z M227.8,617v26.9h293.7c6.2-6.1,9.7-26.9,9.7-26.9H227.8z M554.4,617v26.9h135.9V617H554.4z M742.9,617l10,26.9h38.7l9.3-26.9H742.9z M852.6,617v26.9H990V617H852.6z M11.5,669.2V696h190.8v-26.8H11.5z M227.8,669.2V696h207.3c36.8,0,64.5-26.8,64.5-26.8H227.8z M554.4,669.2V696h135.9v-26.8H554.4z M761.8,669.2l9.6,26.7l1.6,0l9.7-26.8H761.8z M852.6,669.2V696H990v-26.8H852.6z"; 

    private final int MIN_BUTTON_SIZE = 10; 

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

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     HBox root = new HBox(); 
     root.setAlignment(Pos.CENTER); 
     SVGPath svg = new SVGPath(); 

     // Old image works fine. 
     // svg.setContent(OLD_SVG); 

     // New image does not. 
     svg.setContent(NEW_SVG); 

     Button buttonWithGraphics = new Button(); 
     buttonWithGraphics.setGraphic(svg); 
     buttonWithGraphics.setPrefSize(100, 50); 

     // Bind the Image scale property to the buttons size 
     svg.scaleXProperty().bind(buttonWithGraphics.widthProperty().divide(100)); 
     svg.scaleYProperty().bind(buttonWithGraphics.heightProperty().divide(100)); 

     // Declare a minimum size for the button 
     buttonWithGraphics.setMinSize(MIN_BUTTON_SIZE, MIN_BUTTON_SIZE); 

     root.getChildren().addAll(buttonWithGraphics); 
     root.layoutBoundsProperty().addListener((observableValue, oldBounds, newBounds) -> { 
      double size = Math.max(MIN_BUTTON_SIZE, Math.min(newBounds.getWidth(), newBounds.getHeight())); 
      buttonWithGraphics.setPrefSize(size, size); 
     }); 

     Scene scene = new Scene(root); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 
} 

Problem ist, dass während der SVG Bild, das ich in dieser Frage mit den verwendeten Button Größe verändert wurde, mein neues Bild nicht. Es wird angezeigt, es wird nur nicht in der Größe geändert.

Wenn ich den SVG-Pfad in JSFiddle testen, wird das Bild überhaupt nicht angezeigt. Wenn ich stattdessen den Pfad aus dem SVG-Bild verwende, das ich in meiner alten Frage verwendet habe, wird das angezeigt. Ich weiß nicht, was ich von dieser Tatsache halten soll, denn wie gesagt: In meinem JavaFX-Programm wird das Bild angezeigt, es wird einfach nicht mit der Button skaliert.

Warum ist die SVGPath nicht korrekt skaliert und warum wird sie nicht in JSFiddle angezeigt, wenn sie in einem JavaFX-Programm angezeigt werden kann?

Antwort

1

Ihr SVG ist einfach zu groß, um mit diesen Faktoren angemessen skaliert zu werden.

So etwas wie

svg.scaleXProperty().bind(buttonWithGraphics.widthProperty().multiply(0.0005)); 
svg.scaleYProperty().bind(buttonWithGraphics.heightProperty().multiply(0.0005)); 

funktionieren sollte.


Alternativ können Sie den Skalierungsfaktor bestimmen auf der Größe des svg anhand der Größe in Bezug auf die Button zu machen. Der folgende Code bewahrt auch das Verhältnis der Seiten:

DoubleBinding scaleFactor = Bindings.createDoubleBinding(() -> { 
    Bounds bounds = svg.getBoundsInLocal(); 
    double sx = buttonWithGraphics.getWidth()/bounds.getWidth(); 
    double sy = buttonWithGraphics.getHeight()/bounds.getHeight(); 
    return 0.8 * Math.min(sx, sy); // make svg 80% of the button in the "more restrictive" direction 
}, svg.boundsInLocalProperty(), buttonWithGraphics.widthProperty(), buttonWithGraphics.heightProperty()); 

svg.scaleXProperty().bind(scaleFactor); 
svg.scaleYProperty().bind(scaleFactor); 

Wenn ich den SVG-Pfad in JSFiddle Test wird das Bild nicht angezeigt bekommen.

Das ist, weil das Element <svg> zu klein ist. Außerdem schließen Sie das Tag <svg> zweimal im JSFiddle. Versuchen Sie, mit <svg width=1000 height=1000>

<svg height=1000 width=1000> 
 
    <path d="M10,304v26.8h190.8V304H10z M227.8,304v26.8h271.8c0,0-27.8-26.8-64.5-26.8H227.8z M552.9,304v26.8h164.5l-9.8-26.8H552.9z M835.3,304l-9.8,26.8h163V304H835.3z M10,356.2V383h190.8v-26.8H10z M227.8,356.2V383h303.4c0,0-3.5-20.6-9.7-26.8H227.8z M552.9,356.2V383h182.5l-9-26.8H552.9z M815.8,356.2l-9,26.8h181.8v-26.8H815.8z M64.8,408.3v26.9h82.6v-26.9H64.8z M282.6,408.3v26.9h82.6v-26.9H282.6z M445.6,408.3v26.9h82.6c0,0,5.2-14.2,5.2-26.9H445.6z M607.8,408.3v26.9h146.5l-9.8-26.9H607.8z M797.8,408.3l-9.8,26.9h147.2v-26.9H797.8z M64.8,460.5v26.8h82.6v-26.8H64.8z M282.6,460.5v26.8h211c0,0,17.7-13.8,23.3-26.8H282.6z M607.8,460.5v26.8h82.6v-14.9l5.2,14.9h151.3l5.6-14.9v14.9h82.6v-26.8H780.1l-8.2,22.7l-8.3-22.7H607.8z M64.8,512.7v26.8h82.6v-26.8H64.8z M282.6,512.7v26.8h234.3c-5.6-13-23.3-26.8-23.3-26.8H282.6z M607.8,512.7v26.8h82.6v-26.8H607.8z M705.4,512.7l10,26.8h113.5l9.5-26.8H705.4z M852.6,512.7v26.8h82.6v-26.8H852.6z M64.8,564.8v26.8h82.6v-26.8H64.8z M282.6,564.8v26.8h82.6v-26.8H282.6z M445.6,564.8v26.8h87.9c0-12.7-5.2-26.8-5.2-26.8H445.6z M607.8,564.8v26.8h82.6v-26.8H607.8z M724.1,564.8l9.7,26.8h76.1l9.8-26.8H724.1z M852.6,564.8v26.8h82.6v-26.8H852.6z M11.5,617v26.9h190.8V617H11.5z M227.8,617v26.9h293.7c6.2-6.1,9.7-26.9,9.7-26.9H227.8z M554.4,617v26.9h135.9V617H554.4z M742.9,617l10,26.9h38.7l9.3-26.9H742.9z M852.6,617v26.9H990V617H852.6z M11.5,669.2V696h190.8v-26.8H11.5z M227.8,669.2V696h207.3c36.8,0,64.5-26.8,64.5-26.8H227.8z M554.4,669.2V696h135.9v-26.8H554.4z M761.8,669.2l9.6,26.7l1.6,0l9.7-26.8H761.8z M852.6,669.2V696H990v-26.8H852.6z" /> 
 
</svg>

+0

Diese Antwort auf die Frage, danke! Ich bin mir nicht sicher, ob ich eine neue Frage für diese nächste Frage erstellen soll, aber ich werde jetzt weitermachen und sie jetzt fragen: Ist es möglich, den 'SVGPath' auf einen festen Wert zu setzen? Größe? In meinem Fall möchte ich einen 'Button' mit etwas Text sowie einen' SVGPath' als Grafik der Schaltfläche verwenden. Und wenn ich nur einen Text in meinem aktuellen Code hinzufüge, ergeben sich seltsame Ergebnisse. Ich habe auch versucht, den 'SVGPath' in HBox zu setzen und dann die Größe davon einzustellen, aber es scheint nicht zu funktionieren. –

+0

@ JonatanStenbacka Transformationen wie Skalieren, Verschieben und Drehen werden von vielen Knotentypen, die einen Knoten als Nachfolger hinzufügen, nicht berücksichtigt. Das 'SVGPath' in eine' Group' zu wickeln, aber trotzdem die Skalierung auf 'SVGPath' anzuwenden, sollte wahrscheinlich funktionieren. – fabian

+0

@ JonatanStenbacka BTW: Um eine feste Größe zu erhalten, geben Sie bei den Berechnungen des Skalierungsfaktors einfach nicht die Größe der Schaltfläche an. Ersetzen Sie es durch die gewünschte Größe ... – fabian

Verwandte Themen