Skip to content

Commit

Permalink
Merge pull request #65 from IDATT2003-Gruppe-53/64-searchfilter
Browse files Browse the repository at this point in the history
added search functionality to market, portfolio, and history
  • Loading branch information
arelod authored May 26, 2026
2 parents 4be2922 + ac1c1fd commit 27bb541
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 25 deletions.
45 changes: 38 additions & 7 deletions millions/src/main/java/no/ntnu/gruppe53/view/MarketView.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@
import java.math.RoundingMode;
import java.util.function.Consumer;

import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.layout.*;
import javafx.scene.chart.LineChart;
import javafx.util.Subscription;
import no.ntnu.gruppe53.model.*;
Expand Down Expand Up @@ -42,9 +40,11 @@ public class MarketView extends BorderPane {
public TextField gross;
public TextField commission;
public TextField total;
private TextField searchField;

//StockListView
private ListView<Stock> stocksListView;
private FilteredList<Stock> filteredStocksList;

//Input
private Spinner<Integer> quantitySpinner;
Expand Down Expand Up @@ -154,6 +154,21 @@ protected void updateItem(Stock stock, boolean empty) {
}
});

HBox searchBox = new HBox();
searchField = new TextField();
searchField.promptTextProperty().bind(lm.bindString("search"));
searchBox.setStyle("-fx-background-color: #ffe556;" +
"-fx-text-fill: #303539;" +
"-fx-background-radius: 8;" +
"-fx-border-color: #303539;" +
"-fx-border-radius: 8;"
);

searchBox.setPadding(new Insets(8, 14, 8, 14));
searchBox.setAlignment(Pos.CENTER_LEFT);
searchBox.setMaxWidth(Region.USE_PREF_SIZE);
searchBox.getChildren().addAll(searchField);


// Container for list of stocks
HBox stockListBox = new HBox(stocksListView);
Expand Down Expand Up @@ -254,7 +269,7 @@ protected void updateItem(Stock stock, boolean empty) {



vBox.getChildren().addAll(titleBox,
vBox.getChildren().addAll(titleBox, searchBox,
stockBox,
purchaseBox);

Expand Down Expand Up @@ -326,18 +341,34 @@ public void onQuantitySelect(Runnable action) {

/**
* Sets the exchange to use for the view.
* <p>Uses a {@link SortedList} to sort the stocks in the exchange alphabetically
* <p>Uses first a {@link FilteredList} to account for what the user has searched for. </p>
* <p>Then utilises a {@link SortedList} to sort the stocks in the exchange alphabetically
* on their symbol/ticker.</p>
*
* @param exchange the exchange to be used for the view
*/
public void setExchange(Exchange exchange) {
this.exchange = exchange;


if (exchange != null) {
SortedList<Stock> sortedStocks = new SortedList<>(exchange.getObservableStocks());
filteredStocksList = new FilteredList<>(exchange.getObservableStocks());

SortedList<Stock> sortedStocks = new SortedList<>(filteredStocksList);
sortedStocks.setComparator((s1, s2) -> s1.getSymbol().compareToIgnoreCase(s2.getSymbol()));

stocksListView.setItems(sortedStocks);

searchField.textProperty().addListener((observable, oldText, newText) -> {
String search = newText == null ? "" : newText.toLowerCase();

filteredStocksList.setPredicate(stock -> search.isBlank()
|| stock.getSymbol().toLowerCase().contains(search)
|| stock.getCompany().toLowerCase().contains(search)
);
});
}

}

/**
Expand Down
40 changes: 32 additions & 8 deletions millions/src/main/java/no/ntnu/gruppe53/view/PortfolioView.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
import java.util.function.Consumer;

import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.layout.*;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.util.Subscription;
Expand Down Expand Up @@ -56,9 +54,11 @@ public class PortfolioView extends BorderPane {
private TextField tax;
private TextField total;
private TextField profit;
private TextField searchField;

//PortfolioListView
private ListView<Share> portfolioListView;
private FilteredList<Share> filteredPortfolioList;

private Player player;
private SaleCalculator saleCalculator;
Expand Down Expand Up @@ -152,6 +152,21 @@ protected void updateItem(Share item, boolean empty) {
}
});

HBox searchBox = new HBox();
searchField = new TextField();
searchField.promptTextProperty().bind(lm.bindString("search"));
searchBox.setStyle("-fx-background-color: #ffe556;" +
"-fx-text-fill: #303539;" +
"-fx-background-radius: 8;" +
"-fx-border-color: #303539;" +
"-fx-border-radius: 8;"
);

searchBox.setPadding(new Insets(8, 14, 8, 14));
searchBox.setAlignment(Pos.CENTER_LEFT);
searchBox.setMaxWidth(Region.USE_PREF_SIZE);
searchBox.getChildren().addAll(searchField);

VBox portfolioListBox = new VBox(portfolioListView);
portfolioListBox.setStyle("-fx-background-color: #ffe556;" +
"-fx-text-fill: #303539;" +
Expand Down Expand Up @@ -231,7 +246,7 @@ protected void updateItem(Share item, boolean empty) {
saleBox.getChildren().addAll(selectedShareBox, calculationBox, totalBox, sellButton);


vBox.getChildren().addAll(titleBox,
vBox.getChildren().addAll(titleBox, searchBox,
portfolioListBox,
saleBox);
return vBox;
Expand Down Expand Up @@ -265,7 +280,7 @@ public Share getSelectedShare() {
/**
* Sets the player to be observed.
* <p>The values observed are the players portfolio and name.</p>
* <p>Uses an {@link ObservableList} to observe the shares and
* <p>Uses a {@link FilteredList} to get and filter the shares and
* binds it to the portfolioListView.</p>
*
* @param player the player to be observed
Expand All @@ -274,10 +289,19 @@ public void setPlayer(Player player) {
this.player = player;

if (player != null && player.getPortfolio() != null) {
ObservableList<Share> observableShares = player.getPortfolio().getShares();

portfolioListView.setItems(observableShares);
filteredPortfolioList = new FilteredList<>(player.getPortfolio().getShares());

portfolioListView.setItems(filteredPortfolioList);

searchField.textProperty().addListener((observable, oldText, newText) -> {
String search = newText == null ? "" : newText.toLowerCase();

filteredPortfolioList.setPredicate(share -> search.isBlank()
|| share.getStock().getSymbol().toLowerCase().contains(search)
|| share.getStock().getCompany().toLowerCase().contains(search)
);
});

} else {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package no.ntnu.gruppe53.view;

import javafx.collections.transformation.FilteredList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.*;

import java.math.BigDecimal;
import java.math.RoundingMode;

Expand All @@ -31,8 +32,12 @@ public class TransactionArchiveView extends BorderPane {
private final LanguageManager lm = LanguageManager.getInstance();

private ListView<Transaction> historyListView;
private FilteredList<Transaction> filteredTransactionList;

private Label titleLabel;

private TextField searchField;

/**
* Builds the view components and places them in the center pane.
*/
Expand Down Expand Up @@ -146,6 +151,20 @@ protected void updateItem(Transaction item, boolean empty) {
}
});

HBox searchBox = new HBox();
searchField = new TextField();
searchField.promptTextProperty().bind(lm.bindString("search"));
searchBox.setStyle("-fx-background-color: #ffe556;" +
"-fx-text-fill: #303539;" +
"-fx-background-radius: 8;" +
"-fx-border-color: #303539;" +
"-fx-border-radius: 8;"
);

searchBox.setPadding(new Insets(8, 14, 8, 14));
searchBox.setAlignment(Pos.CENTER_LEFT);
searchBox.setMaxWidth(Region.USE_PREF_SIZE);
searchBox.getChildren().addAll(searchField);

VBox historyListBox = new VBox(historyListView);
historyListBox.setStyle("-fx-background-color: #ffe556;" +
Expand All @@ -162,18 +181,33 @@ protected void updateItem(Transaction item, boolean empty) {
VBox.setVgrow(historyListView, Priority.ALWAYS);
VBox.setVgrow(historyListBox, Priority.ALWAYS);

vBox.getChildren().addAll(titleBox, historyListBox);
vBox.getChildren().addAll(titleBox, searchBox, historyListBox);
return vBox;
}

/**
* Sets the player to be observed.
* <p>And puts the {@link TransactionArchive} into a {@link FilteredList} for searching.</p>
*
* @param player the player to be observed
*/
public void setPlayer(Player player) {
if (player != null && player.getTransactionArchive() != null) {
historyListView.setItems(player.getTransactionArchive().getObservableTransactions());
if (player != null && player.getTransactionArchive().getObservableTransactions() != null) {


filteredTransactionList = new FilteredList<>(player.getTransactionArchive().getObservableTransactions());

historyListView.setItems(filteredTransactionList);

searchField.textProperty().addListener((observable, oldText, newText) -> {
String search = newText == null ? "" : newText.toLowerCase();

filteredTransactionList.setPredicate( transaction -> search.isBlank()
|| transaction.getShare().getStock().getSymbol().toLowerCase().contains(search)
|| transaction.getShare().getStock().getCompany().toLowerCase().contains(search)
);
});

} else {
historyListView.setItems(null);
}
Expand Down
1 change: 1 addition & 0 deletions millions/src/main/resources/i18n/lang.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# General
yes = Yes
no = No
search = Search:

# StartView
newGame = New Game
Expand Down
1 change: 1 addition & 0 deletions millions/src/main/resources/i18n/lang_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# General
yes = Yes
no = No
search = Search:

# StartView
newGame = New Game
Expand Down
1 change: 1 addition & 0 deletions millions/src/main/resources/i18n/lang_no.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# General
yes = Ja
no = Nei
search = Søk:

# StartView
newGame = Nytt Spill
Expand Down
6 changes: 4 additions & 2 deletions millions/target/classes/i18n/lang.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Default file to use if there is an error with language locale
# File for the english language

# General
yes = Yes
no = No
search = Search:

# StartView
newGame = New Game
Expand Down Expand Up @@ -58,6 +59,7 @@ portfolioGross = Gross:
portfolioCommission = Commission:
portfolioTax = Tax:
portfolioTotal = Total:
portfolioProfit = Profit:
sellButton = Sell
portfolioShareQuantity = Qty:
portfolioBuyPrice = Buy price:
Expand All @@ -67,7 +69,7 @@ portfolioCurrentPrice = Current Price:
historyTitle=Transaction History
historyTypePurchase=Purchase
historyTypeSale=Sale
historyCellFormat=Week %d | %s | %s | Qty: %s | Total: $%s
historyCellFormat=Week %d | %s | %s | Price: %s | Qty: %s | Gross: %s | Commission: %s | Tax: %s | Total: $%s | Profit: %s

# EndView
congratsLabel = Thank you for playing Millions!\nBelow you can see what level you reached and the amount of\nmoney you ended up with!\nYou can also choose to start a new game.
Expand Down
4 changes: 3 additions & 1 deletion millions/target/classes/i18n/lang_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# General
yes = Yes
no = No
search = Search:

# StartView
newGame = New Game
Expand Down Expand Up @@ -58,6 +59,7 @@ portfolioGross = Gross:
portfolioCommission = Commission:
portfolioTax = Tax:
portfolioTotal = Total:
portfolioProfit = Profit:
sellButton = Sell
portfolioShareQuantity = Qty:
portfolioBuyPrice = Buy price:
Expand All @@ -67,7 +69,7 @@ portfolioCurrentPrice = Current Price:
historyTitle=Transaction History
historyTypePurchase=Purchase
historyTypeSale=Sale
historyCellFormat=Week %d | %s | %s | Qty: %s | Total: $%s
historyCellFormat=Week %d | %s | %s | Price: %s | Qty: %s | Gross: %s | Commission: %s | Tax: %s | Total: $%s | Profit: %s

# EndView
congratsLabel = Thank you for playing Millions!\nBelow you can see what level you reachedand the amount of\nmoney you ended up with!\nYou can also choose to start a new game.
Expand Down
5 changes: 4 additions & 1 deletion millions/target/classes/i18n/lang_no.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# General
yes = Ja
no = Nei
search = Søk:

# StartView
newGame = Nytt Spill
Expand Down Expand Up @@ -58,6 +59,7 @@ portfolioGross = Brutto:
portfolioCommission = Kurtasje:
portfolioTax = Skatt:
portfolioTotal = Total:
portfolioProfit = Profitt:
sellButton = Selg
portfolioShareQuantity = Ant:
portfolioBuyPrice = Kjøpspris:
Expand All @@ -67,7 +69,8 @@ portfolioCurrentPrice = Gjeldende pris:
historyTitle=Transaksjonshistorikk
historyTypePurchase=Kjøp
historyTypeSale=Salg
historyCellFormat=Uke %d | %s | %s | Ant: %s | Total: $%s
historyCellFormat=Uke %d | %s | %s | Pris: %s | Ant: %s | Brutto: %s | Kurtasje: %s | Skatt: %s | Total: $%s | Profit: %s


# EndView
congratsLabel = Takk for at du spilte Millions!\nNedenfor kan du se hvilket nivå du nådde opp til\nog din endelige saldo!\nDu kan også velge å starte et nytt spill.
Expand Down

0 comments on commit 27bb541

Please sign in to comment.