L
L
lonata2018-12-05 03:34:56
Java
lonata, 2018-12-05 03:34:56

How to simplify the written code?

I am writing a program, when you click on the brown rectangle on the left (let's call it the settings button), a strip appears from it, and the category that is associated with it goes to the right (changes its width to show this strip)
When you click on the settings button, all other buttons are deactivated, and are activated only when I click on the current settings button again
. The program works fine, BUT! sooo much code) it is only written for 3 categories, and when there are all 8 categories, the code size will increase 10 times, and even IDEA tells me that the code is duplicated.
QUESTION: How to optimize everything and reduce the size of the code?
I know that, for example, you can deactivate Toggle Buttons (brown rectangles, settings buttons), you can not prescribe somehow for each category all 8 pieces for each category and separately, but I don’t know how to do this =(
I would be grateful for an answer
* I do all the markup through the Scene Builder, and in the same place I assign actions to the buttons and methods of the
Video
Class Main:

package card;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.*;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.awt.*;

public class Main extends Application {

//create variables for dragggable window
private double xOffset = 0;
private double yOffset = 0;

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

  @Override
  public void start(Stage primaryStage) throws Exception {
    try {

      Parent root = FXMLLoader.load(getClass().getResource("/card/card.fxml"));
      Scene scene = new Scene(root, 1200, 600);
      scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm());
      primaryStage.setMaximized(true);
      primaryStage.setScene(scene);
      primaryStage.initStyle(StageStyle.DECORATED.UNDECORATED);

//make application draggable
      root.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
          xOffset = event.getSceneX();
          yOffset = event.getSceneY();
        }
      });

      root.setOnMouseDragged(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
          primaryStage.setX(event.getScreenX() - xOffset);
          primaryStage.setY(event.getScreenY() - yOffset);
        }
      });

      //assign ALT+ENTER to maximize window
      final KeyCombination kb = new KeyCodeCombination(KeyCode.ENTER, KeyCombination.ALT_DOWN);
      scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent event) {
          if (kb.match(event)) {
            primaryStage.setMaximized(!primaryStage.isMaximized());
          }
        }
      });

      //show stage
      primaryStage.show();

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



  }




}

Controller class:
package card;

import javafx.animation.*;
import javafx.scene.control.*;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.layout.*;
import javafx.event.ActionEvent;
import javafx.util.Duration;
import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {

  @FXML  private AnchorPane anchorRow;
  @FXML  private HBox hBoxCat0;
  @FXML  private ToggleButton btnPref1;
  @FXML  private ToggleButton btnPref2;
  @FXML  private ToggleButton btnPref3;
  @FXML  private ToggleButton btnPref4;
  @FXML  private ToggleButton btnPref5;
  @FXML  private ToggleButton btnPref6;
  @FXML  private ToggleButton btnPref7;
  @FXML  private ToggleButton btnPref8;
  @FXML  private Label category1;
  @FXML  private Label category2;
  @FXML  private Label category3;
  private ToggleGroup group;

  @Override
  public void initialize(URL location, ResourceBundle resources) {

    group = new ToggleGroup();
    this.btnPref1.setToggleGroup(group);
    this.btnPref2.setToggleGroup(group);
    this.btnPref3.setToggleGroup(group);

  }


  @FXML
  void openPreference1(ActionEvent event) {
    Timeline tmHbox1 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(hBoxCat0.prefWidthProperty(), 250)));
    Timeline tmHboxOne1 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(hBoxCat0.prefWidthProperty(), 10)));


    if (btnPref1.isSelected()) {
      GridPane.setRowIndex(anchorRow, 0);
      Timeline timelineHCategory1 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(category1.prefWidthProperty(), 1610)));
      tmHbox1.play();
      timelineHCategory1.play();
      btnPref2.setDisable(true);
      btnPref3.setDisable(true);

    }

    else  {
      Timeline timelineHCategoryOne1 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(category1.prefWidthProperty(), 1900)));
      timelineHCategoryOne1.play();
      tmHboxOne1.play();
      btnPref2.setDisable(false);
      btnPref3.setDisable(false);

    }
  }
  //Open preference window and make width animation for categories
  @FXML
  void openPreference2(ActionEvent event) {

    Timeline tmHbox1 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(hBoxCat0.prefWidthProperty(), 250)));
    Timeline tmHboxOne1 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(hBoxCat0.prefWidthProperty(), 10)));


    if (btnPref2.isSelected()) {
      GridPane.setRowIndex(anchorRow, 1);
      Timeline timelineHCategory2 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(category2.prefWidthProperty(), 1610)));
      timelineHCategory2.play();
      tmHbox1.play();
      btnPref1.setDisable(true);
      btnPref3.setDisable(true);
    }

  else  {
     Timeline timelineHCategoryTwo2 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(category2.prefWidthProperty(), 1900)));
      timelineHCategoryTwo2.play();
      tmHboxOne1.play();
      btnPref1.setDisable(false);
      btnPref3.setDisable(false);
  }

  }

  @FXML
  void openPreference3(ActionEvent event) {

    Timeline tmHbox1 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(hBoxCat0.prefWidthProperty(), 250)));
    Timeline tmHboxOne1 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(hBoxCat0.prefWidthProperty(), 10)));


    if (btnPref3.isSelected()) {
      GridPane.setRowIndex(anchorRow, 2);
      Timeline timelineHCategory3 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(category3.prefWidthProperty(), 1610)));
      timelineHCategory3.play();
      tmHbox1.play();
      btnPref1.setDisable(true);
      btnPref2.setDisable(true);
    }

    else  {
      Timeline timelineHCategoryThree3 = new Timeline(new KeyFrame(Duration.millis(300), new KeyValue(category3.prefWidthProperty(), 1900)));
      timelineHCategoryThree3.play();
      tmHboxOne1.play();
      btnPref1.setDisable(false);
      btnPref2.setDisable(false);
    }

  }


}

FXML:

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Alexandrov, 2018-12-05
@lonata

It's easy,
firstly, as I answered in the last question, DO NOT USE Scene Builder, you can write everything by hand even without fxml.
secondly, wrap the whole nightmare with animation and buttons in a separate component class, the code will already be reduced at times. Deactivation\activation of other elements is also easy to fit to a single place by getting all the children from the parent container and setting setDisable in them

L
lonata, 2018-12-05
@lonata

1. I use Scene Builder for several reasons: I can visually see how all the elements in the application will be located, if I write all the markup of the design, then it takes a very long time, and if I need to redo the location of one component, I need to redo a bunch of everything in XML, in In the case of the Scene Builder, all markup changes in the same second.
Why is using Scene Builder bad? it is used in many foreign tutorials
2. If, for example, I create the Animation.java class in the same package where all the other classes are, how can I transfer the code from the Controller? What needs to be done so that the Main and Controller classes see my Animation class and all animation works as before?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question