diff --git a/DynamicComboBox/.gitignore b/DynamicComboBox/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f68d1099657e34d4e7a68aadc730b3ecad84667d --- /dev/null +++ b/DynamicComboBox/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/DynamicComboBox/SearchableObject/src/SearchableObject/SearchableObject.java b/DynamicComboBox/SearchableObject/src/SearchableObject/SearchableObject.java new file mode 100644 index 0000000000000000000000000000000000000000..e86ec61ad4ff396ba4fe39119364c0f2af9acc3b --- /dev/null +++ b/DynamicComboBox/SearchableObject/src/SearchableObject/SearchableObject.java @@ -0,0 +1,5 @@ +package SearchableObject; + +public interface SearchableObject { + String getSearchableValue(); +} diff --git a/DynamicComboBox/src/DynamicComboBox/DynamicComboBox.fxml b/DynamicComboBox/src/DynamicComboBox/DynamicComboBox.fxml new file mode 100644 index 0000000000000000000000000000000000000000..4219504ac96bc6c4d9855b3390d74f8939ab7868 --- /dev/null +++ b/DynamicComboBox/src/DynamicComboBox/DynamicComboBox.fxml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?import DynamicComboBox.DynamicComboBox?> +<?import javafx.collections.FXCollections?> +<?import java.lang.String?> +<DynamicComboBox xmlns="http://javafx.com/javafx/21" + xmlns:fx="http://javafx.com/fxml/1" + fx:id="dynamicComboBox"> +<items> +<FXCollections fx:factory="observableArrayList"> + <String fx:value="Item 1"/> + <String fx:value="Item 2"/> + <String fx:value="Item 3"/> +</FXCollections> +</items> + </DynamicComboBox> \ No newline at end of file diff --git a/DynamicComboBox/src/DynamicComboBox/DynamicComboBox.java b/DynamicComboBox/src/DynamicComboBox/DynamicComboBox.java new file mode 100644 index 0000000000000000000000000000000000000000..91dae513787a36398d8b51e8479c7c55afae0f3a --- /dev/null +++ b/DynamicComboBox/src/DynamicComboBox/DynamicComboBox.java @@ -0,0 +1,184 @@ +package DynamicComboBox; + +import javafx.beans.property.ListProperty; +import javafx.beans.property.SimpleListProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.scene.control.Alert; +import javafx.scene.control.ButtonBar; +import javafx.scene.control.ButtonType; +import javafx.scene.control.ComboBox; +import javafx.scene.input.KeyEvent; + +import java.util.*; + +/** + * Oma versio ComboBox containerista, sisältää haun ja uuden lisäyksen tulkinnan + */ +public class DynamicComboBox extends ComboBox<java.lang.String> { + private final ListProperty<String> sisalto = new SimpleListProperty<>(FXCollections.observableArrayList()); + /** + * Attribuutti items sisältää kaiken comboxin sisällön + */ + + public DynamicComboBox() { + super(); + this.getEditor().addEventHandler(KeyEvent.KEY_TYPED, this::haku); + this.getEditor().setOnAction(_ -> tutkiValinta()); + this.sisalto.addListener((_, _, newValue) ->asetaSisalto(newValue) ); + } + /** + * Seuraavat metodit ovat molemmat sisallon lisäämistä/asettamsita varten + * + * @param sisalto mikä merkkijono/sisalto kokoelma comboboxiin laitetaan + */ + public void asetaSisalto(String[] sisalto) { + this.getItems().setAll(sisalto); + this.sisalto.setAll(Arrays.asList(sisalto)); + + } + + + public void asetaSisalto(List<String> sisalto) { + this.getItems().setAll(sisalto); + this.sisalto.setAll(sisalto); + + } + + @FXML + public void asetaSisalto(ObservableList<String> sisalto) { + this.getItems().setAll(sisalto); + this.sisalto.set(sisalto); + } + + @FXML + public ListProperty<String> sisaltoProperty() { + return sisalto; + } + + @FXML + public ObservableList<String> getSisalto() { + return sisalto.get(); + } + + + /** + * lisää sisältöä comboboxiin + * + * @param uusi merkkijono, joka lisätään + */ + public void lisaaSisaltoa(String uusi) { + this.getItems().add(uusi); + this.sisalto.add(uusi); + } + + + /** + * Vallinan tutkimis metodi Tutkii mitä käyttäjä on sijoittanut ComboBoxiin, jos on uusi valinta, + * niin kysytään halutaanko se lisätä valintoihin. Instanssi pohjainen lisäys, jos lisäys halutaan + * lopulliseksi tulee se tehdä itse + */ + private void tutkiValinta() { + java.lang.String valinta = this.getEditor().getText(); + if (valinta == null) { + return; + } + valinta = valinta.trim(); + if (valinta.isEmpty()) { + return; + } + // katsotaan löytyykö valinta + boolean loytyko = false; + for (String item : sisalto) { + if (valinta.equals(item)) { + loytyko = true; + break; + } + + } + //jos ei löytynyt, niin avataan dialogi ja kysytään halutaanko valinta lisätä + if (!loytyko) { + tallennusIkkuna(valinta); + } else { + this.getEditor().requestFocus(); + } + } + + /** + private void sisaltoMuunnin(List<java.lang.String> items) { + if(!sisalto.isEmpty() && sisalto.getFirst() instanceof SearchableObject){ + for (String item : sisalto) { + SearchableObject h = (SearchableObject) item; + items.add(h.getSearchableValue()); + + } + } else if (sisalto.isEmpty() && sisalto.getFirst() instanceof java.lang.String) { + for (String item : sisalto) { + java.lang.String h = (java.lang.String) item; + items.add(h); + } + } + } + */ + + + /** + * Metodi comboboxista etsimistä varten, Algoritmi toimii vertaamalla käyttäjän tekstiä + * items listan sisältöihin ja lisää ne comboxiin, mitkä vastaavat hakusanaa. + * Jos haku tyhjä, niin laitetaan kaikki comboboxiin, tulostetaan ja poistutaan. + * Aikavaativuus kasvaa lineaarisesti, items listan kasvaessa + */ + private void haku(KeyEvent k) { + //estetään hakeminen, jos painettu enter-nappia + if (k.getCharacter().equals("\r")) { + tutkiValinta(); + return; + } + java.lang.String hakuSana = this.getEditor().getText() + k.getCharacter(); + hakuSana = hakuSana.trim(); + //varmistetaan, että hakusana ei ole tyhjä, jos on niin näytetään kaikki vaihtoehdot + if (hakuSana.isEmpty()) { + this.getItems().setAll(sisalto); + this.show(); + return; + } + //käydään läpi jokainen vaihtoehto ja näytetään vain ne jotka ovat yhteensopivia + List<java.lang.String> naytettavat = new ArrayList<>(); + for (java.lang.String item : sisalto) { + if (item.startsWith(hakuSana)) { + naytettavat.add(item); + } + } + this.getItems().setAll(naytettavat); + } + + + /** + * Tallennusikkunan esittävä metodi + * + * @param valinta valinta joka tallennetaan + */ + private void tallennusIkkuna(java.lang.String valinta) { + Alert alert = new Alert(Alert.AlertType.CONFIRMATION); + alert.setTitle("Valitse"); + alert.setHeaderText(null); + alert.setContentText("Haluatko tallentaa valinnan " + valinta + "?"); + + ButtonType buttonTypeYes = new ButtonType("Kyllä", ButtonBar.ButtonData.OK_DONE); + ButtonType buttonTypeCancel = new ButtonType("Ei", ButtonBar.ButtonData.CANCEL_CLOSE); + + alert.getButtonTypes().setAll(buttonTypeYes, buttonTypeCancel); + + Optional<ButtonType> result = alert.showAndWait(); + if (result.get() == buttonTypeYes) { + sisalto.add(valinta); + } + } + + +} + + + + diff --git a/Ohj2HT/src/Luokat/test/LajiTulkkiTest.java b/Ohj2HT/src/Luokat/test/LajiTulkkiTest.java deleted file mode 100644 index 792d861f2a5e972704472d15fb62048d8290da67..0000000000000000000000000000000000000000 --- a/Ohj2HT/src/Luokat/test/LajiTulkkiTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package Luokat.test; -// Generated by ComTest BEGIN -import static org.junit.Assert.*; -import org.junit.*; -import org.junit.jupiter.api.Test; - -import Luokat.*; -// Generated by ComTest END - -/** - * Test class made by ComTest - * @version 2025.02.06 16:40:35 // Generated by ComTest - * - */ -@SuppressWarnings({ "PMD" }) -public class LajiTulkkiTest { - - - - // Generated by ComTest BEGIN - /** testGetLajiFromId19 */ - @Test - public void testGetLajiFromId19() { // LajiTulkki: 19 - LajiTulkki l = new LajiTulkki(); - assertEquals("From: LajiTulkki line: 21", "ahven", l.getLajiFromId(1)); - assertEquals("From: LajiTulkki line: 22", "kuha", l.getLajiFromId(2)); - } // Generated by ComTest END - - - // Generated by ComTest BEGIN - /** testGetIdFromLaji34 */ - @Test - public void testGetIdFromLaji34() { // LajiTulkki: 34 - LajiTulkki l = new LajiTulkki(); - assertEquals("From: LajiTulkki line: 36", 2, l.getIdFromLaji("kuha")); - assertEquals("From: LajiTulkki line: 37", 1, l.getIdFromLaji("ahven")); - } // Generated by ComTest END -} \ No newline at end of file diff --git a/Ohj2HT/src/fxHeatMapTesti/HeatMapTestiGUIController.java b/Ohj2HT/src/fxHeatMapTesti/HeatMapTestiGUIController.java index 12f83d7476213dbd20b808610e9d8ae70e22324e..29e22bf8ec2d454d942884e54f3b02fe90656a28 100644 --- a/Ohj2HT/src/fxHeatMapTesti/HeatMapTestiGUIController.java +++ b/Ohj2HT/src/fxHeatMapTesti/HeatMapTestiGUIController.java @@ -54,7 +54,7 @@ public class HeatMapTestiGUIController implements Initializable { private void haeKoordinaatti(String answer) { try{ - if(answer.equals("ei")) { + if (answer.equals("ei")) { return; } System.out.println(answer); diff --git a/Ohj2HT/src/fxKaljoja/KalojaGUIController.java b/Ohj2HT/src/fxKaljoja/KalojaGUIController.java index 52846f68ea4612cfd3481162b19eb9472f2e5e06..aec6bce1f15fbf3a47c09b9845d5d02c55d8b811 100644 --- a/Ohj2HT/src/fxKaljoja/KalojaGUIController.java +++ b/Ohj2HT/src/fxKaljoja/KalojaGUIController.java @@ -1,19 +1,18 @@ package fxKaljoja; +import DynamicComboBox.DynamicComboBox; import fi.jyu.mit.fxgui.Dialogs; import fi.jyu.mit.fxgui.ModalControllerInterface; -import fxLisaaReissu.LisaaReissuGUIController; import javafx.collections.FXCollections; import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; -import javafx.scene.Parent; -import javafx.scene.Scene; import javafx.scene.control.*; import java.net.URL; import java.util.ResourceBundle; import Luokat.*; +import SearchableObject.*; + /** * @author miikk * @version 29.1.2025 @@ -22,19 +21,20 @@ import Luokat.*; public class KalojaGUIController implements Initializable, ModalControllerInterface<String> { @FXML private ComboBox<String> koko; - @FXML private DynamicComboBox<String> lajit; + @FXML private DynamicComboBox lajit; - @FXML private TextField vieheVärit; + @FXML private TextField vieheVarit; - @FXML private DynamicComboBox<String> vieheet; + @FXML private DynamicComboBox vieheet; private String ReissuTagi; @Override public void initialize(URL url, ResourceBundle resourceBundle){ koko.setItems(FXCollections.observableArrayList("Sintti", "Keskikokoinen", "Iso", "Kalavalhe")); - lajit.asetaSisalto(new String[]{"kuha","ahven","kiiski"}); - vieheet.asetaSisalto(new String[]{"vaappu","lippa"}); + + + } @@ -54,15 +54,15 @@ public class KalojaGUIController implements Initializable, ModalControllerInterf } private void Tallenna() { + Saalis s = new Saalis(koko.getSelectionModel().getSelectedItem(), lajit.getSelectionModel().getSelectedItem(), Integer.parseInt(ReissuTagi)); System.out.println("saalis : koko " + s.getKoko() + " laji " + s.getLaji() + " id " + s.getSaaliinId() + " Reissulta " + s.getReissunTagi()); - Viehe v = new Viehe(s.getSaaliinId(), vieheet.getSelectionModel().getSelectedItem(), vieheVärit.getText()); + Viehe v = new Viehe(s.getSaaliinId(), vieheet.getSelectionModel().getSelectedItem(), vieheVarit.getText()); System.out.println("saatu vieheellä " + v.getTypyppi() + " " + v.getVari()); String tiedot = s.tiedotTallenusMuodossa(); System.out.println("Tiedot tallennetaan muodossa: " + tiedot); Saalis s2 = new Saalis(tiedot); - System.out.println("saalis muutettuna tiedoista: koko " + s2.getKoko() + " laji " + s2.getLaji() + " id " + s2.getSaaliinId() + " Reissulta " + s2.getReissunTagi()); - + System.out.println("saalis muutettuna tiedoista: koko " + s2.getKoko() + " laji " + s2.getLaji() + " id " + s2.getSaaliinId() + " Reissulta " + s2.getReissunTagi()); } @@ -81,6 +81,5 @@ public class KalojaGUIController implements Initializable, ModalControllerInterf public void handleShown() { } - } diff --git a/Ohj2HT/src/fxKaljoja/KalojaGUIView.fxml b/Ohj2HT/src/fxKaljoja/KalojaGUIView.fxml index b0402ba99a41f37726bd8a452bdb6d6d5f9984d6..c14f022ae24e203f80b2928ed6f762917079c87c 100644 --- a/Ohj2HT/src/fxKaljoja/KalojaGUIView.fxml +++ b/Ohj2HT/src/fxKaljoja/KalojaGUIView.fxml @@ -1,15 +1,17 @@ <?xml version="1.0" encoding="UTF-8"?> +<?import DynamicComboBox.DynamicComboBox?> +<?import java.lang.String?> <?import javafx.geometry.Insets?> <?import javafx.scene.control.Button?> <?import javafx.scene.control.ComboBox?> +<?import javafx.scene.control.TextField?> <?import javafx.scene.layout.BorderPane?> <?import javafx.scene.layout.ColumnConstraints?> <?import javafx.scene.layout.GridPane?> <?import javafx.scene.layout.Pane?> <?import javafx.scene.layout.RowConstraints?> -<?import javafx.scene.control.TextField?> <BorderPane xmlns="http://javafx.com/javafx/23.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fxKaljoja.KalojaGUIController"> <left> <GridPane prefHeight="285.0" prefWidth="534.0" BorderPane.alignment="CENTER"> @@ -25,22 +27,33 @@ <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" /> </rowConstraints> <children> - <fxKaljoja.DynamicComboBox fx:id="lajit" editable="true" prefWidth="150.0" promptText="Lajit" GridPane.rowIndex="1"> + <DynamicComboBox fx:id="lajit" editable="true" prefWidth="150.0" promptText="Lajit" GridPane.rowIndex="1"> <GridPane.margin> <Insets bottom="120.0" left="6.0" right="6.0" /> </GridPane.margin> - </fxKaljoja.DynamicComboBox> + <sisalto> + <String fx:value="ahven" /> + <String fx:value="kuha" /> + <String fx:value="kiiski" /> + </sisalto> + </DynamicComboBox> <ComboBox fx:id="koko" prefWidth="150.0" promptText="Koko" GridPane.columnIndex="1" GridPane.rowIndex="1"> <GridPane.margin> <Insets bottom="120.0" left="6.0" right="6.0" /> </GridPane.margin> </ComboBox> - <fxKaljoja.DynamicComboBox fx:id="vieheet" editable="true" prefWidth="150.0" promptText="Viehe" GridPane.columnIndex="2" GridPane.rowIndex="1"> + <DynamicComboBox fx:id="vieheet" editable="true" prefWidth="150.0" promptText="Viehe" GridPane.columnIndex="2" GridPane.rowIndex="1"> <GridPane.margin> <Insets bottom="120.0" left="6.0" right="6.0" /> </GridPane.margin> - </fxKaljoja.DynamicComboBox> - <TextField fx:id="vieheVärit" prefWidth="150.0" promptText="Vieheen väri" GridPane.columnIndex="3" GridPane.rowIndex="1"> + <sisalto> + <String fx:value="lippa" /> + <String fx:value="jigi" /> + <String fx:value="vaappu" /> + <String fx:value="perho" /> + </sisalto> + </DynamicComboBox> + <TextField fx:id="vieheVarit" prefWidth="150.0" promptText="Vieheen väri" GridPane.columnIndex="3" GridPane.rowIndex="1"> <GridPane.margin> <Insets bottom="120.0" left="6.0" right="6.0" /> </GridPane.margin> diff --git a/Ohj2HT/src/fxKaljoja/DynamicComboBox.java b/Ohj2HT/src/fxKaljoja/MynamicComboBox.java similarity index 75% rename from Ohj2HT/src/fxKaljoja/DynamicComboBox.java rename to Ohj2HT/src/fxKaljoja/MynamicComboBox.java index 841c956c5c8daa35fce2dc2c558281b1144e7e70..d16d45a17184bec072881aac06e8b05dd4eb08fc 100644 --- a/Ohj2HT/src/fxKaljoja/DynamicComboBox.java +++ b/Ohj2HT/src/fxKaljoja/MynamicComboBox.java @@ -11,17 +11,17 @@ import java.util.*; /** * Oma versio ComboBox containerista, sisältää haun ja uuden lisäyksen tulkinnan */ -public class DynamicComboBox<T> extends ComboBox<String> { +public class MynamicComboBox<T> extends ComboBox<String> { /** * Attribuutti items sisältää kaiken comboxin sisällön */ private List<String> items = new ArrayList<>(); - public DynamicComboBox() { + public MynamicComboBox() { super(); this.getEditor().addEventHandler(KeyEvent.KEY_TYPED, this::haku); - this.getEditor().setOnAction(event -> {tutkiValinta(); }); + this.getEditor().setOnAction(_ -> tutkiValinta()); } /** * Seuraavat metodit ovat molemmat sisallon lisäämistä/asettamsita varten @@ -56,8 +56,7 @@ public class DynamicComboBox<T> extends ComboBox<String> { /** - * Vallinan tutkimis metodi laita tämä on action handlerii. - * Tutkii mitä käyttäjä on sijoittanut ComboBoxiin, jos on uusi valinta, + * Vallinan tutkimis metodi Tutkii mitä käyttäjä on sijoittanut ComboBoxiin, jos on uusi valinta, * niin kysytään halutaanko se lisätä valintoihin. Instanssi pohjainen lisäys, jos lisäys halutaan * lopulliseksi tulee se tehdä itse */ @@ -79,7 +78,7 @@ public class DynamicComboBox<T> extends ComboBox<String> { } } - //jos ei löytynyt ja ei olla aikasemmin kysytty, niin avataan dialogi ja kysytään halutaanko valinta lisätä + //jos ei löytynyt, niin avataan dialogi ja kysytään halutaanko valinta lisätä if (!loytyko) { tallennusIkkuna(valinta); } else { @@ -108,47 +107,18 @@ public class DynamicComboBox<T> extends ComboBox<String> { this.show(); return; } - char[] hakuMerkki = hakuSana.toCharArray(); System.out.println("hakuSana: " + hakuSana); //logging //käydään läpi jokainen vaihtoehto ja näytetään vain ne jotka ovat yhteensopivia List<String> naytettavat = new ArrayList<>(); for (String item : items) { - sananTutkinta(item, hakuMerkki, naytettavat); - - } - this.getItems().setAll(naytettavat); - - - } - - /** - * Apumetodi haulle tutkii vastaako sana hakua - * - * @param item tutkittava sana - * @param haku mihin hakusanaan verrataan - * @param naytettavat lisätään kaikki vastaavat sanat tänne - */ - private void sananTutkinta(String item, char[] haku, List<String> naytettavat) { - try { - char[] sisaltoMerkkina = item.toCharArray(); - int i = 0; - while (i < haku.length) { - if (sisaltoMerkkina[i] != haku[i]) { - System.out.println("Ei löytynyt " + item); - break; - } - i++; - } - if (i == haku.length) { - System.out.println("Löytyi " + item); + if (item.startsWith(hakuSana)) { naytettavat.add(item); } - } catch (Exception e) { - System.out.println("Löytyi " + item); - naytettavat.add(item); } + this.getItems().setAll(naytettavat); } + /** * Tallennusikkunan esittävä metodi * diff --git a/Ohj2HT/src/media/Kartta.png b/Ohj2HT/src/media/Kartta.png index ac8f2b30cd2aa682b1afb419ad37944d61f49ea5..b4f584fb83e042b3cb733aeabc7a5047461459ad 100644 Binary files a/Ohj2HT/src/media/Kartta.png and b/Ohj2HT/src/media/Kartta.png differ