JavaFX Tutorial | Search Bar and TableView filter result as you search

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
<b>Hey everyone!</b> <b>Today I am going to show you how to </b> <b>create an effective and dynamic search app</b> <b>which displays search result as you type the keyword</b> <b>we will be using IntelliJ for our IDE</b> <b>and</b> <b>Scene Builder to build our User Interface</b> <b>then a quick work in MySQL WorkBench</b> <b>Alright!</b> <b>We will start with MySQL</b> <b>i will show you our table and sample data</b> <b>here I have a table named Product</b> <b>let's go over the Product Table Definition</b> <b>our table structure has only 6 fields</b> <b>it is more than enough for our needs</b> <b>then let's check our sample data</b> <b>as you can see had already inserted 20 rows</b> <b>of sample data</b> <b>now let's create another SELECT but with fields on it</b> <b>we are going to use it later</b> <b>Description FROM Product</b> <b>and execute query</b> <b>alright</b> <b>these are just sample data and you may use your own</b> <b>they can be replace by any value</b> <b>so long it matches the data type</b> <b>now let's go and open IntelliJ IDEA</b> <b>this code should work with other IDE too</b> <b>New Project</b> <b>and we are on openjdk version 16</b> <b>name it as ProductFinder</b> <b>first order of business is to rename our files here</b> <b>start with sample.fxml</b> <b>we will rename it to productsearch.fxml</b> <b>it's something descriptive</b> <b>good</b> <b>next we will rename the Controller</b> <b>Refactor</b> <b>Rename</b> <b>let's call it ProductSearchController</b> <b>ok good</b> <b>now we are going to setup our Project Structure</b> <b>need to add the JavaFX SDK's</b> <b>and it should be where you save them</b> <b>we just need these four</b> <b>ok</b> <b>and we need to remove that</b> <b>add my MySQL jconnector as wellb</b> <b>open</b> <b>Apply and Ok</b> <b>Next we are going to Design our UI</b> <b>we are going to open and use this fxml in Scene Builder</b> <b>go tob Scene Builder</b> <b>and</b> <b>Open Project and look for that fxml</b> <b>sample... there you go. productsearch.fxml</b> <b>Open</b> <b>and remove that. replace this with Pane</b> <b>search for that</b> <b>just drag it here</b> <b>adjust the size to 1080 x 600</b> <b>then add a TableView</b> <b>and</b> <b>we need to adjust the size as well to 1020 x 502</b> <b>that's right about</b> <b>add a label and position just above the TableView</b> <b>set Text as "Search Product"</b> <b>adjust the Font size and style</b> <b>next we need a TextField</b> <b>just drag it here</b> <b>adjust the length matching the TableView</b> <b>set prompt text as "Keywords..."</b> <b>let's setup this TableView, we need to add more columns</b> <b>to match the number of fields we have in the table</b> <b>set text s as ID next is Brand</b> <b>add 4 more TableColumns</b> <b>look for that. There you go</b> <b>drag it here...</b> <b>another</b> <b>one more</b> <b>alright. then...b</b> <b>Model Number</b> <b>Model Year</b> <b>Product name</b> <b>and Description</b> <b>you may adjust the column widths accordingly</b> <b>it depends on your preferences</b> <b>now we are going to assign FX ID's to the objects we need</b> <b>you may follow your own naming conventions, ofcourse</b> <b>set TableView FXID as productTableView </b> <b>ID TableColumn as ProductID</b> <b>brandTableColumn</b> <b>modelNumberTableColumn</b> <b>modelYearTableColumn</b> <b>and...</b> <b>productNameTableColumn</b> <b>and lastly</b> <b>descriptionTableColumn</b> <b>then here in the controller you can check the FXID's</b> <b>we will set the Controller class as </b> <b>sample.ProductSearchController</b> <b>the Controller we use in our project</b> <b>see that</b> <b>save it</b> <b>If you check the productsearch.fxml you will see updated </b> <b>fx:controller</b> <b>there you go</b> <b>and... the FX:ID's are set as well</b> <b>now let's Preview this and see how it looks like</b> <b>good</b> <b>search "Playstation 5"</b> <b>looks good, we are nowready to proceed to next part</b> <b>close this</b> <b>Now let's go back to IntelliJ</b> <b>our next step is to create module-info.java</b> <b>right now we just need the javafx.controls, fxml</b> <b>fxml</b> <b>and... graphics</b> <b>there is another one but we will just add it later</b> <b>now let's go to main.java</b> <b>change the SetTitle to "Product - Search"</b> <b>then update the setScene using the layout size of </b> <b>Pane in Scene Builder</b> <b>click the Pane then layout</b> <b>copy the Width and Height</b> <b>and change this to</b> <b>1080 x 600</b> <b>now we are ready to run and see how it looks like</b> <b>there you go</b> <b>looks good, the way we want it.</b> <b>we are now ready to proceed with coding</b> <b>the next step is to create a new class</b> <b>to handle the JDBC operation</b> <b>we will use this to establish connection to our</b> <b>MySQL Database</b> <b>this one here</b> <b>so we can access this Product Table</b> <b>Create a new Java Class</b> <b>Name it as DatabaseConnection.java</b> <b>now we are going to add the last piece we need in our </b> <b>module-info.java</b> <b>requires java.sql</b> <b>we need this for our database connection and operation</b> <b>this is pretty basic Connection class</b> <b>I leave the Database and user information blank</b> <b>you need to fill it up with what you have</b> <b>I always keep my code readable as much as I can</b> <b>for example, I use extra variables where technically</b> <b>you can code the databaseLink in a single line</b> <b>if you really want it</b> <b>alright</b> <b>don't forget to fill up</b> <b>databasename and user info before you run</b> <b>Next, we will build our SQL Query</b> <b>just a simple SELECT statement</b> <b>with fields that follow these TableView column order</b> <b>let's go to MySQL</b> <b>New Query</b> <b>and</b> <b>SELECT ProductID</b> <b>Brand</b> <b>ModelNumber</b> <b>ModelYear</b> <b>ProductName</b> <b>and Description</b> <b>FROM Product table</b> <b>Execute this query</b> <b>there you go, our sample data</b> <b>20 rows and 6 columns arrange in order</b> <b>similar to our TableView</b> <b>next, we will create another Class</b> <b>name it as ProductSearchModel.java</b> <b>this will represent our data</b> <b>we will declare our variables</b> <b>that represents our fields or columns</b> <b>it will have the same data type and order</b> <b>that way when we generate our Constructor</b> <b>the parameters are in a correct order as well</b> <b>Now we just need to generate our Getter</b> <b>alright, next</b> <b>our Setter</b> <b>all of this, ok</b> <b>looks good</b> <b>finally we are good to go </b> <b>and code here in the ProductSearchController</b> <b>we start with</b> <b>annotation @FXML and it was automatically imported above</b> <b>We are going to annotate what we need</b> <b>from our productsearch.fxml</b> <b>using these FX:ID's we set</b> <b>these are the ones we assigned in Scene Builder</b> <b>this one</b> <b>these are all of them</b> <b>we start with TableView followed by the TableColumns</b> <b>just import the TableView class</b> <b>and we need to do the same with TableColumns after</b> <b>import the TableColumn class as well</b> <b>then annotate the remaining TableColumns</b> <b>just copy and paste</b> <b>next</b> <b>we need an ObservableList</b> <b>which allow our listener to track</b> <b>any changes</b> <b>one of a factor in making our Search dynamic</b> <b>and use our ProductSearchModel as Object Data Type</b> <b>then name it as "productSearchModelObservableList"</b> <b>assign as ObservableArrayList</b> <b>next, we are going to create Initialize method </b> <b>then Implement Initializable Interface</b> <b>if you are not aware</b> <b>the Initialize</b> <b>the only existing method under Initializable Interface</b> <b>we do this so the initialize method is called and executed</b> <b>after the controller elements were completely processed</b> <b>implements Initializable</b> <b>then just need to override Initialize method</b> <b>just to over simplify, when the main.java runs</b> <b>it loaded this and the Controller initialize</b> <b>execute the codes within it</b> <b>here we need our Database Connection</b> <b>and our SQL Query, we can use the SELECT statement</b> <b>we created in MySQL. This one, just copy it.</b> <b>next we implement Try and Catch</b> <b>with SQL Exception and a logger</b> <b>and if you notice the imports keep growing</b> <b>now we execute query and handle the result</b> <b>we are going to use WHILE here</b> <b>just copy over the variable we use for the query</b> <b>also the corresponding imports are added here</b> <b>now we just need to handle the query result</b> <b>and loop around it</b> <b>next</b> <b>now we are going to pupulate our observablelist</b> <b>we can do it here a single line like this</b> <b>but i prefer manageable and readable code</b> <b>even it will be multiple line of codes</b> <b>so we are going to declare Variables for our 6 fields</b> <b>and set them on equivalent data type</b> <b>just copy them</b> <b>we only have two integer and the rest are stringsb</b> <b>now it will just simply lining them up on the same order</b> <b>manageable and readable</b> <b>we are just populating the productSearchModelOBservableList</b> <b>with data from our query result</b> <b>which is the 20 rows sample data</b> <b>let me put some comments here for reference</b> <b>and in our SQL query as well</b> <b>at this point, the setcellfactory can be assigned</b> <b>Cells of these columns</b> <b>theFX:ID's for tablecolumns has been set and annotated too</b> <b>so we can use it here and instantiate PropertyVaueFactory</b> <b>for all the columns</b> <b>we got our ProductSearchmodel for that</b> <b>will just line up here the fields we need </b> <b>and work it out for each tablecolumns</b> <b>model year, productname, description</b> <b>Ill leave another comment for reference</b> <b>now we ready for our productTableView</b> <b>this one here</b> <b>we are going to assign our ObservableArrayList to</b> <b>our "setItems()" attribute</b> <b>and just to refresh and simplify it</b> <b>our ObservableArrayList is populated here </b> <b>with rows from our SQL query result</b> <b>which in turn we set for our productTableView</b> <b>as you recall </b> <b>our ObservableTableList uses the data model we implement</b> <b>which we apply to our table column CellValueFactory</b> <b>here we utilize the structure of our model class </b> <b>which we reflect it back here accordingly</b> <b>now let's run this and see how it looks with rows of data</b> <b>and there you go</b> <b>our TableView has been populated with our sample data</b> <b>however, at this time, you can consider this just a static </b> <b>list</b> <b>we are yet to tie this up to our search TextField</b> <b>let's see...</b> <b>how the search will look like</b> <b>Playstation 5</b> <b>of course! there is no Playstation 5, did you found any?</b> <b>kidding aside</b> <b>let's complete</b> <b>our code and bind this texfield to our TableView</b> <b>We are going to utilized FilteredList</b> <b>this is another key component for our dynamic search</b> <b>this is where our model class become so useful and handy</b> <b>as it become a central basis of our data</b> <b>and finally we will work our way with the searchTextfield</b> <b>keywordTextField</b> <b>make sure to import this here</b> <b>and annotate as well</b> <b>textProperty().addListener</b> <b>and...</b> <b>will use addListener here to capture any changes</b> <b>in our seach TextField</b> <b>and observable</b> <b>oldValue</b> <b>and newValue</b> <b>and ofcourse</b> <b>using Lambda expression, we will set the Predicate for our </b> <b>filtered list</b> <b>and we are going to use that ProductSearchModel</b> <b>another Lambda expression</b> <b>we are going to have a nested if to handle our search</b> <b>first we will check if the searchTextField is either Empty</b> <b>Blank</b> <b>or Null</b> <b>and return true if it match atleast one of them</b> <b>let's put a note here</b> <b>for reference</b> <b>we will convert our searchkeyword to lowercase</b> <b>to simplify our search</b> <b>we are going to start with Product Name</b> <b>then we will check</b> <b>if there is any matches to our searchKeyword</b> <b>indexof start at position 0 hence anything greater</b> <b>than -1 means a match has been found</b> <b>or you can use not equal to -1 as well with similar result</b> <b>we return True here</b> <b>and filteredData will changed accordingly</b> <b>followed by Description</b> <b>this will be the same for Brand, Model Number</b> <b>and Model year will need to be converted </b> <b>using toString in order to be included as well</b> <b>as it is on Integer Type</b> <b>if no match is found it will return false</b> <b>and it has nothing to display</b> <b>then we are going to wrap and sort our filteredData</b> <b>as sortedData</b> <b>Now we are going to bind the sortedlist</b> <b>to the productTableView</b> <b>this way both are in sync. </b> <b>The TableView display the changes</b> <b>we do to our FilteredData or technically the SortedList</b> <b>finally we set items for our TableView</b> <b>this is loaded during initialization</b> <b>Now let's run this and see the final output</b> <b>I am going to search for "Apple"</b> <b>and there you go, it only shows rows with apple on it</b> <b>same for Sony</b> <b>let's try that</b> <b>and we got it</b> <b>as you notice as well, our search result changes dynamically</b> <b>it displays rows</b> <b>that contains our search keyword</b> <b>for example</b> <b>for example search this XBOX here</b> <b>the display changes as you type</b> <b>this search is so useful and user friendly</b> <b>what's hapenning here is that when you type</b> <b>in the textfield</b> <b>our listener take that as new value</b> <b>in our filtered list, we check it by row</b> <b>product name, description and others contain that new value</b> <b>if there is a match, TableView display</b> <b>the matching rows</b> <b>else it shows nothings</b> <b>because if there is a match it return TRUE</b> <b>then the FilteredList filter itself</b> <b>with only those matching rows</b> <b>and doing so will trigger the BINDING we made</b> <b>between sorted list and tableview</b> <b>and that trigger the TableView to refresh itself</b> <b>display matching rows</b> <b>that way it make the TableView look dynamic</b> <b>it refresh the display as you type</b> <b>whethere there is match or not</b> <b>alright! that's all I have</b> <b>if you have any question just leave a comment</b> <b>Just a quick snap of the entire code we use in this demo</b> <b>you can just simply pause the video if you want to </b> <b>look closely</b> <b>thank you for watching.</b>
Info
Channel: tookootek
Views: 2,437
Rating: undefined out of 5
Keywords: javafx tableview, javafx scene builder, javafx filteredlist, javafx filter tableview, javafx lambda expression, javafx listener, javafx search box, JavaFX, javafx tutorial, javafx tutorial for beginners, javafx intellij, javafx project, JavaFX project, javafx mysql, java mysql, javafx database, javafx table, javafx control javafx, javafx scene builder tutorial, javafx dynamic tableview from database, javafx mysql connection, javafx search bar tableview, javafx sortedlist
Id: 2M0L6w3tMOY
Channel Id: undefined
Length: 20min 8sec (1208 seconds)
Published: Mon Jul 12 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.