Feature/restaurant page#81
Conversation
📝 WalkthroughWalkthroughCentralizes restaurant data via RestaurantHandler, enhances restaurant-detail UI and image loading, replaces booking-view.fxml with a new booking-form.fxml, updates main view layout, and tweaks scene size and CSS. Changes affect controllers, FXML, image handling, and restaurant card rendering. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧹 Recent nitpick comments
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🧬 Code graph analysis (1)src/main/java/frontend/view/RestaurantCard.java (1)
🔇 Additional comments (2)
✏️ Tip: You can disable this entire section by setting Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/frontend/controller/RestaurantController.java (1)
38-46: NullPointerException when restaurant is null.
setRestaurantData(restaurant)is called outside the null check on line 41. Ifrestaurantis null, line 49 (restaurant.getName()) will throw an NPE.Additionally,
restaurantName.setText()is called twice (lines 42 and 49) - the first call is redundant.🐛 Proposed fix
`@FXML` private void initialize() { restaurant = RestaurantHandler.getCurrentRestaurant(); if (restaurant != null) { - restaurantName.setText(restaurant.getName()); + setRestaurantData(restaurant); } - - setRestaurantData(restaurant); }
🤖 Fix all issues with AI agents
In `@src/main/java/frontend/controller/RestaurantController.java`:
- Around line 48-60: setRestaurantData may pass a null Image from
ImageHandler.getRestaurantImage into ImageHandler.scaleAndCropImage causing an
NPE; update setRestaurantData to capture the result of
ImageHandler.getRestaurantImage(restaurant) into a local Image variable (or
check restaurantImage.getImage()), check for null and if null either set a
fallback placeholder Image or skip calling ImageHandler.scaleAndCropImage, then
call restaurantImage.setImage(...) only with a non-null Image; ensure
javafx.scene.image.Image is imported if not already.
In `@src/main/java/frontend/model/ImageHandler.java`:
- Around line 35-44: getRestaurantImage currently returns null on failure which
causes NPEs when callers like RestaurantCard call scaleAndCropImage; change
getRestaurantImage to return a non-null fallback Image instead of null (e.g.,
load a bundled placeholder resource such as "/images/placeholder.png" and return
that when Objects.requireNonNull or resource loading fails), ensure the method
still logs the error, and leave scaleAndCropImage and RestaurantCard unchanged;
alternatively, if you prefer explicit handling, throw a custom unchecked
ImageLoadException from getRestaurantImage and update RestaurantCard to catch it
and handle the fallback there (use the symbols getRestaurantImage,
scaleAndCropImage, RestaurantCard).
In `@src/main/java/frontend/view/RestaurantCard.java`:
- Around line 25-37: ImageHandler.getRestaurantImage(restaurant) can return null
causing ImageHandler.scaleAndCropImage(view,...) to NPE; update RestaurantCard
to check the returned Image before calling scaleAndCropImage: call
ImageHandler.getRestaurantImage(restaurant) into a local variable, if it's null
set view to a default/placeholder Image (or skip scaling) and only call
ImageHandler.scaleAndCropImage(view, 100, 150) and apply the Rectangle clip when
the Image is non-null; ensure the local variable and ImageView "view" are used
so you don't call scaleAndCropImage or access image properties on a null image.
In `@src/main/resources/frontend/restaurant-view.fxml`:
- Around line 26-27: The fx:id values in the FXML contain a typo: rename fx:id
"adressIcon" to "addressIcon" and "restaurantAdress" to "restaurantAddress" in
the restaurant-view.fxml, and update the corresponding field names and any `@FXML`
injections/method references in RestaurantController.java (e.g., rename
fields/methods referencing adressIcon and restaurantAdress to addressIcon and
restaurantAddress) to keep identifiers consistent and restore bindings.
🧹 Nitpick comments (6)
src/main/java/frontend/controller/BookingController.java (2)
16-16: Potential null reference if timing is incorrect.The
restaurantfield is initialized at declaration time, which occurs when the FXML is loaded. IfRestaurantHandler.setCurrentRestaurant()hasn't been called before this controller is instantiated,restaurantwill benull, causing aNullPointerExceptioninBookTable().Consider moving initialization to the
initialize()method to ensure it occurs at a predictable point:Proposed fix
- private Restaurant restaurant = RestaurantHandler.getCurrentRestaurant(); + private Restaurant restaurant;Then in
initialize():`@FXML` private void initialize() { restaurant = RestaurantHandler.getCurrentRestaurant(); // ... existing code }
78-81: Remove commented-out dead code.Commented-out code adds noise and reduces readability. Since the setter pattern has been intentionally replaced with
RestaurantHandler, this dead code should be removed entirely.Proposed fix
- -// public void setRestaurant(Restaurant restaurant) { -// this.restaurant = restaurant; -// }src/main/resources/frontend/booking-form.fxml (1)
38-38: Consider following Java naming conventions for methods.The action handler
#BookTableuses PascalCase, but Java convention for methods is camelCase (#bookTable). While this works functionally, it's inconsistent with standard Java naming conventions.Proposed fix
In
booking-form.fxml:- <Button text="Book" onAction="#BookTable" prefWidth="100" styleClass="bookingForm-Button"/> + <Button text="Book" onAction="#bookTable" prefWidth="100" styleClass="bookingForm-Button"/>In
BookingController.java:- private void BookTable() { + private void bookTable() {src/main/java/frontend/model/ImageHandler.java (2)
3-10: Remove unused imports.
RestaurantCard(line 4) andRectangle(line 8) are imported but not used in this file.Proposed fix
import backend.entities.Restaurant; -import frontend.view.RestaurantCard; import javafx.geometry.Rectangle2D; import javafx.scene.image.Image; import javafx.scene.image.ImageView; -import javafx.scene.shape.Rectangle;
40-41: Consider using a logging framework instead of System.out.Using
System.out.printlnande.printStackTrace()for error handling is not ideal for production code. Consider using a logging framework (e.g., SLF4J, java.util.logging) for better control over log levels and output.src/main/resources/frontend/restaurant-view.fxml (1)
6-9: Unused import.The
javafx.scene.image.Imageimport on line 8 appears unused in this FXML file. TheImageViewis used, butImageobjects are set programmatically in the controller.♻️ Proposed fix
<?import javafx.geometry.Insets?> <?import javafx.scene.image.ImageView?> -<?import javafx.scene.image.Image?>
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/main/java/frontend/HelloFX.javasrc/main/java/frontend/controller/BookingController.javasrc/main/java/frontend/controller/MainController.javasrc/main/java/frontend/controller/RestaurantController.javasrc/main/java/frontend/model/ImageHandler.javasrc/main/java/frontend/view/RestaurantCard.javasrc/main/resources/frontend/application.csssrc/main/resources/frontend/booking-form.fxmlsrc/main/resources/frontend/booking-view.fxmlsrc/main/resources/frontend/main-view.fxmlsrc/main/resources/frontend/restaurant-view.fxml
💤 Files with no reviewable changes (1)
- src/main/resources/frontend/booking-view.fxml
🧰 Additional context used
🧬 Code graph analysis (4)
src/main/java/frontend/model/ImageHandler.java (1)
src/main/java/frontend/view/RestaurantCard.java (1)
RestaurantCard(15-54)
src/main/java/frontend/controller/BookingController.java (1)
src/main/java/frontend/model/RestaurantHandler.java (1)
RestaurantHandler(8-29)
src/main/java/frontend/controller/RestaurantController.java (1)
src/main/java/frontend/model/ImageHandler.java (1)
ImageHandler(12-46)
src/main/java/frontend/view/RestaurantCard.java (1)
src/main/java/frontend/model/ImageHandler.java (1)
ImageHandler(12-46)
🪛 Biome (2.1.2)
src/main/resources/frontend/application.css
[error] 28-28: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 29-29: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 30-30: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 31-31: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 34-34: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 35-35: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 36-36: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 37-37: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 40-40: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 41-41: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 42-42: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 43-43: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 48-48: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 49-49: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 50-50: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 53-53: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 54-54: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 57-57: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 58-58: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 61-61: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 62-62: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 63-63: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 66-66: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 67-67: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 70-70: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 71-71: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
[error] 72-72: Unknown property is not allowed.
See CSS Specifications and browser specific properties for more details.
To resolve this issue, replace the unknown property with a valid CSS property.
(lint/correctness/noUnknownProperty)
🔇 Additional comments (6)
src/main/java/frontend/HelloFX.java (1)
19-19: LGTM!The scene size adjustment to 680x500 accommodates the expanded UI layout changes in this PR.
src/main/resources/frontend/application.css (1)
26-74: LGTM! New styling is well-organized.The new CSS classes for the restaurant page and booking form are properly structured with clear section comments.
Note: The static analysis warnings from Biome are false positives — Biome is a web CSS linter that doesn't recognize JavaFX-specific
-fx-prefixed properties (like-fx-font-family,-fx-padding,-fx-text-fill). These are valid and correct for JavaFX CSS.src/main/resources/frontend/booking-form.fxml (1)
1-41: LGTM! Well-structured booking form layout.The FXML structure is clean with proper use of layout containers, style classes, and FXML bindings. All
fx:idvalues correctly correspond to the@FXMLannotated fields inBookingController.src/main/java/frontend/controller/MainController.java (1)
25-26: LGTM!The new
mainAreaVBox field is properly injected and passed toRestaurantCardfor scene navigation context, whilerestaurantContainercorrectly remains the visual container for displaying cards.Also applies to: 48-49
src/main/resources/frontend/main-view.fxml (1)
22-31: LGTM!The restructured layout correctly nests
restaurantContainerinsidemainArea, aligning with the controller changes wheremainAreais passed toRestaurantCardfor scene navigation.src/main/resources/frontend/restaurant-view.fxml (1)
9-40: Layout structure looks good.The restructured layout with HBox root, nested VBox for content, spacer pane, and included booking form is well-organized and aligns with the controller changes.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| private void setRestaurantData(Restaurant restaurant){ | ||
| restaurantName.setText(restaurant.getName()); | ||
| adressIcon.setText("📍"); | ||
| restaurantAdress.setText(restaurant.getAddress()); | ||
| categoryIcon.setText("🍴"); | ||
| restaurantCategory.setText(restaurant.getCategory()); | ||
| meanPriceIcon.setText("$"); | ||
| restaurantMeanPrice.setText(restaurant.getMeanPrice().toString() + " kr"); | ||
| ratingIcon.setText("⭐ "); | ||
| restaurantRating.setText(String.valueOf(restaurant.getRating())); | ||
| restaurantImage.setImage(ImageHandler.getRestaurantImage(restaurant)); | ||
| ImageHandler.scaleAndCropImage(restaurantImage, 250, 350); | ||
| } |
There was a problem hiding this comment.
Potential NullPointerException if image loading fails.
Same issue as in RestaurantCard: ImageHandler.getRestaurantImage() can return null, which will cause an NPE in scaleAndCropImage().
🛠️ Proposed fix
- restaurantImage.setImage(ImageHandler.getRestaurantImage(restaurant));
- ImageHandler.scaleAndCropImage(restaurantImage, 250, 350);
+ Image image = ImageHandler.getRestaurantImage(restaurant);
+ if (image != null) {
+ restaurantImage.setImage(image);
+ ImageHandler.scaleAndCropImage(restaurantImage, 250, 350);
+ }Note: You'll need to add import javafx.scene.image.Image; if not already imported via the wildcard.
🤖 Prompt for AI Agents
In `@src/main/java/frontend/controller/RestaurantController.java` around lines 48
- 60, setRestaurantData may pass a null Image from
ImageHandler.getRestaurantImage into ImageHandler.scaleAndCropImage causing an
NPE; update setRestaurantData to capture the result of
ImageHandler.getRestaurantImage(restaurant) into a local Image variable (or
check restaurantImage.getImage()), check for null and if null either set a
fallback placeholder Image or skip calling ImageHandler.scaleAndCropImage, then
call restaurantImage.setImage(...) only with a non-null Image; ensure
javafx.scene.image.Image is imported if not already.
| public static Image getRestaurantImage(Restaurant restaurant) { | ||
| String imagePath = "/images/" + restaurant.getImagePath(); | ||
| try { | ||
| return new Image(Objects.requireNonNull(ImageHandler.class.getResourceAsStream(imagePath))); | ||
| } catch (Exception e) { | ||
| System.out.println("Could not find: " + imagePath); | ||
| e.printStackTrace(); | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
Returning null will cause NPE in downstream callers.
When image loading fails, this method returns null. However, RestaurantCard (line 25-26 in the relevant snippet) calls scaleAndCropImage() immediately after, which accesses image.getWidth() on line 16 of this file — causing a NullPointerException.
Consider either:
- Return a placeholder/fallback image instead of null
- Throw a custom exception to force callers to handle the error explicitly
- Document the null return and update callers to handle it
Option 1: Return a placeholder image (preferred)
public static Image getRestaurantImage(Restaurant restaurant) {
String imagePath = "/images/" + restaurant.getImagePath();
try {
return new Image(Objects.requireNonNull(ImageHandler.class.getResourceAsStream(imagePath)));
} catch (Exception e) {
System.out.println("Could not find: " + imagePath);
e.printStackTrace();
- return null;
+ // Return a placeholder image or handle gracefully
+ return new Image(Objects.requireNonNull(ImageHandler.class.getResourceAsStream("/images/placeholder.png")));
}
}Option 2: Add null guard in RestaurantCard
In RestaurantCard.java:
Image image = ImageHandler.getRestaurantImage(restaurant);
if (image != null) {
view.setImage(image);
ImageHandler.scaleAndCropImage(view, 100, 150);
}🤖 Prompt for AI Agents
In `@src/main/java/frontend/model/ImageHandler.java` around lines 35 - 44,
getRestaurantImage currently returns null on failure which causes NPEs when
callers like RestaurantCard call scaleAndCropImage; change getRestaurantImage to
return a non-null fallback Image instead of null (e.g., load a bundled
placeholder resource such as "/images/placeholder.png" and return that when
Objects.requireNonNull or resource loading fails), ensure the method still logs
the error, and leave scaleAndCropImage and RestaurantCard unchanged;
alternatively, if you prefer explicit handling, throw a custom unchecked
ImageLoadException from getRestaurantImage and update RestaurantCard to catch it
and handle the fallback there (use the symbols getRestaurantImage,
scaleAndCropImage, RestaurantCard).
| ImageView view = new ImageView(); | ||
| view.setImage(ImageHandler.getRestaurantImage(restaurant)); | ||
| ImageHandler.scaleAndCropImage(view, 100, 150); | ||
|
|
||
| //Rounds upper two corners of image, so it matches corners of VBox (container) | ||
| Rectangle clip = new Rectangle(); | ||
| clip.widthProperty().bind(view.fitWidthProperty()); | ||
| clip.heightProperty().bind(view.fitHeightProperty().add(50)); | ||
| clip.setArcWidth(30); | ||
| clip.setArcHeight(30); | ||
|
|
||
| view.setClip(clip); | ||
| this.getChildren().add(view); |
There was a problem hiding this comment.
Potential NullPointerException if image loading fails.
ImageHandler.getRestaurantImage() returns null when the image cannot be found (see ImageHandler.java). If this happens, scaleAndCropImage() will throw an NPE when accessing image.getWidth() on the null image.
🛠️ Proposed fix
ImageView view = new ImageView();
- view.setImage(ImageHandler.getRestaurantImage(restaurant));
- ImageHandler.scaleAndCropImage(view, 100, 150);
+ Image image = ImageHandler.getRestaurantImage(restaurant);
+ if (image != null) {
+ view.setImage(image);
+ ImageHandler.scaleAndCropImage(view, 100, 150);
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ImageView view = new ImageView(); | |
| view.setImage(ImageHandler.getRestaurantImage(restaurant)); | |
| ImageHandler.scaleAndCropImage(view, 100, 150); | |
| //Rounds upper two corners of image, so it matches corners of VBox (container) | |
| Rectangle clip = new Rectangle(); | |
| clip.widthProperty().bind(view.fitWidthProperty()); | |
| clip.heightProperty().bind(view.fitHeightProperty().add(50)); | |
| clip.setArcWidth(30); | |
| clip.setArcHeight(30); | |
| view.setClip(clip); | |
| this.getChildren().add(view); | |
| ImageView view = new ImageView(); | |
| Image image = ImageHandler.getRestaurantImage(restaurant); | |
| if (image != null) { | |
| view.setImage(image); | |
| ImageHandler.scaleAndCropImage(view, 100, 150); | |
| } | |
| //Rounds upper two corners of image, so it matches corners of VBox (container) | |
| Rectangle clip = new Rectangle(); | |
| clip.widthProperty().bind(view.fitWidthProperty()); | |
| clip.heightProperty().bind(view.fitHeightProperty().add(50)); | |
| clip.setArcWidth(30); | |
| clip.setArcHeight(30); | |
| view.setClip(clip); | |
| this.getChildren().add(view); |
🤖 Prompt for AI Agents
In `@src/main/java/frontend/view/RestaurantCard.java` around lines 25 - 37,
ImageHandler.getRestaurantImage(restaurant) can return null causing
ImageHandler.scaleAndCropImage(view,...) to NPE; update RestaurantCard to check
the returned Image before calling scaleAndCropImage: call
ImageHandler.getRestaurantImage(restaurant) into a local variable, if it's null
set view to a default/placeholder Image (or skip scaling) and only call
ImageHandler.scaleAndCropImage(view, 100, 150) and apply the Rectangle clip when
the Image is non-null; ensure the local variable and ImageView "view" are used
so you don't call scaleAndCropImage or access image properties on a null image.
| <Label fx:id="adressIcon" styleClass="restaurantPage-Icon"/> | ||
| <Label fx:id="restaurantAdress" styleClass="restaurantPage-Info"/> |
There was a problem hiding this comment.
Typo: "adress" should be "address".
The fx:id values adressIcon and restaurantAdress contain a spelling error. This should be addressIcon and restaurantAddress for consistency and clarity. The corresponding fields in RestaurantController.java would also need to be renamed.
🤖 Prompt for AI Agents
In `@src/main/resources/frontend/restaurant-view.fxml` around lines 26 - 27, The
fx:id values in the FXML contain a typo: rename fx:id "adressIcon" to
"addressIcon" and "restaurantAdress" to "restaurantAddress" in the
restaurant-view.fxml, and update the corresponding field names and any `@FXML`
injections/method references in RestaurantController.java (e.g., rename
fields/methods referencing adressIcon and restaurantAdress to addressIcon and
restaurantAddress) to keep identifiers consistent and restore bindings.
Summary by CodeRabbit
New Features
Style
✏️ Tip: You can customize this high-level summary in your review settings.