Добавление суперкласса и нескольких подклассов в мою программу рисования JavaFX

Я создал программу рисования на JavaFX. Весь код, как вы видите, находится в одном БОЛЬШОМ файле. Итак, я хочу создать суперкласс под названием Figure, чтобы иметь все, что есть у фигур. Затем я хочу создать подклассы для каждой линии, круга, прямоугольника и многоугольника и, возможно, создать методы рисования с обработчиком событий в каждом из этих классов, возможно ли это?

Это мой код:

package tegneprogram;

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.stage.Stage;

//------------------------------------------------------------------------------
// CONTROLFX MUST BE ADDED IN THE PROJECT LIBRARY TO SEE THE EFFECT
//------------------------------------------------------------------------------

import org.controlsfx.control.PopOver;


//---------------------------------------------------------------------------------------
// DESCRIPTION:
//
// A PROGRAM THAT ALLOWS THE USER TO DRAW GEOMETRIC FIGURES WITH DIFFERENT COLORS.
// YOU CAN ALSO ADD TEXT TO THE PANE. WHEN FIGURES AND TEXT IS APPLIED YOU CAN MOUSE_PRESS
// AND MOUSE_DRAG THEM INDIVIDUALLY AND MOVE EACH ONE AROUND THE PANE.
//
//------------------------------------------------------------------------------




public class Tegneprogram extends Application {


//------------------------------------------------------------------------------
// START
//------------------------------------------------------------------------------



//------------------------------------------------------------------------------
// GEOMETRIC FIGURES
//------------------------------------------------------------------------------

     Rectangle rect; 
     Line line;
     Polygon poly;
     Circle circ;
     TextField text;

//------------------------------------------------------------------------------
// VARIABLES FOR DRAGGING FIGURES
//------------------------------------------------------------------------------

    double nwPosX = 0, nwPosY = 0;
    double TX = 0, TY = 0;

//------------------------------------------------------------------------------ 
// DRAWING PANE
//------------------------------------------------------------------------------

     Pane pane;

//------------------------------------------------------------------------------  
// COLORPICKER
//------------------------------------------------------------------------------  

     ColorPicker cpFill;
     ColorPicker cpLine;

//------------------------------------------------------------------------------
// POLYGON VARIABLES, ARRAYLIST AND DOUBLE ARRAY
//------------------------------------------------------------------------------

int count = 0;
double x[] = new double[3];
double y[] = new double[3];
List<Double> values = new ArrayList();


//------------------------------------------------------------------------------
// SPACE
//------------------------------------------------------------------------------


    @Override
    public void start(Stage primaryStage) {

//------------------------------------------------------------------------------
// TOGGLE BUTTON FOR FIGURES
//------------------------------------------------------------------------------

        ToggleButton linebtn = new ToggleButton("Line");
        ToggleButton rectbtn = new ToggleButton("Rectangel");
        ToggleButton circbtn = new ToggleButton("Circle");
        ToggleButton polybtn = new ToggleButton("Polygon");
        ToggleButton textbtn = new ToggleButton("Text");

//------------------------------------------------------------------------------
// LABELS FOR INFORMATION ABOUT COLOR
//------------------------------------------------------------------------------
        Label line_color = new Label("Line Color");
        Label fill_color = new Label("Fill Color");

 //-----------------------------------------------------------------------------
 // TABLE ARRAY FOR ALL THE TOGGLE BUTTONS
 //-----------------------------------------------------------------------------

        ToggleButton[] FigureTool = {linebtn, rectbtn, circbtn, polybtn, textbtn};

//------------------------------------------------------------------------------
// GROUP OBJECT FOR TOGGLEBUTTONS
//------------------------------------------------------------------------------

        ToggleGroup tools = new ToggleGroup();

//------------------------------------------------------------------------------ 
// COUNTING ALL THE BUTTONS IN TABLE ARRAY AND GROUPS THEM IN A TOGGLEGROUP
//------------------------------------------------------------------------------

        for(ToggleButton tool : FigureTool) {
            tool.setMinWidth(90);//width on buttons
            tool.setToggleGroup(tools);
            tool.setCursor(Cursor.HAND);

        }
//------------------------------------------------------------------------------
// COLORPICKER
//------------------------------------------------------------------------------
         cpLine = new ColorPicker(Color.BLACK);
         cpFill = new ColorPicker(Color.TRANSPARENT);         


//------------------------------------------------------------------------------
// HBOX FOR PLACING BUTTONS
//------------------------------------------------------------------------------

        HBox buttons = new HBox(10);
        buttons.getChildren().addAll(linebtn, rectbtn, circbtn, polybtn, textbtn);

//------------------------------------------------------------------------------
// STYLING FOR HBOX BUTTONS
//------------------------------------------------------------------------------

        buttons.setPadding(new Insets(5));
        buttons.setStyle("-fx-background: #777");
        buttons.setPrefWidth(90);


//------------------------------------------------------------------------------       
// VBOX FOR PLACING LINE AND COLOR BUTTONS
//------------------------------------------------------------------------------

        VBox colors = new VBox(10);
        colors.getChildren().addAll(line_color,cpLine,fill_color, cpFill);

//------------------------------------------------------------------------------  
// STYLING FOR VBOX COLORS BUTTONS 
//------------------------------------------------------------------------------

        colors.setPadding(new Insets(5));
        colors.setStyle("-fx-background: #777");


//------------------------------------------------------------------------------
// SETTING UP DRAWING PANE
//------------------------------------------------------------------------------

        pane = new Pane();
        pane.setStyle("-fx-background-color: white");


//------------------------------------------------------------------------------
// MOUSE_DRAGGED LINE
//------------------------------------------------------------------------------



    EventHandler<MouseEvent> lineMousePressed = (MouseEvent e) -> {
            nwPosX  = e.getSceneX();
            nwPosY  = e.getSceneY();
            TX  = ((Line)(e.getSource())).getTranslateX();
            TY  = ((Line)(e.getSource())).getTranslateY();


            ((Line)(e.getSource())).toFront();

        };

    EventHandler<MouseEvent> lineMoveDrag = (MouseEvent e) -> {

            double newSetX = e.getSceneX() - nwPosX;
            double newSetY = e.getSceneY() - nwPosY;
            double NSX = TX + newSetX;
            double NSY = TY + newSetY;


            ((Line)(e.getSource())).setTranslateX(NSX);
            ((Line)(e.getSource())).setTranslateY(NSY);
        };


//------------------------------------------------------------------------------
// MOUSE_DRAGGED RECTANGLE
//------------------------------------------------------------------------------



    EventHandler<MouseEvent> rectMousePressed = (MouseEvent e) -> {
            nwPosX  = e.getSceneX();
            nwPosY  = e.getSceneY();
            TX  = ((Rectangle)(e.getSource())).getTranslateX();
            TY  = ((Rectangle)(e.getSource())).getTranslateY();


           ((Rectangle)(e.getSource())).toFront();
        };

    EventHandler<MouseEvent> rectMoveDrag = (MouseEvent e) -> {

            double newSetX = e.getSceneX() - nwPosX;
            double newSetY = e.getSceneY() - nwPosY;
            double NSX = TX + newSetX;
            double NSY = TY + newSetY;


            ((Rectangle)(e.getSource())).setTranslateX(NSX);
            ((Rectangle)(e.getSource())).setTranslateY(NSY);
        };



//------------------------------------------------------------------------------
// MOUSE_DRAGGED CIRCLE
//------------------------------------------------------------------------------


    EventHandler<MouseEvent> circlMousePressed = (MouseEvent e) -> {
            nwPosX  = e.getSceneX();
            nwPosY  = e.getSceneY();
            TX  = ((Circle)(e.getSource())).getTranslateX();
            TY  = ((Circle)(e.getSource())).getTranslateY();


            ((Circle)(e.getSource())).toFront();

        };


    EventHandler<MouseEvent> circMoveDrag = (MouseEvent e) -> {

            double NSX = e.getSceneX() - nwPosX;
            double NSY = e.getSceneY() - nwPosY;
            double newX = TX + NSX;
            double newY = TY + NSY;


            ((Circle)(e.getSource())).setTranslateX(newX);
            ((Circle)(e.getSource())).setTranslateY(newY);
        };



//------------------------------------------------------------------------------
// MOUSE_DRAGGED POLYGON
//------------------------------------------------------------------------------

    EventHandler<MouseEvent> polyMousePressed = (MouseEvent e) -> {

            nwPosX  = e.getSceneX();
            nwPosY  = e.getSceneY();
            TX  = ((Polygon)(e.getSource())).getTranslateX();
            TY  = ((Polygon)(e.getSource())).getTranslateY();


            ((Polygon)(e.getSource())).toFront();

        };

    EventHandler<MouseEvent> polyMoveDrag = (MouseEvent e) -> {

            double newSetX = e.getSceneX() - nwPosX;
            double newSetY = e.getSceneY() - nwPosY;
            double NSX = TX + newSetX;
            double NSY = TY + newSetY;


            ((Polygon)(e.getSource())).setTranslateX(NSX);
            ((Polygon)(e.getSource())).setTranslateY(NSY);
        };

//------------------------------------------------------------------------------
// MOUSE_DRAGGED TEXT
//------------------------------------------------------------------------------


    EventHandler<MouseEvent> textMousePressed = (MouseEvent e) -> {

            nwPosX  = e.getSceneX();
            nwPosY  = e.getSceneY();
            TX  = ((TextField)(e.getSource())).getTranslateX();
            TY  = ((TextField)(e.getSource())).getTranslateY();


            ((TextField)(e.getSource())).toFront();

        };


    EventHandler<MouseEvent> textMoveDrag = (MouseEvent e) -> {

            double newSetX = e.getSceneX() - nwPosX;
            double newSetY = e.getSceneY() - nwPosY;
            double NSX = TX + newSetX;
            double NSY = TY + newSetY;


            ((TextField)(e.getSource())).setTranslateX(NSX);
            ((TextField)(e.getSource())).setTranslateY(NSY);
        };    


//------------------------------------------------------------------------------
// POPOVER PANELS FOR SIDE INFORMATION ON THE RIGHT
//------------------------------------------------------------------------------

     String linjetype = "Straight line";
     String rectangle = "Rectangle";
     String circle = "Circle";
     String poly1 = "Polygon";
     String text1 = "TEXT";


     Label line1 = new Label("\n"+linjetype+" ");
     Label rect1 = new Label("\n"+rectangle+" ");
     Label circ1 = new Label("\n"+circle+" ");
     Label poly2 = new Label("\n"+poly1+" ");
     Label text2 = new Label("\n"+text1+" ");

     VBox vBox = new VBox(line1);
     VBox vBox2 = new VBox(rect1);
     VBox vBox3 = new VBox(circ1);
     VBox vBox4 = new VBox(poly2);
     VBox vBox5 = new VBox(text2);

     PopOver popOver = new PopOver(vBox);
     PopOver popOver2 = new PopOver(vBox2);
     PopOver popOver3 = new PopOver(vBox3);
     PopOver popOver4 = new PopOver(vBox4);
     PopOver popOver5 = new PopOver(vBox5);


//------------------------------------------------------------------------------
// EVENTHANDLER: MOUSE_PRESSED LINE
//------------------------------------------------------------------------------

        pane.addEventHandler(MouseEvent.MOUSE_PRESSED, e-> {
            if (linebtn.isSelected()) {
            popOver.show(pane);
            line = new Line();
            line.setStartX(e.getX());
            line.setStartY(e.getY());  
            line.setStroke(cpFill.getValue()); 
            line.setOnMousePressed(lineMousePressed);
            line.setOnMouseDragged(lineMoveDrag);
            pane.getChildren().add(line);  
            }



//------------------------------------------------------------------------------
// MOUSE_PRESSED RECTANGLE
//------------------------------------------------------------------------------

            else if (rectbtn.isSelected()) {
            popOver2.show(pane);
            rect = new Rectangle(); 
            rect.setX(e.getX());                
            rect.setY(e.getY());     
            rect.setStroke(cpLine.getValue());
            rect.setFill(cpFill.getValue());  
            rect.setOnMousePressed(rectMousePressed);
            rect.setOnMouseDragged(rectMoveDrag);
            pane.getChildren().add(rect);
            }

//------------------------------------------------------------------------------
// MOUSE_PRESSED CIRCLE
//------------------------------------------------------------------------------

            else if (circbtn.isSelected()) {
            popOver3.show(pane);
            circ = new Circle();
            circ.setStroke(cpLine.getValue());
            circ.setFill(cpFill.getValue());
            circ.setCenterY(e.getY());
            circ.setCenterX(e.getX());
            pane.getChildren().add(circ);
            circ.setOnMousePressed(circlMousePressed);
            circ.setOnMouseDragged(circMoveDrag);
            }

//------------------------------------------------------------------------------
// MOUSE_PRESSED POLYGON
//------------------------------------------------------------------------------

            else if (polybtn.isSelected()) {
            popOver4.show(pane);
            poly = new Polygon();
            x[count] = e.getX();
            y[count] = e.getY(); 
            poly.setStroke(cpLine.getValue());
            poly.setFill(cpFill.getValue());
            poly.setOnMousePressed(polyMousePressed);
            poly.setOnMouseDragged(polyMoveDrag);
            pane.getChildren().add(poly);
            } 


//------------------------------------------------------------------------------
// MOUSE_PRESSED TEXTFIELD
//------------------------------------------------------------------------------

            else if (textbtn.isSelected()){
            popOver5.show(pane);
            text = new TextField();
            text.setFont(Font.font("Verdana", 30));    
            text.setOnMousePressed(textMousePressed);
            text.setOnMouseDragged(textMoveDrag);
            text.toFront();
            pane.getChildren().add(text);
            }

         }); 


//------------------------------------------------------------------------------
// EVENTHANDLER: MOUSE_RELEASED RECTANGLE
//------------------------------------------------------------------------------

            pane.addEventHandler(MouseEvent.MOUSE_RELEASED, e-> {
            if (rectbtn.isSelected()) {
            rect.setWidth(e.getX() - rect.getX());
            rect.setHeight(e.getY() - rect.getY());
            }     

//------------------------------------------------------------------------------
// MOUSE_RELEASED LINE
//------------------------------------------------------------------------------

            else if (linebtn.isSelected()) {
            line.setEndX(e.getX());
            line.setEndY(e.getY());

            }

//------------------------------------------------------------------------------
// MOUSE_RELEASED CIRCLE
//------------------------------------------------------------------------------

            else if (circbtn.isSelected()) {
            //Math.abs gives exact value of the radius
            circ.setRadius(Math.abs(e.getX() - circ.getCenterX()) + Math.abs(e.getY() - circ.getCenterY()) / 2);
             }

//------------------------------------------------------------------------------
// MOUSE_RELEASED POLYGON
//------------------------------------------------------------------------------

           else if (polybtn.isSelected()) {
            values.add(x[count]);
            values.add(y[count]);
            count++;
            poly.getPoints().addAll(values);
           }
      });

//------------------------------------------------------------------------------
// STAGE AND SCENE
//------------------------------------------------------------------------------

        BorderPane pane1 = new BorderPane();
        pane1.setTop(buttons);
        pane1.setRight(colors);
        pane1.setCenter(pane);
        Scene scene = new Scene(pane1, 800, 450);
        primaryStage.setTitle("Tegneprogram");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

//------------------------------------------------------------------------------
// END
//------------------------------------------------------------------------------

В моем воображении я думал, что суперкласс Figure будет примерно таким: здесь есть все экземпляры объектов, а также цвета фигур и так далее:

public class Figur {

     Rectangle rect; 
     Line line;
     Polygon poly;
     Circle circ;
     TextField text;

     ColorPicker cpFill;
     ColorPicker cpLine;

}

А затем, возможно, настроить все обработчики событий для рисования фигур в отдельных подклассах. Возможно ли это, и как мне это соединить?

Подкласс Line может быть чем-то вроде этого, с методом createdLine, который рисует линию. То же самое и с другими формами.

public class Line extends Figur {

    public void createLine(){

            popOver.show(pane);
            super(line);
            line.setStartX(e.getX());
            line.setStartY(e.getY());  
            line.setStroke(cpFill.getValue()); 
            line.setOnMousePressed(lineMousePressed);
            line.setOnMouseDragged(lineMoveDrag);
            pane.getChildren().add(line);  
         }
    }

И способ рисования окончания линии:

public void endLine(){
        line.setEndX(e.getX());
        line.setEndY(e.getY());
     }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
356
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вероятно, вы захотите объявить Figur (я предполагаю, что эта версия с ошибкой - это то, что вам нужно) как абстрактный класс только с этими членами: cpFill, cpLine, mousePressedHandler, mouseDraggedHandler и конструктором, который принимает аргументы для cpFill и cpLine. Затем для каждого подкласса вам нужно объявить, какой объект формы содержит, и конструктор, который определяет mousePressedHandler и mouseDraggedHandler.

Обновлено: образцы кода, чтобы лучше продемонстрировать то, что я описал выше.

public abstract class Figure {
    private ColorPicker cpFill;
    private ColorPicker cpLine;
    private EventHandler<MouseEvent> mousePressedHandler;
    private EventHandler<MouseEvent> mouseDraggedHandler;

    public Figur(ColorPicker cpFill, ColorPicker cpLine) {
        this.cpFill = cpFill;
        this.cpLine = cpLine;
    }
}

public class MyRectangle extends Figure {
    private Rectangle rect;

    public MyRectangle(ColorPicker cpFill, ColorPicker cpLine) {
        super(cpFill, cpLine);

        mousePressedHandler = e -> {
            // do something with your rectangle here
        }

        mouseDraggedHandler = e -> {
            // do another thing with your rectangle here
        }

        rect.setOnMousePressed(mousePressedHandler);
        rect.setOnMouseDragged(mouseDraggedHandler);
    }
}

public class MyLine extends Figure {
    private Line line;

    public MyRectangle(ColorPicker cpFill, ColorPicker cpLine) {
        super(cpFill, cpLine);

        mousePressedHandler = e -> {
            // do something with your line here
        }

        mouseDraggedHandler = e -> {
            // do another thing with your line here
        }

        line.setOnMousePressed(mousePressedHandler);
        line.setOnMouseDragged(mouseDraggedHandler);
    }
}

Примечание: теперь, когда я написал код, я понял, что вам не нужно объявлять mousePressedHandler и mouseDraggedHandler в вашем абстрактном классе. Тем не менее, я все же оставляю их там, чтобы все было немного яснее. Смело удаляйте их и просто звоните

line.setOnMousePressed(e -> {
    // something
});

line.setOnMouseDragged(e -> {
    // another thing
});

вместо

Итак, если у меня есть только cpFill, cpLine, mousePressedHandler mouseDraggedHandler в абстрактном классе, вам также нужны экземпляры объектов, чтобы код работал правильно? Так следует ли мне иметь это в абстрактном классе? Прямоугольник rect; Линия линии; Многоугольник poly; Круг по кругу; TextField text;

dexedrine 17.11.2018 19:08

Вы не должны, потому что они относятся к подклассам. Я объяснил в своем ответе, что вы должны объявить один из них для каждого из своих подклассов.

Gnas 17.11.2018 19:09

Кстати, я полный новичок в этом деле, так что спасибо за помощь. Когда дело доходит до mousePressedHandler и mouseDraggedHandler, могу ли я просто настроить обычную структуру из того, что у меня есть в основном? Я действительно не понимаю ...: / Я сделал конструктор, который теперь получает cpFill и cpLine. публичная фигура (ColorPicker cpFill, ColorPicker cpLine) {this.cpFill = cpFill; this.cpLine = cpLine; }

dexedrine 17.11.2018 19:28

Итак, я написал все подклассы! : D У меня проблемы с некоторыми методами в них, хотя они выделяются красным цветом. Есть ли способ их импортировать? :) Например, метод "setEndX" в подклассе строки, обработчик событий MOUSE_RELEASED отмечен красным.

dexedrine 17.11.2018 22:00
setEndX - это метод Line, поэтому вам следует писать line.setEndX; что касается MOUSE_RELEASED, то нужно писать MouseEvent.MOUSE_RELEASED
Gnas 17.11.2018 22:37

Итак, мой код для MOUSE_RELEASED теперь выглядит так. MOUSE_RELEASED = e -> {line.setEndX (e.getX ()); line.setEndY (e.getY ()); }; "line.setEndX", как вы видите, уже применен (но все еще красный). Я попытался импортировать класс круга, но это не сработало. Если я сделаю это: EventHandler (MouseEvent.MOUSE_RELEASED e -> {line.setEndX (e.getX ()); line.setEndY (e.getY ());}; красные отметки на методах setEnd исчезнут, но «EventHandler ( MouseEvent.MOUSE_RELEASED e -> "весь красный, вероятно, потому что он уже определен в классе Figure.

dexedrine 17.11.2018 23:07

Проблема в вашем синтаксисе, который выглядит очень неправильно (это часть EventHandler(MouseEvent.MOUSE_RELEASED e). Поиск правильного синтаксиса в Google не займет много времени (я считаю, что предоставленный мной код также имеет правильный синтаксис). Также вы обычно можете сказать, почему это неправильно, наведя курсор на эту часть в среде IDE, она также может предложить исправления, если это возможно.

Gnas 17.11.2018 23:17

Другие вопросы по теме