JavaFX Sqlite get ID from selected ListView Element - sqlite

I have a ListView which is filled with artwork names (from SQLite database), these are strings and the names are not primary keys (not unique). Of course each artwork has its own ID (primary key).
What I do, I select one artwork from this list and pass it as a string argument to a button, which creates additional informations (that is not neccessary for this question).
But I select the name, now I need to get the ID from this selected artwork as foreign key.
Of course I can create a select query like this:
"select * from Artwork where Name = ?";
and then get the ID from the artwork with this name, but as I said before, there can be multiple artworks with the same name, so this is not good.
The Plan B which I have is to display in the ListView also the IDs of the the artworks, then If you select one artwork, you could slice the String at " " and take work with the list argument which contains the ID.
But that does not feel right.
Thanks! I hope you understood what I need, if not I could provide code, but there is really a lot.

You are confusing what is displayed in the list view (the data) with how it is displayed (the view). You want the data to consist of objects containing both the id and the name. You want the view to simply display the name of those objects.
Create a class representing the Artwork that contains both the id and the name:
public class Artwork {
private final int id ;
private final String name ;
public Artwork(int id, String name) {
this.id = id ;
this.name = name ;
}
public String getName() {
return name ;
}
public int getId() {
return id ;
}
}
Have your database code return a list of Artwork objects, and define your list view:
ListView<Artwork> listView = new ListView<>();
listView.getItems().addAll(getArtworkFromDatabase());
Finally, to configure how the list view is displayed, set the cell factory:
listView.setCellFactory(lv -> new ListCell<Artwork>() {
#Override
public void updateItem(Artwork artwork, boolean empty) {
super.updateItem(artwork, empty) ;
setText(empty ? null : artwork.getName());
}
}
Now you can get whatever data you need from the selected item:
Artwork selected = listView.getSelectionModel().getSelectedItem();
int selectedId = selected.getId();
String selectedName = selected.getName();

Related

Select an item, with an specific json property value, using as a dataset a list of objects with one property beeing a json

I have the following list.
Public Class Car
{
int id;
string info;
}
List<Car> cars = {
new Car(1, "[{'color': 'blue','model': 'toyota'}]"),
new Car(2, "[{'color': 'red','model': 'tesla'}]"),
new Car(3, "[{'color': 'green','model': 'honda'}]")
}
I want to return the id(3) of the Honda.
Do I need to convert the whole list to a Json, then query for the specific item.
Or can I do something like
var chosenCar = cars.Where(s => JObject.Parse(s.info)["model"].Value == "honda");

JavaFX Saving editable TableView to SQL

I have created a two column editable TableView which the user can edit and change the data thats inside each cell. Now my question is, once the user has changed some data around in each cell, how do I then save this data or print it out in a way to add to an SQL query like this example below
INSERT INTO table_name
VALUES (Value from table,Value from table,Value from table,...);
//Editable cell
PriceColumn.setCellFactory(TextFieldTableCell.forTableColumn());
PriceColumn.setOnEditCommit(
new EventHandler<CellEditEvent<NewCustomerList, String>>() {
#Override
public void handle(CellEditEvent<NewCustomerList, String> t) {
((NewCustomerList) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setPrice(t.getNewValue());
}
}
);
You could do this by getting the required values and then passing them onto the DAO class to execute the query on the DB. Example follows-
PriceColumn.setOnEditCommit(
new EventHandler<CellEditEvent<NewCustomerList, String>>() {
#Override
public void handle(CellEditEvent<NewCustomerList, String> t) {
((NewCustomerList) t.getTableView().getItems().get(t.getTablePosition().getRow())).setPrice(t.getNewValue());
String newPrice = t.getNewValue();
String uniqueIdentifier = t.getRowValue().getUniqueIdentifier(); //Unique identfier is something that uniquely identify the row. It could be the name of the object that we are pricing here.
daoObj.updatePrice(newPrice, uniqueIdentifier); //Call DAO now
}
}
);
And somewhere in the deep dark jungles of DAO class,
private final String updateQuery = "UPDATE <TABLE_NAME> SET <PRICE_COLUMN> = ? WHERE <UNIQUE_COLUMN> = ?"; //If you require multiple columns to get a unique row, add them in the where clause as well.
public void updatePrice(String newPrice, String uniqueIdentifier) {
PreparedStatement ps = con.prepareStatement(updateQuery); //con is the connection object
ps.setString(1,uniqIdentifier); //if a string
ps.setString(2,newPrice); //if a string
ps.executeQuery();
}
If this is not what you were expecting, then can you please clarify your requirement?

JavaFX Add data to Column's instead of row

Good day,
I have a fixed number of columns in TableView, however I need to populate column by column, not row by row, as one column data depends on the previous one. Is there an example of such thing? I have searched for such way, but unfortunately. Hope I made it understandable.
Since nobody provided me an example, and the comment was not very helpful I manage to solve my problem in the following way (in my case one column result depends on the previous one and the number of elements can be different as well as the number of columns are predefined)
Simple example:
We have an object:
public class Cars{
private String name;
private String company;
private String year;
public Cars(String name,String company,String year){
this.name=name;
this.company=company;
this.year=year;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company= company;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year= year;
}
}
Then we have our table:
public TableView createTable() {
TableView<Cars> table = new TableView<>();
TableColumn<Cars, String> nameyColumn = new TableColumn("Name");
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<Cars, String> companyColumn = new TableColumn<>("Company");
companyColumn.setCellValueFactory(new PropertyValueFactory<>("company"));
TableColumn<Cars, String> yearColumn = new TableColumn<>("Year");
yearColumn.setCellValueFactory(new PropertyValueFactory<>("year"));
table.setItems(makeCars());
table.getColumns().addAll(nameColumn, companyColumn, yearColumn);
return table;
}
Afterwards we generate the information that we want to put into the table and put all the information into, in this case a String Array. So if we have 3 String arrays we can make an ArrayListlist of arrays and populate it with information.
However, the sizes of the String arrays inside the ArrayList have to be predefined, so that you would not get a NullPointException where the at one point you have a car's name and you dont have a year it will be set to an empty automatically, as an empty predefined String array contains null as elements automatically. So in my case I know the max size that one array can be and set all of them to the same size.
And afterwards I just loop through the ArrayList of String Arrays and create objects which I add to the ObservableList ( might be a better way of doing it but I did it this way):
private ObservableList<Cars> makeCars() {
ObservableList<Cars> madeList = FXCollections.observableArrayList();
ArrayList<String[]>arrayOfArrays=new ArrayList<>();
for(int i=0;i<maxRow;i++){
madeList.add(new Cars(arrayOfArrays.get(0)[i],arrayOfArrays.get(1)[i],
arrayOfArrays.get(2)[i]));
}
return madeList;
}
Hope this will helpful to somebody, if there is a better way and I am overdoing it please share.

Bind repeater list with enum

I have a requirement where when a user clicks on image a list should be shown with checkboxes and all the categories that is present in DB and user should be able to select the checkboxes. How can this be achieved using asp:repeater control? the caegory is a enum type and can have n number of values. In repeater i have added a checkbox and a label; the label should display the category text.
To start with, you should add the [Description] attribute to each value in your Enum. This allows you to set proper descriptive text for each value. This attribute is in System.ComponentModel, here's an example: -
public enum CalendarShowAsEnum
{
[Description("None")]
None = 10,
[Description("Busy")]
Busy = 20,
[Description("Out Of Office")]
OutOfOffice = 30,
[Description("On Holiday")]
OnHoliday = 40
}
You then need 2 functions: -
One function that takes an Enum type and a ListBox/DropDown as parameters, and adds an entry for each Enum into the list
A helper function that converts the enum into the descriptive title you gave them (example above)
The List function might look as follows (all this is taken from a project I worked on): -
public static void BindNamedEnumList(ListControl list,
Type enumerationType)
{
list.Items.Clear();
Array array = Enum.GetValues(enumerationType);
ListItem item;
string name;
var enumerator = array.GetEnumerator();
if (enumerator != null)
{
while (enumerator.MoveNext())
{
Enum value = enumerator.Current as Enum;
name = EnumHelper.GetEnumName(value);
item = new ListItem(name);
item.Value = Convert.ToInt32(value).ToString();
list.Items.Add(item);
}
}
}
This function takes a Type and a ListControl (which ListBox and DropDownList both inherit from). The Type is the .GetType() of the enum you want to add to the list. Note that it doesn't select any values and that it does depend on each enum value having a defined integer value. The latter part will help you with selecting individual items.
Note the loop calls EnumHelper.GetEnumName(value) - this is the helper function that uses the Description attribute I mentioned at the start. This function looks like: -
public static string GetEnumName(object value)
{
string retVal = string.Empty;
try
{
FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
retVal = ((attributes.Length != 0) ? attributes[0].Description : value.ToString());
}
catch (System.NullReferenceException)
{
}
finally
{
if (string.IsNullOrEmpty(retVal))
{
retVal = "Unknown";
}
}
return retVal;
}
It uses reflection, so you'll need to add an Imports for System.Reflection
To use the list function to bind a set of Enum values to the list, simply call
{HelperClass}.BindNamedEnumList(myListBox, typeof({MyEnumType})

How to handle multiple session variables in ASP .Net?

As a part of online shopping, I implemented a cart using Session.
I have implemented the Cart in the following manner :
Session[pname] = qty;
where pname is a string variable which holds the name of the product and I used that as the key. qty is an integer variable which holds the number of items of that particular product.
To display the cart items I simply used the following loop :
foreach(string keys in Session.Keys)
Through this I get the names of the products along with the associated quantity and using this I display the cart items. The problem arises when I also have a session for the user active on the same page.
Session["uname"] = user_name;
And while retrieving the keys using Session.Keys, the uname gets included which I don't want as I need only the product's names. Is there any way I can read the keys from Session[pname] without reading from Session["uname"]?
Instead of storing an object in session for each product and quantity, just store a single object (e.g. List) which contains all of your cart items.
Here is an example which you could tweak to meet your needs:
First, a simple object to store the data:
public class CartItem {
public string Name { get; set; }
public int Quantity { get; set; }
}
Then if you need to add an object to the cart list:
var cartItems = new List<CartItem>();
cartItems.Add(new CartItem() {
Name = "",
Quantity = 1
});
Session["Cart"] = cartItems;
//Need to fetch the cart items later on?
cartItems = (List<CartItem>)Session["Cart"];
Obviously this can be implemented differently and this was just a quick example.
You mentioned needing an easier fix than what Justin Helgerson said, so here's a couple of suggestions, but they feel a little quick and dirty. Justin's is probably the superior solution. I used a quick Console app to demonstrate this, so place your constants where they belong, and you obviously don't have to create a dictionary.
const string USERSESSION = "uname";
Dictionary<string, object> session = new Dictionary<string, object>();
session["item1"] = 2;
session["item2"] = 1;
session[USERSESSION] = "StackOverflowUser";
// print cart items - minus the user name session key
foreach (string key in session.Keys.Where(s => s != USERSESSION))
{
Console.WriteLine("Key: {0} Value: {1}", key, session[key]);
}
Alternatively, if you plan on there being more keys than just "uname", use the Linq Except method.
// build up except set
List<string> exceptKeys = new List<string>
{
USERSESSION
};
foreach (string key in session.Keys.Except(exceptKeys))
{
Console.WriteLine("Key: {0} Value: {1}", key, session[key]);
}

Resources