2017-01-16 20 views
1

以下はMain.classController.classです。できるだけ簡単にしようとしました。StackFane内でJavaFX Canvasが正しくサイズ変更されない

プログラムは、以下の画面を出力: enter image description here


ブラックStackPane命名visualizerStackPaneであり、それはCanvas名前visualizerCanvasで内部。 StackPane内のCanvasは、StackPaneサイズ引数4に応じてリサイズされます。ウィンドウのサイズを変更するとすべてが失敗します。あなたは試してみてどのような

...

1)は、ウィンドウを最大化し、その後、戻ってそれを正規化します。

2)ウィンドウのサイズを大きくし、ゆっくりと戻します。

これが起こっているのはなぜ?私は今、3ヶ月、この問題を持っていると私は解決策を見つけることができません...

...私は JavaFX - Resize Canvas when screen is resizedをも見てきましたが、ここで問題が異なるように思えます

Main.java:

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class Main extends Application { 
    @Override 
    public void start(Stage primaryStage) { 
     try { 

      //Scene 
      Scene scene = new Scene(new Controller(), 400, 400); 
      primaryStage.setScene(scene); 

      //Show 
      primaryStage.show(); 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

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

Controller.java:私はキャンバスをペイントするコントローラクラスを変更し、Initialize方法からバインディングを削除した

、それは動作しません、それは以下の生成:

enter image description here

場合、私手動でCanvasの幅と高さを設定しないでください。塗りつぶされません。理由はわかりません。

import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

import javafx.fxml.FXML; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 

public class Controller extends StackPane { 

    @FXML 
    private GridPane container; 

    @FXML 
    private GridPane topGridPane; 

    @FXML 
    private StackPane visualizerStackPane; 

    @FXML 
    private Canvas visualizerCanvas; 

    @FXML 
    private VBox topRightVBox; 

    @FXML 
    private StackPane mediaFileStackPane; 

    @FXML 
    private GridPane bottomGridPane; 

    // ------------------------------ 

    GraphicsContext gc; 
    int    canvasWidth  = 0; 
    int    canvasHeight = 0; 

    /** 
    * Constructor 
    */ 
    public Controller() { 

     // ------------------------FXMLLoader --------------------------------- 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("Controller.fxml")); 
     loader.setController(this); 
     loader.setRoot(this); 

     try { 
      loader.load(); 
     } catch (IOException ex) { 
      Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Controller FXML can't be loaded!", ex); 
     } 
    } 

    /** 
    * Called as soon as FXML FILE has been loaded 
    */ 
    @FXML 
    private void initialize() { 

     gc = visualizerCanvas.getGraphicsContext2D(); 

     // // VisualizerStackPane inside which visualizerCanvas is 
     // visualizerCanvas.widthProperty().bind(visualizerStackPane.widthProperty().subtract(4)); 
     // visualizerCanvas.heightProperty().bind(visualizerStackPane.heightProperty().subtract(4)); 
     // 

     // Add width and height change listeners 
     visualizerStackPane.widthProperty().addListener((observable, oldValue, 
       newValue) -> resizeVisualizerCanvas(newValue.doubleValue(), visualizerStackPane.getHeight())); 

     visualizerStackPane.heightProperty().addListener((observable, oldValue, 
       newValue) -> resizeVisualizerCanvas(visualizerStackPane.getWidth(), newValue.doubleValue()) 

     ); 

     repaintCanvas(); 
    } 

    /** 
    * Repaints the Canvas 
    */ 
    public void repaintCanvas() { 

     //Clear the previous rectangle 
     gc.clearRect(0, 0, canvasWidth, canvasHeight); 

     // Draw the 
     gc.setFill(Color.RED); 
     gc.fillRect(0, 0, canvasWidth, canvasHeight); 

     // Draw the Line 
     gc.setLineWidth(3); 
     gc.setStroke(Color.WHITE); 
     gc.strokeLine(0, canvasHeight, canvasWidth, 0); 

    } 

    /** 
    * Resizes the visualizerCanvas to the given values. 
    * 
    * @param width 
    *   the width 
    * @param height 
    *   the height 
    */ 
    public void resizeVisualizerCanvas(double width, double height) { 
     if (width > 0 && height > 0) { 

      this.canvasWidth = (int) width; 
      this.canvasHeight = (int) height; 

      // Print something 
      System.out.println("Canvas Width is:" + width+" , Canvas Height is:"+height +" Canvas is Resizable: "+visualizerCanvas.isResizable()); 

      // Repaint the Canvas 
      repaintCanvas(); 

      // ---------------------------Below i have tried several things to 
      // solve the problem.... 

      // Set the width and height of Canvas 
      visualizerCanvas.setWidth(width); 
      visualizerCanvas.setHeight(height); 

      // Careful with contentBias here 
      prefWidth(-1); 
      prefHeight(-1); 

      // autosize() 

      // System.out.println("Content Bias is:"+this.getContentBias()) 

     } 
    } 
} 

Controller.fxml:最後に

<?xml version="1.0" encoding="UTF-8"?> 

<?import javafx.geometry.Insets?> 
<?import javafx.scene.canvas.Canvas?> 
<?import javafx.scene.control.Label?> 
<?import javafx.scene.layout.ColumnConstraints?> 
<?import javafx.scene.layout.GridPane?> 
<?import javafx.scene.layout.Region?> 
<?import javafx.scene.layout.RowConstraints?> 
<?import javafx.scene.layout.StackPane?> 
<?import javafx.scene.layout.VBox?> 

<fx:root prefHeight="212.0" prefWidth="456.0" type="StackPane" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"> 
    <padding> 
     <Insets bottom="2.0" left="2.0" right="2.0" top="2.0" /> 
    </padding> 
    <children> 
     <GridPane fx:id="container"> 
     <columnConstraints> 
      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="50.0" prefWidth="100.0" /> 
      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="50.0" prefWidth="100.0" /> 
     </columnConstraints> 
     <rowConstraints> 
      <RowConstraints minHeight="10.0" percentHeight="40.0" vgrow="SOMETIMES" /> 
      <RowConstraints minHeight="10.0" percentHeight="60.0" vgrow="SOMETIMES" /> 
     </rowConstraints> 
     <children> 
      <GridPane fx:id="topGridPane" gridLinesVisible="true" GridPane.columnSpan="2"> 
       <columnConstraints> 
       <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="50.0" prefWidth="100.0" /> 
       <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="50.0" prefWidth="100.0" /> 
       </columnConstraints> 
       <rowConstraints> 
       <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> 
       </rowConstraints> 
       <children> 
        <StackPane fx:id="visualizerStackPane" style="-fx-border-color: white; -fx-border-width: 1.5; -fx-background-color: rgb(0,0,0,0.95);"> 
        <children> 
         <Canvas fx:id="visualizerCanvas" /> 
        </children> 
        </StackPane> 
        <VBox fx:id="topRightVBox" GridPane.columnIndex="1"> 
        <children> 
         <StackPane prefHeight="150.0" prefWidth="200.0"> 
          <children> 
           <Region style="-fx-background-color: rgb(255,255,255,0.7);" /> 
           <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-font-weight: bold;" text="text here" /> 
          </children> 
         </StackPane> 
         <StackPane fx:id="mediaFileStackPane" maxWidth="1.7976931348623157E308" /> 
        </children> 
        </VBox> 
       </children> 
      </GridPane> 
      <GridPane fx:id="bottomGridPane" gridLinesVisible="true" GridPane.columnSpan="2" GridPane.rowIndex="1"> 
       <columnConstraints> 
       <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="20.0" prefWidth="35.0" /> 
       <ColumnConstraints halignment="CENTER" hgrow="SOMETIMES" minWidth="10.0" percentWidth="60.0" prefWidth="343.0" /> 
        <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="20.0" prefWidth="52.0" /> 
       </columnConstraints> 
       <rowConstraints> 
       <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> 
       </rowConstraints> 
       <children> 
        <StackPane prefHeight="150.0" prefWidth="200.0" GridPane.columnIndex="2"> 
        <children> 
         <Region style="-fx-background-color: rgb(255,255,255,0.7);" /> 
         <Label alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" style="-fx-font-weight: bold;" text="text here" textAlignment="CENTER" wrapText="true" StackPane.alignment="CENTER" /> 
        </children> 
        </StackPane> 
        <VBox prefHeight="200.0" prefWidth="100.0" spacing="5.0" /> 
       </children> 
      </GridPane> 
     </children> 
     </GridPane> 
    </children> 
</fx:root> 

:番目を解決するために管理します人に

大感謝問題です:)。

+0

あなた '初期化()'メソッドからのすべての行を削除します。 StackPaneの機能を妨げているレイアウト操作を自分自身で制御しようとしています。代わりに、StackPaneの幅を2に設定したり、StackPaneのパディングをすべての面で0.5に設定したり、すべての面でCanvasのStackPane.marginを0.5に設定したりすることができます。 – VGR

+0

@VGR次に、キャンバスの幅と高さを取得する方法は?キャンバスは自動サイズ変更されますか? ChangeListenerを 'Canvas'の' widthProperty'と 'heightProperty'に追加するときはいつでも' -1'を取得しています。私はあなたの助けに感謝しています... :) – GOXR3PLUS

+0

StackPaneは既に、各子をStackPaneのコンテンツサイズ(StackPaneのサイズからその挿入を引いたもの)にサイズ変更しています。何もする必要はありません。 – VGR

答えて

1

研究の後、私は解決策を見つけました。私のアイデアを与えたHow to make canvas Resizable in javaFX?

リンク:http://dlsc.com/2014/04/10/javafx-tip-1-resizable-canvas/


カスタムにCanvasからCanvasクラスと@Overridingメソッドの作成:この質問への最終的な答えから


を非常に喜んでResizableCavas.java:

import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.paint.Color; 

class ResizableCanvas extends Canvas { 

    GraphicsContext gc     = getGraphicsContext2D(); 
    int    canvasWidth   = 0; 
    int    canvasHeight  = 0; 
    int    halfCanvasHeight = 0; 

    /** 
    * Constructor 
    */ 
    public ResizableCanvas() { 

     // if i didn't add the draw to the @Override resize(double width, double 
     // height) then it must be into the below listeners 

     // Redraw canvas when size changes. 
     widthProperty().addListener((observable, oldValue, newValue) -> { 
      System.out.println("Entered WIDTH property"); 
      canvasWidth = (int) widthProperty().get(); 
     }); 
     heightProperty().addListener((observable, oldValue, newValue) -> { 
      System.out.println("Entered HEIGHT property"); 

      canvasHeight = (int) heightProperty().get(); 
      halfCanvasHeight = canvasHeight >> 1; 
     }); 

    } 

    /** 
    * Redraw the Canvas 
    */ 
    private void draw() { 

     System.out.println(" Real Canvas Width is:" + getWidth() + " , Real Canvas Height is:" + getHeight() + "\n"); 

     gc.clearRect(0, 0, canvasWidth, canvasHeight); 

     gc.setStroke(Color.RED); 
     gc.strokeLine(0, 0, canvasWidth, canvasHeight); 
     gc.strokeLine(0, canvasHeight, canvasWidth, 0); 
    } 

    @Override 
    public double minHeight(double width) { 
     return 1; 
    } 

    @Override 
    public double maxHeight(double width) { 
     return Double.MAX_VALUE; 
    } 

    @Override 
    public double prefHeight(double width) { 
     return minHeight(width); 
    } 

    @Override 
    public double minWidth(double height) { 
     return 1; 
    } 

    @Override 
    public double maxWidth(double height) { 
     return Double.MAX_VALUE; 
    } 

    @Override 
    public boolean isResizable() { 
     return true; 
    } 

    @Override 
    public void resize(double width, double height) { 
     super.setWidth(width); 
     super.setHeight(height); 
     draw(); 
    } 
} 

Controller.java:

import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

import javafx.beans.property.SimpleIntegerProperty; 
import javafx.fxml.FXML; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.canvas.Canvas; 
import javafx.scene.canvas.GraphicsContext; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.VBox; 
import javafx.scene.paint.Color; 

public class Controller extends StackPane { 

    @FXML 
    private GridPane container; 

    @FXML 
    private GridPane topGridPane; 

    @FXML 
    private StackPane visualizerStackPane; 

    @FXML 
    private VBox topRightVBox; 

    @FXML 
    private StackPane mediaFileStackPane; 

    @FXML 
    private GridPane bottomGridPane; 

    // ------------------------------ 

    ResizableCanvas visualizerCanvas = new ResizableCanvas(); 

    /** 
    * Constructor 
    */ 
    public Controller() { 

     // ------------------------FXMLLoader --------------------------------- 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("Controller.fxml")); 
     loader.setController(this); 
     loader.setRoot(this); 

     try { 
      loader.load(); 
     } catch (IOException ex) { 
      Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Controller FXML can't be loaded!", ex); 
     } 
    } 

    /** 
    * Called as soon as FXML FILE has been loaded 
    */ 
    @FXML 
    private void initialize() { 

     visualizerStackPane.getChildren().add(visualizerCanvas); 

    } 
} 
1

initialize()メソッドからバインディングを削除します。 StackPaneは、自分が行っていることをやめて、レイアウト操作を自分自身で制御しようとしています。これにより、Canvasのサイズが適切に変更されます。

Canvaswidthheightを印刷すると-1と返されます。これを行う代わりに、容器StackPanewidthheightを印刷します。結局、Canvasが完全にStackPaneに含まれているので、widthheightは、同一でない場合もほとんど同じです。

+0

Hello Michael私はコードを修正しました。私は 'Controller.java'をバインディングを持たないように変更し、' Canvas'の幅を変更しないようにしましたが、paintされません。幅と高さを変更するとあなたが2番目のイメージで見ることができるように 'キャンバス'の塗りつぶし:)助けてくれてありがとう... – GOXR3PLUS

+0

あなたの幅と高さのプロパティリスナーでresizeVisualizerコールを取り出してください。 –

+0

バインディングを使わずに 'canvasWidth'と' canvasHeight'をCanvasの 'width'と' height'にバインドする方法が必要です。パフォーマンス上の理由から、私は 'Canvas'でアニメーションを描画しています。 – GOXR3PLUS

関連する問題