2015-11-05 8 views
1

Я пытаюсь изменить размер холста в Javafx. Я использую конструктор сцен и fxml. Пока пользователь нажимает на холст, холст становится черным, и когда я изменяю размер экрана и нажимаю на холст, только оригинальный размер холста становится черным (холст не изменяется). Я не знаю, как это решить. Любые идеи или решения помогут много.JavaFX resize canvas in 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

-первых, некоторые Javadocs :)

Узел Холст построен с шириной и высотой, которая определяет размер изображения, в котором предоставляются команды рисования холст. Все операции рисования привязаны к границам этого изображения.

Таким образом, каждый раз, когда пользователь меняет размер окна, нам нужно изменить ширину холста, а затем нам нужно повторно рисовать холст.

Давайте начнем с добавления 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(); 
     }); 
    } 
} 

Я не создал новый метод reDraw() с момента drawClicked() не делает ничего. Но вы можете разделить оба метода, когда это имеет смысл.

Последнее, что нужно связать с корневым макетом 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