Files
Progetto-ingegneria-del-sof…/deliverables/Coverage/htmlReport/ns-12/sources/source-3.html
T
2026-06-19 21:50:38 +02:00

499 lines
24 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html id="htmlId">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Coverage Report > LeaderboardFXMLController</title>
<style type="text/css">
@import "../../css/coverage.css";
@import "../../css/idea.min.css";
</style>
<script type="text/javascript" src="../../js/highlight.min.js"></script>
<script type="text/javascript" src="../../js/highlightjs-line-numbers.min.js"></script>
</head>
<body>
<div class="content">
<div class="breadCrumbs">
Current scope: <a href="../../index.html">all classes</a>
<span class="separator">|</span>
<a href="../index.html">it.polimi.ingsw.gc14.View.GUI</a>
</div>
<h1>Coverage Summary for Class: LeaderboardFXMLController (it.polimi.ingsw.gc14.View.GUI)</h1>
<table class="coverageStats">
<tr>
<th class="name">Class</th>
<th class="coverageStat
">
Class, %
</th>
<th class="coverageStat
">
Method, %
</th>
<th class="coverageStat
">
Branch, %
</th>
<th class="coverageStat
">
Line, %
</th>
</tr>
<tr>
<td class="name">LeaderboardFXMLController</td>
<td class="coverageStat">
<span class="percent">
0%
</span>
<span class="absValue">
(0/1)
</span>
</td>
<td class="coverageStat">
<span class="percent">
0%
</span>
<span class="absValue">
(0/19)
</span>
</td>
<td class="coverageStat">
<span class="percent">
0%
</span>
<span class="absValue">
(0/34)
</span>
</td>
<td class="coverageStat">
<span class="percent">
0%
</span>
<span class="absValue">
(0/182)
</span>
</td>
</tr>
</table>
<br/>
<br/>
<pre>
<code class="sourceCode" id="sourceCode">&nbsp;package it.polimi.ingsw.gc14.View.GUI;
&nbsp;
&nbsp;import it.polimi.ingsw.gc14.Controller.ClientController;
&nbsp;import it.polimi.ingsw.gc14.Model.Player;
&nbsp;import javafx.animation.ScaleTransition;
&nbsp;import it.polimi.ingsw.gc14.Model.PlayableCard;
&nbsp;import javafx.event.Event;
&nbsp;import javafx.fxml.FXML;
&nbsp;import javafx.scene.Scene;
&nbsp;import javafx.scene.control.ScrollPane;
&nbsp;import javafx.stage.Popup;
&nbsp;import javafx.geometry.Insets;
&nbsp;import javafx.geometry.Pos;
&nbsp;import javafx.scene.Cursor;
&nbsp;import javafx.scene.Node;
&nbsp;import javafx.scene.control.Label;
&nbsp;import javafx.scene.effect.DropShadow;
&nbsp;import javafx.scene.image.Image;
&nbsp;import javafx.scene.image.ImageView;
&nbsp;import javafx.scene.input.MouseEvent;
&nbsp;import javafx.scene.layout.*;
&nbsp;import javafx.scene.paint.Color;
&nbsp;import javafx.scene.paint.LinearGradient;
&nbsp;import javafx.scene.paint.Stop;
&nbsp;import javafx.scene.paint.CycleMethod;
&nbsp;import javafx.scene.text.Font;
&nbsp;import javafx.stage.Stage;
&nbsp;import javafx.stage.Window;
&nbsp;import javafx.util.Duration;
&nbsp;
&nbsp;import java.util.*;
&nbsp;
&nbsp;/**
&nbsp; * FXML controller for the end-of-game leaderboard scene.
&nbsp; *
&nbsp; * &lt;p&gt;Displays the final player rankings and a winner/game-over banner.
&nbsp; */
<b class="nc">&nbsp;public class LeaderboardFXMLController {</b>
&nbsp;
&nbsp; @FXML private StackPane rootPane;
&nbsp; @FXML private VBox mainVBox;
&nbsp; @FXML private VBox rankingList;
&nbsp; // title label removed; outcome text is added dynamically in render()
&nbsp; //TODO
&nbsp; private ClientController controller;
&nbsp; //TODO
&nbsp; private Popup popup;
&nbsp; //TODO
&nbsp; private VBox popupContent;
&nbsp; //TODO
<b class="nc">&nbsp; private static final Map&lt;String, Image&gt; imageCache = new HashMap&lt;&gt;();</b>
&nbsp; //TODO
&nbsp; private Scene loginScene;
&nbsp;
&nbsp; //TODO
&nbsp; private Runnable action;
&nbsp;
&nbsp; /** Returns a cached {@link Image} for the given classpath {@code path}, loading it on first access. */
&nbsp; private Image loadImage(String path) {
<b class="nc">&nbsp; return imageCache.computeIfAbsent(path,</b>
<b class="nc">&nbsp; p -&gt; new Image(getClass().getResourceAsStream(p)));</b>
&nbsp; }
&nbsp;
&nbsp;
&nbsp; /**
&nbsp; * Injects the client controller, a post-game action, and the login scene reference.
&nbsp; *
&nbsp; * @param controller the client controller.
&nbsp; * @param action the action to run when the player returns to the login screen.
&nbsp; * @param loginScene the login scene to show on exit.
&nbsp; */
&nbsp; public void setController(ClientController controller, Runnable action, Scene loginScene) {
<b class="nc">&nbsp; this.controller = controller;</b>
<b class="nc">&nbsp; this.loginScene = loginScene;</b>
<b class="nc">&nbsp; this.action = action;</b>
&nbsp; }
&nbsp;
&nbsp;
&nbsp; /** Initializes the scene: loads fonts, sets up the background, and initializes the popup. */
&nbsp; @FXML
&nbsp; public void initialize() {
<b class="nc">&nbsp; Font.loadFont(getClass().getResourceAsStream(&quot;/Fonts/InknutAntiqua-Regular.ttf&quot;), 14);</b>
<b class="nc">&nbsp; mainVBox.sceneProperty().addListener((obs, oldScene, newScene) -&gt; {</b>
<b class="nc">&nbsp; if (newScene != null) newScene.getRoot().applyCss();</b>
&nbsp; });
<b class="nc">&nbsp; renderBackground();</b>
<b class="nc">&nbsp; initPopup();</b>
&nbsp; }
&nbsp;
&nbsp;
&nbsp; /** Populates the ranking list with the final player standings and shows the outcome banner. */
&nbsp; public void render() {
<b class="nc">&nbsp; rankingList.getChildren().clear();</b>
<b class="nc">&nbsp; if(!controller.getMiniModel().standingPlayers.isEmpty())</b>
&nbsp; {
<b class="nc">&nbsp; List&lt;Player&gt; sorted = controller.getMiniModel().standingPlayers;</b>
&nbsp;
<b class="nc">&nbsp; boolean iWon = sorted.get(0).getUserName().equals(controller.getMyUsername());</b>
&nbsp;
&nbsp; // Label grande Winner / Game Over
<b class="nc">&nbsp; Label outcomeLabel = new Label(iWon ? &quot;\uD83C\uDFC6 WINNER! \uD83C\uDFC6&quot; : &quot;GAME OVER&quot;);</b>
<b class="nc">&nbsp; outcomeLabel.setStyle(</b>
&nbsp; &quot;-fx-font-size: 64px;&quot; +
&nbsp; &quot;-fx-font-weight: bold;&quot; +
<b class="nc">&nbsp; &quot;-fx-text-fill: &quot; + (iWon ? &quot;#FFD700;&quot; : &quot;#FF4444;&quot;)</b>
&nbsp; );
<b class="nc">&nbsp; DropShadow glow = new DropShadow();</b>
<b class="nc">&nbsp; glow.setColor(iWon ? Color.rgb(255, 200, 0, 0.95) : Color.rgb(220, 0, 0, 0.95));</b>
<b class="nc">&nbsp; glow.setRadius(35);</b>
<b class="nc">&nbsp; glow.setSpread(0.35);</b>
<b class="nc">&nbsp; outcomeLabel.setEffect(glow);</b>
<b class="nc">&nbsp; rankingList.getChildren().add(outcomeLabel);</b>
&nbsp;
<b class="nc">&nbsp; Region sep = new Region();</b>
<b class="nc">&nbsp; sep.setPrefHeight(16);</b>
<b class="nc">&nbsp; rankingList.getChildren().add(sep);</b>
&nbsp;
<b class="nc">&nbsp; for (int i = 0; i &lt; sorted.size(); i++) {</b>
<b class="nc">&nbsp; rankingList.getChildren().add(createPlayerRow(i + 1, sorted.get(i)));</b>
&nbsp; }
&nbsp; }
&nbsp; }
&nbsp;
&nbsp;
&nbsp; // ==== EFFECTS ====
&nbsp; /** Scales {@code node} to 1.02× on hover and sets a hand cursor. */
&nbsp; private void addHoverZoom(Node node) {
<b class="nc">&nbsp; ScaleTransition scaleUp = new ScaleTransition(Duration.millis(150), node);</b>
<b class="nc">&nbsp; scaleUp.setToX(1.02);</b>
<b class="nc">&nbsp; scaleUp.setToY(1.02);</b>
<b class="nc">&nbsp; ScaleTransition scaleDown = new ScaleTransition(Duration.millis(150), node);</b>
<b class="nc">&nbsp; scaleDown.setToX(1.0);</b>
<b class="nc">&nbsp; scaleDown.setToY(1.0);</b>
<b class="nc">&nbsp; node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -&gt; { scaleUp.play(); node.setCursor(Cursor.HAND); });</b>
<b class="nc">&nbsp; node.addEventHandler(MouseEvent.MOUSE_EXITED, e -&gt; { scaleDown.play(); node.setCursor(Cursor.DEFAULT); });</b>
&nbsp; }
&nbsp;
&nbsp; /** Applies a static drop-shadow to {@code node}. */
&nbsp; private void addShadow(Node node) {
<b class="nc">&nbsp; DropShadow shadow = new DropShadow();</b>
<b class="nc">&nbsp; shadow.setColor(Color.rgb(0, 0, 0, 0.6));</b>
<b class="nc">&nbsp; shadow.setRadius(12);</b>
<b class="nc">&nbsp; shadow.setOffsetX(3);</b>
<b class="nc">&nbsp; shadow.setOffsetY(3);</b>
<b class="nc">&nbsp; node.setEffect(shadow);</b>
&nbsp; }
&nbsp;
&nbsp;
&nbsp; // ==== ROW ====
&nbsp; /** Builds a styled leaderboard row showing rank, totem, username, stats, and prestige for {@code player}. */
&nbsp; private HBox createPlayerRow(int position, Player player) {
<b class="nc">&nbsp; HBox row = new HBox(20);</b>
<b class="nc">&nbsp; row.setAlignment(Pos.CENTER_LEFT);</b>
<b class="nc">&nbsp; row.setPadding(new Insets(14, 28, 14, 28));</b>
<b class="nc">&nbsp; row.setMaxWidth(Double.MAX_VALUE);</b>
&nbsp;
<b class="nc">&nbsp; LinearGradient gradient = new LinearGradient(</b>
&nbsp; 0, 0, 1, 0, true, CycleMethod.NO_CYCLE,
<b class="nc">&nbsp; new Stop(0.0, Color.rgb(0, 0, 0, 0.75)),</b>
<b class="nc">&nbsp; new Stop(0.5, Color.rgb(0, 0, 0, 0.60)),</b>
<b class="nc">&nbsp; new Stop(1.0, Color.rgb(0, 0, 0, 0.75))</b>
&nbsp; );
<b class="nc">&nbsp; row.setBackground(new Background(new BackgroundFill(</b>
&nbsp; gradient,
&nbsp; new CornerRadii(12),
&nbsp; Insets.EMPTY
&nbsp; )));
<b class="nc">&nbsp; addShadow(row);</b>
<b class="nc">&nbsp; addHoverZoom(row);</b>
&nbsp;
<b class="nc">&nbsp; Label posLabel = new Label(position + &quot;°&quot;);</b>
<b class="nc">&nbsp; posLabel.setMinWidth(55);</b>
<b class="nc">&nbsp; String medalColor = switch (position) {</b>
<b class="nc">&nbsp; case 1 -&gt; &quot;#FFD700&quot;; // oro</b>
<b class="nc">&nbsp; case 2 -&gt; &quot;#C0C0C0&quot;; // argento</b>
<b class="nc">&nbsp; case 3 -&gt; &quot;#CD7F32&quot;; // bronzo</b>
<b class="nc">&nbsp; default -&gt; &quot;#EEEEEE&quot;;</b>
<b class="nc">&nbsp; };</b>
<b class="nc">&nbsp; posLabel.setStyle(&quot;-fx-font-size: 28px; -fx-font-weight: bold; -fx-text-fill: &quot; + medalColor + &quot;;&quot;);</b>
&nbsp;
&nbsp;
<b class="nc">&nbsp; ImageView totem = new ImageView(loadImage(</b>
<b class="nc">&nbsp; &quot;/GUIImages/Totems/totem_&quot; + player.getTotem().toString().toLowerCase(Locale.ROOT) + &quot;.png&quot;));</b>
<b class="nc">&nbsp; totem.setFitHeight(55);</b>
<b class="nc">&nbsp; totem.setPreserveRatio(true);</b>
&nbsp;
<b class="nc">&nbsp; Label nameLabel = new Label(player.getUserName());</b>
<b class="nc">&nbsp; nameLabel.setStyle(</b>
&nbsp; &quot;-fx-font-size: 22px; -fx-font-weight: bold; -fx-text-fill: &quot; +
<b class="nc">&nbsp; (player.getUserName().equals(controller.getMyUsername()) ? &quot;#ff6b6b;&quot; : &quot;#FFFFFF;&quot;)</b>
&nbsp; );
<b class="nc">&nbsp; HBox.setHgrow(nameLabel, Priority.ALWAYS);</b>
&nbsp;
<b class="nc">&nbsp; HBox stats = createStatsBox(player);</b>
&nbsp;
<b class="nc">&nbsp; HBox ppBox = new HBox(6);</b>
<b class="nc">&nbsp; ppBox.setAlignment(Pos.CENTER);</b>
<b class="nc">&nbsp; ImageView ppIcon = new ImageView(loadImage(&quot;/GUIImages/Icons/PrestigePoint.png&quot;));</b>
<b class="nc">&nbsp; ppIcon.setFitHeight(45);</b>
<b class="nc">&nbsp; ppIcon.setPreserveRatio(true);</b>
<b class="nc">&nbsp; Label ppLabel = new Label(String.valueOf(player.getPrestigeValue()));</b>
<b class="nc">&nbsp; ppLabel.setStyle(&quot;-fx-font-size: 28px; -fx-font-weight: bold; -fx-text-fill: #FFD700;&quot;);</b>
<b class="nc">&nbsp; ppBox.getChildren().addAll(ppIcon, ppLabel);</b>
&nbsp;
<b class="nc">&nbsp; row.getChildren().addAll(posLabel, totem, nameLabel, stats, ppBox);</b>
<b class="nc">&nbsp; row.setOnMouseClicked(e -&gt; openPlayerPopup(player));</b>
<b class="nc">&nbsp; return row;</b>
&nbsp; }
&nbsp;
&nbsp; /** Creates a compact icon+count stats strip for all card types of {@code player}. */
&nbsp; private HBox createStatsBox(Player player) {
<b class="nc">&nbsp; HBox stats = new HBox(14);</b>
<b class="nc">&nbsp; stats.setAlignment(Pos.CENTER);</b>
&nbsp;
<b class="nc">&nbsp; stats.getChildren().add(createStatItem(&quot;/GUIImages/Icons/Food.png&quot;, String.valueOf(player.getFoodValue()), 26));</b>
<b class="nc">&nbsp; stats.getChildren().add(createStatItem(&quot;/GUIImages/Icons/Artist.png&quot;, String.valueOf(player.getArtists().size()), 26));</b>
<b class="nc">&nbsp; stats.getChildren().add(createStatItem(&quot;/GUIImages/Icons/Gatherer.png&quot;, String.valueOf(player.getGatherers().size()), 26));</b>
<b class="nc">&nbsp; stats.getChildren().add(createStatItem(&quot;/GUIImages/Icons/Inventor.png&quot;, String.valueOf(player.getInventors().size()), 26));</b>
<b class="nc">&nbsp; stats.getChildren().add(createStatItem(&quot;/GUIImages/Icons/Builder.png&quot;, String.valueOf(player.getBuilders().size()), 26));</b>
<b class="nc">&nbsp; stats.getChildren().add(createStatItem(&quot;/GUIImages/Icons/Shaman.png&quot;, String.valueOf(player.getShamans().size()), 26));</b>
<b class="nc">&nbsp; stats.getChildren().add(createStatItem(&quot;/GUIImages/Icons/Hunter.png&quot;, String.valueOf(player.getHunters().size()), 26));</b>
<b class="nc">&nbsp; stats.getChildren().add(createStatItem(&quot;/GUIImages/Icons/Building.png&quot;, String.valueOf(player.getBuildingCards().size()), 26));</b>
&nbsp;
<b class="nc">&nbsp; return stats;</b>
&nbsp; }
&nbsp;
&nbsp; /** Creates a single icon + label widget for one stat type. */
&nbsp; private HBox createStatItem(String iconPath, String value, double iconHeight) {
<b class="nc">&nbsp; HBox box = new HBox(4);</b>
<b class="nc">&nbsp; box.setAlignment(Pos.CENTER);</b>
<b class="nc">&nbsp; ImageView icon = new ImageView(loadImage(iconPath));</b>
<b class="nc">&nbsp; icon.setFitHeight(iconHeight);</b>
<b class="nc">&nbsp; icon.setPreserveRatio(true);</b>
<b class="nc">&nbsp; Label label = new Label(value);</b>
<b class="nc">&nbsp; label.setStyle(&quot;-fx-font-size: 16px; -fx-text-fill: #FFFFFF; -fx-font-weight: bold;&quot;);</b>
<b class="nc">&nbsp; DropShadow textShadow = new DropShadow();</b>
<b class="nc">&nbsp; textShadow.setColor(Color.rgb(0, 0, 0, 0.9));</b>
<b class="nc">&nbsp; textShadow.setRadius(4);</b>
<b class="nc">&nbsp; label.setEffect(textShadow);</b>
<b class="nc">&nbsp; box.getChildren().addAll(icon, label);</b>
<b class="nc">&nbsp; return box;</b>
&nbsp; }
&nbsp;
&nbsp;
&nbsp; // ==== POPUP ====
&nbsp; /** Creates and configures the auto-hiding player-detail popup. */
&nbsp; private void initPopup() {
<b class="nc">&nbsp; popupContent = new VBox(12);</b>
<b class="nc">&nbsp; popupContent.setAlignment(Pos.CENTER);</b>
<b class="nc">&nbsp; popupContent.setPadding(new Insets(16));</b>
<b class="nc">&nbsp; popupContent.setStyle(</b>
&nbsp; &quot;-fx-background-color: rgba(20,10,5,0.97);&quot; +
&nbsp; &quot;-fx-border-color: #8B4513;&quot; +
&nbsp; &quot;-fx-border-width: 3;&quot; +
&nbsp; &quot;-fx-border-radius: 14;&quot; +
&nbsp; &quot;-fx-background-radius: 14;&quot;
&nbsp; );
&nbsp;
<b class="nc">&nbsp; popup = new Popup();</b>
<b class="nc">&nbsp; popup.getContent().add(popupContent);</b>
<b class="nc">&nbsp; popup.setAutoHide(true);</b>
<b class="nc">&nbsp; popup.addEventHandler(Event.ANY, e -&gt; {</b>
<b class="nc">&nbsp; if (popup.getScene() != null) popup.getScene().setFill(Color.TRANSPARENT);</b>
&nbsp; });
&nbsp; }
&nbsp;
&nbsp; /** Opens the player-detail popup showing all cards held by {@code player}, grouped by type. */
&nbsp; private void openPlayerPopup(Player player) {
<b class="nc">&nbsp; popupContent.getChildren().clear();</b>
&nbsp;
<b class="nc">&nbsp; HBox header = new HBox(10);</b>
<b class="nc">&nbsp; header.setAlignment(Pos.CENTER);</b>
<b class="nc">&nbsp; ImageView totem = new ImageView(loadImage(</b>
<b class="nc">&nbsp; &quot;/GUIImages/Totems/totem_&quot; + player.getTotem().toString().toLowerCase(Locale.ROOT) + &quot;.png&quot;));</b>
<b class="nc">&nbsp; totem.setFitHeight(30);</b>
<b class="nc">&nbsp; totem.setPreserveRatio(true);</b>
<b class="nc">&nbsp; Label nameLabel = new Label(player.getUserName());</b>
<b class="nc">&nbsp; nameLabel.setStyle(&quot;-fx-font-size: 18px; -fx-font-weight: bold; -fx-text-fill: #FFD700;&quot;);</b>
<b class="nc">&nbsp; header.getChildren().addAll(totem, nameLabel);</b>
<b class="nc">&nbsp; popupContent.getChildren().add(header);</b>
&nbsp;
<b class="nc">&nbsp; String[][] types = {</b>
&nbsp; {&quot;Artist&quot;, &quot;artists&quot;},
&nbsp; {&quot;Gatherer&quot;, &quot;gatherers&quot;},
&nbsp; {&quot;Inventor&quot;, &quot;inventors&quot;},
&nbsp; {&quot;Builder&quot;, &quot;builders&quot;},
&nbsp; {&quot;Shaman&quot;, &quot;shamans&quot;},
&nbsp; {&quot;Hunter&quot;, &quot;hunters&quot;},
&nbsp; {&quot;Building&quot;, &quot;buildingCards&quot;}
&nbsp; };
&nbsp;
<b class="nc">&nbsp; VBox grid = new VBox(6);</b>
<b class="nc">&nbsp; grid.setAlignment(Pos.CENTER_LEFT);</b>
<b class="nc">&nbsp; boolean hasAnyCard = false;</b>
&nbsp;
<b class="nc">&nbsp; for (String[] type : types) {</b>
<b class="nc">&nbsp; String typeName = type[0];</b>
<b class="nc">&nbsp; String field = type[1];</b>
<b class="nc">&nbsp; ArrayList&lt;PlayableCard&gt; cards = getPlayerCards(player.getUserName(), field);</b>
<b class="nc">&nbsp; if (cards.isEmpty()) continue;</b>
<b class="nc">&nbsp; hasAnyCard = true;</b>
&nbsp;
<b class="nc">&nbsp; HBox row = new HBox(6);</b>
<b class="nc">&nbsp; row.setAlignment(Pos.CENTER_LEFT);</b>
&nbsp;
<b class="nc">&nbsp; ImageView typeIcon = new ImageView(loadImage(&quot;/GUIImages/Icons/&quot;+typeName+&quot;.png&quot;));</b>
<b class="nc">&nbsp; typeIcon.setFitHeight(22);</b>
<b class="nc">&nbsp; typeIcon.setPreserveRatio(true);</b>
<b class="nc">&nbsp; row.getChildren().add(typeIcon);</b>
&nbsp;
<b class="nc">&nbsp; for (PlayableCard card : cards) {</b>
<b class="nc">&nbsp; ImageView img = new ImageView(loadImage(&quot;/GUIImages/Fronts/card-&quot; + card.getIdIMG() + &quot;.png&quot;));</b>
<b class="nc">&nbsp; img.setFitHeight(230);</b>
<b class="nc">&nbsp; img.setPreserveRatio(true);</b>
<b class="nc">&nbsp; img.setCursor(Cursor.HAND);</b>
<b class="nc">&nbsp; row.getChildren().add(img);</b>
&nbsp; }
&nbsp;
<b class="nc">&nbsp; grid.getChildren().add(row);</b>
&nbsp; }
&nbsp;
<b class="nc">&nbsp; if (!hasAnyCard) {</b>
<b class="nc">&nbsp; Label empty = new Label(&quot;No cards&quot;);</b>
<b class="nc">&nbsp; empty.setStyle(&quot;-fx-font-size: 14px; -fx-text-fill: #888888;&quot;);</b>
<b class="nc">&nbsp; grid.getChildren().add(empty);</b>
&nbsp; }
&nbsp;
<b class="nc">&nbsp; ScrollPane scrollPane = new ScrollPane(grid);</b>
<b class="nc">&nbsp; scrollPane.setFitToWidth(true);</b>
<b class="nc">&nbsp; scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);</b>
<b class="nc">&nbsp; scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);</b>
<b class="nc">&nbsp; scrollPane.setStyle(&quot;-fx-background: transparent; -fx-background-color: transparent;&quot;);</b>
&nbsp;
<b class="nc">&nbsp; Window window = rootPane.getScene().getWindow();</b>
<b class="nc">&nbsp; scrollPane.setMaxHeight(window.getHeight() * 0.8); // cap scroll area to 80% of window height</b>
<b class="nc">&nbsp; popupContent.getChildren().add(scrollPane);</b>
<b class="nc">&nbsp; popup.show(window, 0, 0);</b>
<b class="nc">&nbsp; popup.getScene().setFill(Color.TRANSPARENT);</b>
<b class="nc">&nbsp; popup.setX(window.getX() + (window.getWidth() - popup.getWidth()) / 2);</b>
<b class="nc">&nbsp; popup.setY(window.getY() + (window.getHeight() - popup.getHeight()) / 2);</b>
&nbsp; }
&nbsp;
&nbsp; /** Returns a copy of the named card collection for {@code username}. */
&nbsp; private ArrayList&lt;PlayableCard&gt; getPlayerCards(String username, String type) {
<b class="nc">&nbsp; Player p = controller.getMiniModel().players.get(username);</b>
<b class="nc">&nbsp; return switch (type) {</b>
<b class="nc">&nbsp; case &quot;artists&quot; -&gt; new ArrayList&lt;&gt;(p.getArtists());</b>
<b class="nc">&nbsp; case &quot;gatherers&quot; -&gt; new ArrayList&lt;&gt;(p.getGatherers());</b>
<b class="nc">&nbsp; case &quot;inventors&quot; -&gt; new ArrayList&lt;&gt;(p.getInventors());</b>
<b class="nc">&nbsp; case &quot;builders&quot; -&gt; new ArrayList&lt;&gt;(p.getBuilders());</b>
<b class="nc">&nbsp; case &quot;shamans&quot; -&gt; new ArrayList&lt;&gt;(p.getShamans());</b>
<b class="nc">&nbsp; case &quot;hunters&quot; -&gt; new ArrayList&lt;&gt;(p.getHunters());</b>
<b class="nc">&nbsp; case &quot;buildingCards&quot; -&gt; new ArrayList&lt;&gt;(p.getBuildingCards());</b>
<b class="nc">&nbsp; default -&gt; new ArrayList&lt;&gt;();</b>
&nbsp; };
&nbsp; }
&nbsp;
&nbsp; // ==== BACKGROUND ====
&nbsp; /** Sets the full-cover background image on the root pane. */
&nbsp; private void renderBackground() {
<b class="nc">&nbsp; BackgroundSize size = new BackgroundSize(</b>
&nbsp; BackgroundSize.AUTO, BackgroundSize.AUTO,
&nbsp; false, false, true, true
&nbsp; );
<b class="nc">&nbsp; rootPane.setBackground(new Background(new BackgroundImage(</b>
<b class="nc">&nbsp; loadImage(&quot;/GUIImages/Background.png&quot;),</b>
&nbsp; BackgroundRepeat.NO_REPEAT,
&nbsp; BackgroundRepeat.NO_REPEAT,
&nbsp; BackgroundPosition.CENTER,
&nbsp; size
&nbsp; )));
&nbsp; }
&nbsp;
&nbsp;
&nbsp; // ==== ACTIONS ====
&nbsp; /** Disconnects the client and invokes the post-game action to return to the login scene. */
&nbsp; @FXML
&nbsp; private void onNewGame() {
<b class="nc">&nbsp; controller.disconnect();</b>
<b class="nc">&nbsp; action.run();</b>
&nbsp; }
&nbsp;}
</code>
</pre>
</div>
<script type="text/javascript">
(function() {
var msie = false, msie9 = false;
/*@cc_on
msie = true;
@if (@_jscript_version >= 9)
msie9 = true;
@end
@*/
if (!msie || msie && msie9) {
hljs.highlightAll()
hljs.initLineNumbersOnLoad();
}
})();
</script>
<div class="footer">
<div style="float:right;">generated on 2026-06-14 21:53</div>
</div>
</body>
</html>