I have my current class assignment and I'm having trouble setting the margin for my rectangle. It is a fruit list that is supposed to calculate the total of the desired fruits picked by the user. the HBox is used to display the bottom part of the window where I have my checkout button as well as my total label in the center of the rectangle, which is so far working just fine. But, I'm trying to set the margin for the rectangle so it looks more centered in the bottom part and I keep running into this set margin static error. Please help, and would love it if anybody can show me how to set an exception for my total if the user does not want to pick from my fruits options where the total = 0 for the non-picked ones. Also, please let me know if there are some cleaner way of coding, would love to get to know that as well :)
public class Grid_Layout extends Application {
public static void main(String[] args) {
Application.launch(args);
}
public void start(Stage primaryStage)
{
BorderPane border = new BorderPane(); // for the title use
HBox hbox = new HBox(20); // for the rectangle, checkout button, and the total label // 20 for spacing
// Calling out GridPane and setting alignments and measurements
GridPane pane = new GridPane();
border.setCenter(pane);
border.setBottom(hbox);
pane.setAlignment(Pos.CENTER);
pane.setPadding(new Insets(10,20,10,20)); //top, right, bottom, left space between content and border
pane.setHgap(10);
pane.setVgap(20);
pane.setStyle("-fx-background-color: #e6ffb3;");
// Set images as Image
Image apple_img = new Image("File:images/apple.png");
Image apricot_img = new Image("File:images/apricot.png");
Image banana_img = new Image("File:images/banana.png");
Image cherry_img = new Image("File:images/cherry.png");
Image grape_img = new Image("File:images/grape.png");
Image lemmon_img = new Image("File:images/lemmon.png");
Image orange_img = new Image("File:images/orange.png");
Image pear_img = new Image("File:images/pear.png");
Image strawberry_img = new Image("File:images/strawberry.png");
Image watermelon_img = new Image("File:images/watermelon.png");
// To set Image(s) to ImageView in order to display
ImageView apple_iv = new ImageView(apple_img);
pane.add(apple_iv, 0, 1);
ImageView apricot_iv = new ImageView(apricot_img);
pane.add(apricot_iv, 3, 1);
ImageView banana_iv = new ImageView(banana_img);
pane.add(banana_iv, 6, 1);
ImageView cherry_iv = new ImageView(cherry_img);
pane.add(cherry_iv, 0, 2);
ImageView grape_iv = new ImageView(grape_img);
pane.add(grape_iv, 3, 2);
ImageView lemmon_iv = new ImageView(lemmon_img);
pane.add(lemmon_iv, 6, 2);
ImageView orange_iv = new ImageView(orange_img);
pane.add(orange_iv, 0, 3);
ImageView pear_iv = new ImageView(pear_img);
pane.add(pear_iv, 3, 3);
ImageView strawberry_iv = new ImageView(strawberry_img);
pane.add(strawberry_iv, 6, 3);
ImageView watermelon_iv = new ImageView(watermelon_img);
pane.add(watermelon_iv, 0, 4);
// To insert all of the textfields for user input
TextField tf1 = new TextField();
tf1.setMaxWidth(50);
TextField tf2 = new TextField();
tf2.setMaxWidth(50);
TextField tf3 = new TextField();
tf3.setMaxWidth(50);
TextField tf4 = new TextField();
tf4.setMaxWidth(50);
TextField tf5 = new TextField();
tf5.setMaxWidth(50);
TextField tf6 = new TextField();
tf6.setMaxWidth(50);
TextField tf7 = new TextField();
tf7.setMaxWidth(50);
TextField tf8 = new TextField();
tf8.setMaxWidth(50);
TextField tf9 = new TextField();
tf9.setMaxWidth(50);
TextField tf10 = new TextField();
tf10.setMaxWidth(50);
// To insert all of the labels
pane.add(new Label("0.99/lb"), 1, 1);
pane.add(tf1, 2, 1);
pane.add(new Label("1.49/lb"), 4, 1);
pane.add(tf2, 5, 1);
pane.add(new Label("0.49/lb"), 7, 1);
pane.add(tf3, 8, 1);
pane.add(new Label("1.99/lb"), 1, 2);
pane.add(tf4, 2, 2);
pane.add(new Label("0.99/lb"), 4, 2);
pane.add(tf5, 5, 2);
pane.add(new Label("1.99/lb"), 7, 2);
pane.add(tf6, 8, 2);
pane.add(new Label("0.99/lb"), 1, 3);
pane.add(tf7, 2, 3);
pane.add(new Label("1.49/lb"), 4, 3);
pane.add(tf8, 5, 3);
pane.add(new Label("1.99/lb"), 7, 3);
pane.add(tf9, 8, 3);
pane.add(new Label("0.99/lb"), 1, 4);
pane.add(tf10, 2, 4);
// to lock in prefered window size for the user, it is still resizable
ColumnConstraints col = new ColumnConstraints();
col.setPercentWidth(10);
pane.setPrefSize(700, 350);
pane.setMaxSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
// Body title
Label titlelbl = new Label("Anna's Fresh Market");
border.setTop(titlelbl);
BorderPane.setAlignment(titlelbl, Pos.CENTER);
titlelbl.setPadding(new Insets(10));
titlelbl.setStyle("-fx-font-size: 25px; -fx-text-fill: green;-fx-background-color: #e6ffb3;");
border.setStyle("-fx-background-color: #e6ffb3;");
// Rectangle
Rectangle rect = new Rectangle();
hbox.setAlignment(Pos.BOTTOM_CENTER);
hbox.setStyle("-fx-border-color: green;");
rect.setFill(Color.TRANSPARENT);
hbox.setPadding(new Insets(10,10,10,10));
hbox.setMargin(rect, new Insets(20,30,40,50));
// add result label & checkout button
Label result = new Label("Total: $0.00");
result.setAlignment(Pos.CENTER);
Button btAdd = new Button("Checkout");
hbox.getChildren().addAll(rect, result, btAdd);
btAdd.setOnAction(e ->{
Double AppleValue = Double.valueOf(tf1.getText());
Double AppricotValue = Double.valueOf(tf2.getText());
Double BananaValue = Double.valueOf(tf3.getText());
Double CherryValue = Double.valueOf(tf4.getText());
Double GrapeValue = Double.valueOf(tf5.getText());
Double LemonValue = Double.valueOf(tf6.getText());
Double OrangeValue = Double.valueOf(tf7.getText());
Double PearValue = Double.valueOf(tf8.getText());
Double StrawberryValue = Double.valueOf(tf9.getText());
Double WatermelonValue = Double.valueOf(tf10.getText());
Double r = (AppleValue * 0.99) + (AppricotValue * 1.49) + (BananaValue * 0.49) +
(CherryValue * 1.99) + (GrapeValue * 0.99)+ (LemonValue * 1.99)+
(OrangeValue * 0.99)+ (PearValue * 1.49)+ (StrawberryValue * 1.99) +
(WatermelonValue * 0.99);
result.setText("$ " + r.toString());
});
// Window title
Scene scene = new Scene(border);
primaryStage.setTitle("Anna's Fresh Market");
primaryStage.setScene(scene);
primaryStage.setResizable(true);
primaryStage.show();
}
}
Since you asked about "cleaner coding", I have these suggestions:
I couldn't figure out what
rect
was for since you created it with no size, but I put theresults
in an HBox and gave it a border, in case that was what you were going for.You created ColumnConstraints, but didn't use them.
Just sorting out those issues, cuts your code by nearly 1/2 and makes it a lot easier to follow (I had to change all your images to "flag" since I didn't have your image files):
The biggest issue I see is that you're treating the whole screen like one big monolithic structure. Your GridPane has 30 individual elements in it, but it's actual just 10 smaller structures each with three elements in it. You can avoid a ton of repetition and make the structure much more coherent by creating a custom widget (I used an extension of HBox that I called "FruitBox") to hold the your Image/Label/TextField triplets and then just put those in the pane.
Once you've rethought it from 30 widgets in a GridPane to just 10, you should realize that FlowPane is a better layout container than GridPane. Then you don't need to keep track of rows and columns.
Next, you've got the prices hard-coded as String and Double and mingled up with your layout. I've treated them more like data, and the layout for the FruitBox converts it to a String for the display. FruitBox is the only thing that has a reference to the TextField, and it has a method called
getAmount()
that will multiply the price times the number in the TextField.Even though the price/image info is still hard-coded, it's now treated a little more like data now.
Finally, it's easier to see how things go together when you split out all of the setup work for each section of the BorderPane into their own methods. It also makes it easier to get away from the monolithic design when you break it down this way.
If it was me, I'd get rid of all of the in-line styling and create a CSS for the scene and use it.
This is my refactoring into a non-monolithic design. I hope you find it interesting, if not useful: