2015-11-05 158 views
1

我正尝试在Javafx中调整画布大小。我正在使用场景生成器和fxml。到目前为止,当用户点击画布时,画布会变黑,当我调整画面大小并单击画布时,画布的原始大小将变为黑色(画布未被调整大小)。我不知道如何解决这个问题。任何想法或解决方案都会有帮助。JavaFX在fxml中调整画布大小

代码:

控制器:

public class MainFXMLController implements Initializable 
{ 

    @FXML 
    private Canvas mainCanvas; 

    @FXML 

    public GraphicsContext gc; 

    public void initGraphics() 
    { 
     gc = mainCanvas.getGraphicsContext2D(); 
    } 

    public void drawClicked(MouseEvent me) 
    { 

     gc.clearRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight()); 
     gc.setFill(Color.BLACK); 
     gc.fillRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight()); 
     System.out.println("Current mosue position: " + me.getX() + ":" + me.getY()); 
    } 

    @Override 
    public void initialize(URL url, ResourceBundle rb) 
    { 
     initGraphics(); 

    } 
} 

FXML:

<AnchorPane id="AnchorPane" prefHeight="600.0" prefWidth="750.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.MainFXMLController"> 
<children> 
    <Canvas fx:id="mainCanvas" height="565.0" onMouseClicked="#drawClicked" width="750.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="35.0" /> 

主要的Java文件:

public class DrawFx extends Application 
{ 

    @Override 
    public void start(Stage stage) throws Exception 
    { 
     Parent root = FXMLLoader.load(getClass().getResource("MainFXML.fxml")); 

     Scene scene = new Scene(root); 
     stage.setTitle("DrawFx"); 
     stage.getIcons().add(new Image("/icon/icon.png")); 
     stage.setScene(scene); 
     stage.show(); 
    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) 
    { 
     launch(args); 
    } 

} 

回答

1

首先一些Javadoc中:)

画布节点被构造成具有宽度和高度,指定到其中的画布绘制命令被描绘的图像的大小。所有绘图操作都被剪切到该图像的边界。

因此,每次用户调整窗口大小时,都需要更改画布的宽度,然后我们需要重新绘制画布。

让我们开始在根布局中添加一个fx:id

<AnchorPane fx:id="anchorPane" prefHeight="600.0" prefWidth="750.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.MainFXMLController"> 
    <children> 
     <Canvas fx:id="mainCanvas" height="565.0" onMouseClicked="#drawClicked" width="750.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="35.0"/> 
    </children> 
</AnchorPane> 

下一步是改变监听器添加到根布局将设置新的高度和宽度,以在画布然后重绘。我们可以在控制器的initialize()内部完成。

public class Controller implements Initializable { 

    @FXML 
    AnchorPane anchorPane; 

    @FXML 
    private Canvas mainCanvas; 

    @FXML 
    public GraphicsContext gc; 

    public void initGraphics() { 
     gc = mainCanvas.getGraphicsContext2D(); 
    } 

    public void drawClicked() { 
     gc.clearRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight()); 
     gc.setFill(Color.BLACK); 
     gc.fillRect(0, 0, mainCanvas.getWidth(), mainCanvas.getHeight()); 
    } 

    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
     initGraphics(); 

     anchorPane.prefWidthProperty().addListener((ov, oldValue, newValue) -> { 
      mainCanvas.setWidth(newValue.doubleValue()); 
      drawClicked(); 
     }); 

     anchorPane.prefHeightProperty().addListener((ov, oldValue, newValue) -> { 
      mainCanvas.setHeight(newValue.doubleValue()); 
      drawClicked(); 
     }); 
    } 
} 

我没有因为你的drawClicked()什么也没做创造了reDraw()的新方法。但是,一旦更有意义,您可以将这两种方法分开。

最后一件事是分别将根布局的prefWidthProperty()prefHeightProperty()绑定到场景的宽度和高度。

public class Main extends Application { 
    public static void main(String[] args) { 
     launch(args); 
    } 
    @Override 
    public void start(Stage stage) throws IOException { 
     AnchorPane root = FXMLLoader.load(getClass().getResource("MainFXML.fxml")); 

     Scene scene = new Scene(root); 

     stage.setTitle("DrawFx"); 
     stage.setScene(scene); 
     stage.show(); 

     root.prefWidthProperty().bind(scene.widthProperty()); 
     root.prefHeightProperty().bind(scene.heightProperty()); 
    } 
} 
+0

非常感谢你的工作!不过,我想知道是否有可能在调用redraw()函数时将数据保存在画布上?因此,如果画布可以保留之前的图纸,而不是黑色填充 – parth2701

+0

您可以对原始画布执行相同的逻辑,但将所涉及的点缩放到新的大小。 – ItachiUchiha