如何在JavaFX中将元素分离到类中?

问题描述 投票:0回答:1

我使用 JavaFX 开发了一个相对简单的应用程序,除了允许用户操纵该对象之外,还能够在用户每次按下按钮时向界面添加圆形形状。

我需要将程序分成类,所以我考虑为圆圈创建一个类,但我不知道该怎么做。你能帮我吗?

这是我的 AddCircleApp.java:

package addcircleapp;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class AddCircleApp extends Application {
    
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
        
        Scene scene = new Scene(root);
        
        stage.setScene(scene);
        stage.setTitle("Interacting with Objects");
        stage.show();
    }

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

这是我的 FXMLDocumentController.java:

package addcircleapp;

import java.net.URL;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Slider;
import javafx.scene.input.*;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Circle;
import javafx.util.Pair;

public class FXMLDocumentController implements Initializable {

    @FXML
    private Pane containerPane;

    @FXML
    private Button addCircleButton;

    @FXML
    private Button editButton;

    @FXML
    private Button deleteButton;

    @FXML
    private ColorPicker colorPicker;

    @FXML
    private Slider sizeSlider;

    @FXML
    private Label colorSelectLabel;

    @FXML
    private Label sizeSelectLabel;

    private List<Circle> circles = new ArrayList<>();
    private Circle selectedCircle = null;
    private double xOffset = 0;
    private double yOffset = 0;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
        sizeSelectLabel.setText("Size: " + String.valueOf(sizeSlider.getValue()));

        sizeSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            sizeSelectLabel.setText("Size: " + String.valueOf(newValue.intValue()));
        });
    }

    public void handleAddCircleButton() {

        Random rand = new Random();
        int x = rand.nextInt(500);
        int y = rand.nextInt(200);

        Color selectedColor = colorPicker.getValue();
        double selectedSize = sizeSlider.getValue();

        Circle circle = new Circle(x, y, selectedSize, selectedColor);

        circle.setOnMouseClicked((MouseEvent e) -> {
            handleCircleClick(circle);
        });

        circle.setOnKeyPressed((KeyEvent e) -> {
            handleCircleMovement(e, circle);
        });

        circle.setOnMousePressed((MouseEvent e) -> {
            handleCircleDragStart(e, circle);
        });

        circle.setOnMouseDragged((MouseEvent e) -> {
            handleCircleDrag(e, circle);
        });

        circle.setOnMouseReleased((MouseEvent e) -> {
            handleCircleDragEnd(e, circle);
        });

        circles.add(circle);
        containerPane.getChildren().add(circle);

        System.out.println("New circle was created!");
    }

    public void handleEditButton() {
        if (selectedCircle != null) {
            Dialog<Pair<Color, Double>> editDialog = new Dialog<>();
            editDialog.setTitle("Edit Circle");
            editDialog.setHeaderText("Edit the color and size of the selected circle.");

            ButtonType confirmButton = new ButtonType("OK", ButtonData.OK_DONE);
            editDialog.getDialogPane().getButtonTypes().addAll(confirmButton, ButtonType.CANCEL);

            ColorPicker colorPicker = new ColorPicker((Color) selectedCircle.getFill());
            Slider sizeSlider = new Slider(10, 100, selectedCircle.getRadius());

            VBox vbox = new VBox(10);
            Label colorLabel = new Label("Color:");
            Label sizeLabel = new Label("Size:");

            sizeLabel.setText("Size: " + String.valueOf((int) sizeSlider.getValue()));

            sizeSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
                sizeLabel.setText("Size: " + String.valueOf((int) sizeSlider.getValue()));
            });

            vbox.getChildren().addAll(colorLabel, colorPicker, sizeLabel, sizeSlider);

            editDialog.getDialogPane().setContent(vbox);

            editDialog.setResultConverter((ButtonType dialogButton) -> {
                if (dialogButton == confirmButton) {
                    return new Pair<>(colorPicker.getValue(), sizeSlider.getValue());
                }
                return null;
            });

            Optional<Pair<Color, Double>> result = editDialog.showAndWait();

            result.ifPresent(newValues -> {
                selectedCircle.setFill(newValues.getKey());
                selectedCircle.setRadius(newValues.getValue());
            });
        }
    }

    public void handleDeleteButton(ActionEvent event) {
        if (selectedCircle != null) {
            circles.remove(selectedCircle);
            containerPane.getChildren().remove(selectedCircle);
            selectedCircle = null;
        }
    }

    private void handleCircleClick(Circle clickedCircle) {
        if (selectedCircle != null) {
            selectedCircle.setStroke(Color.TRANSPARENT);
        }

        selectedCircle = clickedCircle;
        Color fillColor = (Color) selectedCircle.getFill();
        Color complementary = Color.color(1.0 - fillColor.getRed(), 1.0 - fillColor.getBlue(), 1.0 - fillColor.getGreen());

        selectedCircle.setStroke(complementary);
        selectedCircle.setStrokeWidth(2.0);

        selectedCircle.requestFocus();
    }

    public void handleContainerPaneClick(MouseEvent event) {
        if (selectedCircle != null && !selectedCircle.contains(event.getX(), event.getY())) {
            selectedCircle.setStroke(Color.TRANSPARENT);
            selectedCircle = null;
        }
    }

    private void handleCircleMovement(KeyEvent event, Circle circle) {
        if (selectedCircle != null && null != event.getCode()) {
            switch (event.getCode()) {
                case LEFT:
                    circle.setCenterX(circle.getCenterX() - 10);
                    event.consume();
                    break;
                case RIGHT:
                    circle.setCenterX(circle.getCenterX() + 10);
                    event.consume();
                    break;
                case UP:
                    circle.setCenterY(circle.getCenterY() - 10);
                    event.consume();
                    break;
                case DOWN:
                    circle.setCenterY(circle.getCenterY() + 10);
                    event.consume();
                    break;
                default:
                    break;
            }
        }

    }

    public void handleCircleDragStart(MouseEvent event, Circle circle) {
        xOffset = event.getSceneX() - circle.getCenterX();
        yOffset = event.getSceneY() - circle.getCenterY();
    }

    public void handleCircleDrag(MouseEvent event, Circle circle) {
        double x = event.getSceneX() - xOffset;
        double y = event.getSceneY() - yOffset;

        circle.setCenterX(x);
        circle.setCenterY(y);
    }

    public void handleCircleDragEnd(MouseEvent event, Circle circle) {
        xOffset = 0;
        yOffset = 0;
    }

}

这是我的 FXMLDocument.fxml:

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

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ColorPicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.layout.Pane?>

<Pane fx:id="containerPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" onMouseClicked="#handleContainerPaneClick" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="addcircleapp.FXMLDocumentController">
   <children>
      <Button fx:id="addCircleButton" layoutX="345.0" layoutY="362.0" mnemonicParsing="false" onAction="#handleAddCircleButton" text="AddCircle" />
      <ColorPicker fx:id="colorPicker" layoutX="14.0" layoutY="361.0" />
      <Slider fx:id="sizeSlider" blockIncrement="1.0" layoutX="180.0" layoutY="367.0" min="1.0" value="50.0" />
      <Button fx:id="editButton" layoutX="432.0" layoutY="362.0" mnemonicParsing="false" onAction="#handleEditButton" prefHeight="25.0" prefWidth="67.0" text="Edit" />
      <Button fx:id="deleteButton" layoutX="519.0" layoutY="361.0" mnemonicParsing="false" onAction="#handleDeleteButton" prefHeight="25.0" prefWidth="67.0" text="Delete" />
      <Label fx:id="colorSelectLabel" layoutX="14.0" layoutY="340.0" text="Select a color:" />
      <Label fx:id="sizeSelectLabel" layoutX="180.0" layoutY="340.0" text="Size:" />
   </children>
</Pane>

我设法创建了一个“MyCircle”类并添加了一些事件处理程序,但某些功能无法正常工作,例如handleCircleClick方法。另外,我不知道如何解析handleEditButton和handleDeleteButton方法。

我的 FXMLDocumentController.java 文件如下所示:

package addcircleapp;

import java.net.URL;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Slider;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.util.Pair;

public class FXMLDocumentController implements Initializable {

    @FXML
    private Pane containerPane;

    @FXML
    private Button addCircleButton;

    @FXML
    private Button editButton;

    @FXML
    private Button deleteButton;

    @FXML
    private ColorPicker colorPicker;

    @FXML
    private Slider sizeSlider;

    @FXML
    private Label colorSelectLabel;

    @FXML
    private Label sizeSelectLabel;

    private List<MyCircle> circles = new ArrayList<>();
    private MyCircle selectedCircle = null;
    //private double xOffset = 0;
    //private double yOffset = 0;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
        sizeSelectLabel.setText("Size: " + String.valueOf(sizeSlider.getValue()));

        sizeSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
            sizeSelectLabel.setText("Size: " + String.valueOf(newValue.intValue()));
        });
    }

    public void handleAddCircleButton() {

        Random rand = new Random();
        int x = rand.nextInt(500);
        int y = rand.nextInt(200);

        Color selectedColor = colorPicker.getValue();
        double selectedSize = sizeSlider.getValue();

        MyCircle circle = new MyCircle(x, y, selectedSize, selectedColor);

        /*circle.setOnMouseClicked((MouseEvent e) -> {
        handleCircleClick(circle);
        });
        
        circle.setOnKeyPressed((KeyEvent e) -> {
        handleCircleMovement(e, circle);
        });
        
        circle.setOnMousePressed((MouseEvent e) -> {
        handleCircleDragStart(e, circle);
        });
        
        circle.setOnMouseDragged((MouseEvent e) -> {
        handleCircleDrag(e, circle);
        });
        
        circle.setOnMouseReleased((MouseEvent e) -> {
        handleCircleDragEnd(e, circle);
        });*/
        circles.add(circle);
        containerPane.getChildren().add(circle);

        System.out.println("New circle was created!");
    }

    public void handleEditButton() {
        if (selectedCircle != null) {
            Dialog<Pair<Color, Double>> editDialog = new Dialog<>();
            editDialog.setTitle("Edit Circle");
            editDialog.setHeaderText("Edit the color and size of the selected circle.");

            ButtonType confirmButton = new ButtonType("OK", ButtonData.OK_DONE);
            editDialog.getDialogPane().getButtonTypes().addAll(confirmButton, ButtonType.CANCEL);

            ColorPicker colorPicker = new ColorPicker((Color) selectedCircle.getFill());
            Slider sizeSlider = new Slider(10, 100, selectedCircle.getRadius());

            VBox vbox = new VBox(10);
            Label colorLabel = new Label("Color:");
            Label sizeLabel = new Label("Size:");

            sizeLabel.setText("Size: " + String.valueOf((int) sizeSlider.getValue()));

            sizeSlider.valueProperty().addListener((observable, oldValue, newValue) -> {
                sizeLabel.setText("Size: " + String.valueOf((int) sizeSlider.getValue()));
            });

            vbox.getChildren().addAll(colorLabel, colorPicker, sizeLabel, sizeSlider);

            editDialog.getDialogPane().setContent(vbox);

            editDialog.setResultConverter((ButtonType dialogButton) -> {
                if (dialogButton == confirmButton) {
                    return new Pair<>(colorPicker.getValue(), sizeSlider.getValue());
                }
                return null;
            });

            Optional<Pair<Color, Double>> result = editDialog.showAndWait();

            result.ifPresent(newValues -> {
                selectedCircle.setFill(newValues.getKey());
                selectedCircle.setRadius(newValues.getValue());
            });
        }
    }

    public void handleDeleteButton(ActionEvent event) {
        if (selectedCircle != null) {
            circles.remove(selectedCircle);
            containerPane.getChildren().remove(selectedCircle);
            selectedCircle = null;
        }
    }

    /*private void handleCircleClick(MyCircle clickedCircle) {
    if (selectedCircle != null) {
    selectedCircle.setStroke(Color.TRANSPARENT);
    }
    
    selectedCircle = clickedCircle;
    Color fillColor = (Color) selectedCircle.getFill();
    Color complementary = Color.color(1.0 - fillColor.getRed(), 1.0 - fillColor.getBlue(), 1.0 - fillColor.getGreen());
    
    selectedCircle.setStroke(complementary);
    selectedCircle.setStrokeWidth(2.0);
    
    selectedCircle.requestFocus();
    }*/

    public void handleContainerPaneClick(MouseEvent event) {
        if (selectedCircle != null && !selectedCircle.contains(event.getX(), event.getY())) {
            selectedCircle.setStroke(Color.TRANSPARENT);
            selectedCircle = null;
        }
    }

    /*
    private void handleCircleMovement(KeyEvent event, MyCircle circle) {
    if (selectedCircle != null && null != event.getCode()) {
    switch (event.getCode()) {
    case LEFT:
    circle.setCenterX(circle.getCenterX() - 10);
    event.consume();
    break;
    case RIGHT:
    circle.setCenterX(circle.getCenterX() + 10);
    event.consume();
    break;
    case UP:
    circle.setCenterY(circle.getCenterY() - 10);
    event.consume();
    break;
    case DOWN:
    circle.setCenterY(circle.getCenterY() + 10);
    event.consume();
    break;
    default:
    break;
    }
    }
    
    }
    
    public void handleCircleDragStart(MouseEvent event, MyCircle circle) {
    xOffset = event.getSceneX() - circle.getCenterX();
    yOffset = event.getSceneY() - circle.getCenterY();
    }
    
    public void handleCircleDrag(MouseEvent event, MyCircle circle) {
    double x = event.getSceneX() - xOffset;
    double y = event.getSceneY() - yOffset;
    
    circle.setCenterX(x);
    circle.setCenterY(y);
    }
    
    public void handleCircleDragEnd(MouseEvent event, MyCircle circle) {
    xOffset = 0;
    yOffset = 0;
    }*/

}

我的 MyCircle.java 文件如下所示:

package addcircleapp;

import javafx.scene.input.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;

public class MyCircle extends Circle {
    double xOffset = 0;
    double yOffset = 0;
    MyCircle selectedCircle = null;
    
    public MyCircle(int xPos, int yPos, double radius, Color color){
        super(xPos, yPos, radius, color);
        
        setOnMouseClicked((MouseEvent event) ->{
            //Handle circle click
            MyCircle selectedCircle = (MyCircle) event.getTarget();
            
            if(selectedCircle.isSelected()){
                selectedCircle.deselect();
            } else {
                selectedCircle.select();
            }
        });
        
        setOnKeyPressed((KeyEvent event) ->{
            //Handle circle movement
            handleCircleMovement(event, this);
        });
        
        setOnMousePressed((MouseEvent event) ->{
            //Handle drag start
            handleCircleDragStart(event, this);
        });
        
        setOnMouseDragged((MouseEvent event) ->{
            //Handle drag
            handleCircleDrag(event, this);
        });
        
        setOnMouseReleased((MouseEvent event) ->{
            //Handle drag end
            handleCircleDragEnd(this);
        });
    }
    
    public void select(){
        if(selectedCircle != null){
            selectedCircle.setStroke(Color.TRANSPARENT);
        }
        
        Color fillColor = (Color) getFill();
        Color complementary = Color.color(1.0 - fillColor.getRed(), 1.0 - fillColor.getBlue(), 1.0 - fillColor.getGreen());
        
        setStroke(complementary);
        setStrokeWidth(2.0);
        
        requestFocus();
    }
    
    public void deselect(){
        setStroke(Color.TRANSPARENT);
    }
    
    public boolean isSelected(){
        return getStroke() != Color.TRANSPARENT;
    }
    
    public void handleCircleMovement(KeyEvent event, MyCircle circle){
        if(null != event.getCode())switch (event.getCode()) {
            case LEFT:
                circle.setCenterX(circle.getCenterX() - 10);
                event.consume();
                break;
            case RIGHT:
                circle.setCenterX(circle.getCenterX() + 10);
                event.consume();
                break;
            case UP:
                circle.setCenterY(circle.getCenterY() - 10);
                event.consume();
                break;
            case DOWN:
                circle.setCenterY(circle.getCenterY() + 10);
                event.consume();
                break;
            default:
                break;
        }
    }
    
    public void handleCircleDragStart(MouseEvent event, MyCircle circle){
        xOffset = event.getSceneX() - circle.getCenterX();
        yOffset = event.getSceneY() - circle.getCenterY();
    }
    
    public void handleCircleDrag(MouseEvent event, MyCircle circle){
        double x = event.getSceneX() - xOffset;
        double y = event.getSceneY() - yOffset;
        
        circle.setCenterX(x);
        circle.setCenterY(y);
    }
    
    public void handleCircleDragEnd(MyCircle circle){
        xOffset = 0;
        yOffset = 0;
    }
}

java javafx netbeans java-8 scenebuilder
1个回答
0
投票

这是一个相当广泛的问题,对于这个网站来说可能有点过于基于意见,但我会尝试给出一些建议。

  1. 您的每个类都应该有一个单一的职责,并且应该只包含与该职责相关的字段和方法。如果您有一个名为

    MyCircle
    的类,则该类的每个实例都代表一个圆。 “选择哪个圆”不是该类的责任的一部分(它是更广泛的应用程序的一部分)。事实上,您正在实施一项业务规则(也许您实际上没有用语言表达),即一次只能选择一个圆圈。实施该规则(或跟踪选择了多个圆圈中的哪一个)当然不是
    MyCircle
    (同样,仅代表单个圆圈)的责任。

    另一方面,“这个圈子是否被选中”可能是

    MyCircle
    类的责任。因此,某种布尔
    selected
    属性在这里可能很合适。不难看出如何更改此类属性以响应鼠标单击。

    这实际上是您在实施此操作时遇到困难的原因;您试图在每个圆实例中维持“选择哪个圆”的状态。

  2. 优先选择组合而不是继承。这是 Joshua Bloch 的书《Effective Java》(每个 Java 程序员都应该阅读)中的关键内容之一。我的具体经验法则是,如果您不向类添加功能,而只是提供一种方便的方法来配置它的实例,那么您不应该对其进行子类化。即使您要添加一些功能(在您的情况下,您可以说您是:您正在添加选择的概念),您可能会喜欢组合。 从类继承意味着您可以访问该类的更多内部工作方式,因此您在理解类如何工作方面有更多的责任,以免编写可能无法按您想要的方式工作的代码。 (引用 Bloch 的话,“继承违反了封装”。)类越复杂(UI 类也非常复杂),您在子类化它们时就应该更加小心。我不建议在这里子类化

    Circle

    第一点产生了一个潜在的问题:我们确实需要某个地方来跟踪选择了哪个圆。如果每个圆圈只知道它何时被选择,我们需要知道任何 

    selected
  3. 值(每个圆圈一个)何时发生变化。 JavaFX 提供了一种通过
JavaFX Properties

执行此操作的机制。这些基本上是“可观察”属性:这意味着我们可以向它们

注册一个侦听器
,并且如果属性值发生变化,则调用侦听器。 所以我会这样做: import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; public class SelectableCircle { double xOffset = 0; double yOffset = 0; private final Circle uiComponent; private final BooleanProperty selected = new SimpleBooleanProperty(false); public BooleanProperty selectedProperty() { return selected; } public final boolean isSelected() { return selectedProperty().get(); } public final void setSelected(boolean selected) { selectedProperty().set(selected); } public SelectableCircle(int xPos, int yPos, double radius, Color color){ uiComponent = new Circle(xPos, yPos, radius, color); uiComponent.setOnMouseClicked(e -> { setSelected( ! isSelected() ); }); uiComponent.setOnKeyPressed((KeyEvent event) ->{ //Handle circle movement handleCircleMovement(event); }); uiComponent.setOnMousePressed((MouseEvent event) ->{ //Handle drag start handleCircleDragStart(event); }); uiComponent.setOnMouseDragged((MouseEvent event) ->{ //Handle drag handleCircleDrag(event); }); // update circle ui according to selected state: selected.addListener((obs, wasSelected, isNowSelected) -> { if (isNowSelected) { Color fillColor = (Color) uiComponent.getFill(); Color complementary = Color.color(1.0 - fillColor.getRed(), 1.0 - fillColor.getBlue(), 1.0 - fillColor.getGreen()); uiComponent.setStroke(complementary); uiComponent.requestFocus(); } else { uiComponent.setStroke(Color.TRANSPARENT); } }); } public void handleCircleMovement(KeyEvent event){ switch (event.getCode()) { case LEFT: uiComponent.setCenterX(uiComponent.getCenterX() - 10); event.consume(); break; case RIGHT: uiComponent.setCenterX(uiComponent.getCenterX() + 10); event.consume(); break; case UP: uiComponent.setCenterY(uiComponent.getCenterY() - 10); event.consume(); break; case DOWN: uiComponent.setCenterY(uiComponent.getCenterY() + 10); event.consume(); break; default: break; } } public void handleCircleDragStart(MouseEvent event){ xOffset = event.getSceneX() - uiComponent.getCenterX(); yOffset = event.getSceneY() - uiComponent.getCenterY(); } public void handleCircleDrag(MouseEvent event){ double x = event.getSceneX() - xOffset; double y = event.getSceneY() - yOffset; uiComponent.setCenterX(x); uiComponent.setCenterY(y); } public Circle getUIComponent() { return uiComponent; } }

现在您需要对控制器代码进行一些更改。添加圆圈时,您需要执行以下操作:

    public void handleAddCircleButton() {

        Random rand = new Random();
        int x = rand.nextInt(500);
        int y = rand.nextInt(200);

        Color selectedColor = colorPicker.getValue();
        double selectedSize = sizeSlider.getValue();

        SelectableCircle circle = new SelectableCircle(x, y, selectedSize, selectedColor);

        // if selected state of circle changes, update our selectedCircle:
        circle.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
            if (isNowSelected) {
                selectedCircle = circle;
            }
        });

        circles.add(circle);
        containerPane.getChildren().add(circle.getUIComponent());

        System.out.println("New circle was created!");
    }

然后在各个地方(基本上在使用 UI 时)您将需要参考

selectedCircle.getUIComponent()
 而不仅仅是 
selectedCircle

。例如:

    public void handleDeleteButton(ActionEvent event) {
        if (selectedCircle != null) {
            circles.remove(selectedCircle);
            containerPane.getChildren().remove(selectedCircle.getUIComponent());
            selectedCircle = null;
        }
    }
    

© www.soinside.com 2019 - 2024. All rights reserved.