How to refresh a ChoiceBox in JavaFX? - javafx

I would like to refresh the choice box after I added a new value it should be shown there.
I read all the topics about this that I found on stackoverflow but none of these worked.
public void setNamesChoiceBoxes() {
ArrayList<Worker> workers = new ArrayList<>();
ArrayList<String> names = new ArrayList<>();
workers = db.getWorkers();
for (Worker i : workers) {
String tmp = i.getName() + " (" + i.getID() + ")";
names.add(tmp);
}
ArrayList<String> searchNames = new ArrayList<>(names);
searchNames.add(0, "All");
ObservableList<String> search = FXCollections.observableList(searchNames);
searchNameChoiceBox.setItems(search);
searchNameChoiceBox.setValue(search.get(0));
ArrayList<String> addNames = new ArrayList<>(names);
addNames.add(0, "");
ObservableList<String> add = FXCollections.observableList(addNames);
addNameChoiceBox.setItems(add);
addNameChoiceBox.setValue(add.get(0));
}
#Override
public ArrayList<Worker> getWorkers() {
ArrayList<Worker> workers = new ArrayList<>();
String sql = "select * from names";
try {
ResultSet rs = statement.executeQuery(sql);
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
workers.add(new Worker(id, name));
}
} catch (Exception ex) {
System.out.println("Exception in class \"DB\" (\" public ArrayList<Worker> getWorkers()\" failed): " + ex);
}
return workers;
}
#FXML
public void addNewWorkerButton(ActionEvent event) {
String name = workerNameTextField.getText();
workerNameTextField.setText("");
db.addWorker(name);
addWorkerAnchorPane.setVisible(false);
mainAnchorPane.setOpacity(1);
mainAnchorPane.setDisable(false);
setNamesChoiceBoxes();
}
I get the worker names from the database when I start the program, it works perfectly. When I add a new name to the DB, and call the "setNamesChoiceBoxes" method (to refresh the choicebox from DB), it gives alot of errors, although the new name is in the Choice Box list, but the "searchNameChoiceBox" value should be "All" but it is "".
After I added a new name choice box looks like this: https://imgur.com/a/N4JarK7
It should be like this... (since I set the value to "All" in method...): https://imgur.com/a/ZAEB7A3

I think i understood that you want a particular item to be selected and shown in your ChoiceBox?
If so, I would recommend to remove this line(and analoguous for the other Box):
//addNameChoiceBox.setValue(add.get(0));
And use instead a real selection for the Item to show. This selects the first Item:
addNameChoiceBox.getSelectionModel().select(0);
Alternativly there is a seperate method that also selects the first Item:
addNameChoiceBox.getSelectionModel().selectFirst();
And then again you may want to select the Item shown by value:
addNameChoiceBox.getSelectionModel().select("All"); //or whatever value you want to select.
I hope this helps you at least with a part of your problem.

Related

make a search in recylerview

I want to make a search on recyclerview, but the data appears if the phone is turned off and then turned on again, why is that?
the example photo
the app
When i'm search the recylerview is blank
but when the phones turned off and then turn on again, the data is appear
here's the code in fragment class
//search
editText = view.findViewById(R.id.searchServant);
searchButton = view.findViewById(R.id.button2);
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String s = editText.getText().toString();
firebaseSearch(s);
}
});
//RecylerviewDatabaseServant
recyclerViewdatabase = view.findViewById(R.id.recyclerViewServant);
mManager = new LinearLayoutManager(getContext());
recyclerViewdatabase.setLayoutManager(mManager);
FirebaseRecyclerOptions<Servant> options =
new FirebaseRecyclerOptions.Builder<Servant>().setQuery(FirebaseDatabase.getInstance().getReference().child("Servant")
, Servant.class)
.build();
servantAdapter = new ServantAdapter(options);
recyclerViewdatabase.setAdapter(servantAdapter);
//End
here the function firebase search
private void firebaseSearch(String s) {
FirebaseRecyclerOptions<Servant> options = new FirebaseRecyclerOptions.Builder<Servant>().setQuery(FirebaseDatabase.getInstance()
.getReference().child("Servant").orderByChild("name").startAt(s).endAt(s + "\uf8ff"), Servant.class).build();
servantAdapter = new ServantAdapter(options);
recyclerViewdatabase.setAdapter(servantAdapter);
}
Try add this line in You search query
private void firebaseSearch(String s) {
FirebaseRecyclerOptions<Servant> options = new FirebaseRecyclerOptions.Builder<Servant>().setQuery(FirebaseDatabase.getInstance()
.getReference().child("Servant").orderByChild("name").startAt(s).endAt(s + "\uf8ff"), Servant.class).build();
servantAdapter = new ServantAdapter(options);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager({**context**}));
recyclerViewdatabase.setAdapter(servantAdapter);
servantAdapter.startListening();
}

How to move Resultset curser via button click, and display data in textfields?

So, I'm creating a desktop banking application. It's nothing too serious, I'm just trying to practice and get better.
// Method I use to get a connection. I know this works.
public static Connection getConnection() throws SQLException {
String sCon = "jdbc:sqlite:banking.sqlite";
Connection connection = DriverManager.getConnection(sCon);
return connection;
}
.
..
...
.....Other code
Method I attempt to use to create and manipulate the data in the result set.
The problem I believe starts here. With this code, I am only able to return one row of the result set and only the last row.
public static Customers getAccounts(Customers c) {
String query = "select RowCount, Customers.Account_Number, "
+ "Customers.First_Name, Last_Name, Address, "
+ "Phone_Number, Accounts.Balance "
+ "from Customers "
+ "join Accounts ";
try (Connection connection = getConnection();
PreparedStatement ps = connection.prepareStatement(query);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
String fName = rs.getString("First_Name");
String lName = rs.getString("Last_Name");
String address = rs.getString("Address");
String phone = rs.getString("Phone_Number");
String accNum = rs.getString("Account_Number");
String balance = rs.getString("Balance");
c.setFirstName(fName);
c.setLastName(lName);
c.setAddress(address);
c.setPhoneNumber(phone);
c.setAccountNumber(accNum);
c.setBalance(balance);
}
return c;
} catch (SQLException e) {
System.err.println(e);
}
return null;
}
}
Here is the method that is linked to the button I use to perform what I'm trying to attempt. It's part of the Controller class. I believe this method is also a part of the problem. Any ideas? Thank for all you guys do. This website is a real benefit to the community.
public void next() {
Customers c = new Customers();
DBInterface.getAccounts(c);
firstNameF2.setText(c.getFirstName());
lastNameF2.setText(c.getLastName());
addressF2.setText(c.getAddress());
phoneNumberF2.setText(c.getPhoneNumber());
accNumF.setText(c.getAccountNumber());
balanceF.setText(c.getBalance());
}
If you are expecting to get multiple Customers objects, then you definitely should return a list of that.
public static List<Customers> getAccounts() {
// Whatever you originally had...
final List<Customers> ret = new ArrayList<>();
while (rs.next()) {
String fName = rs.getString("First_Name");
String lName = rs.getString("Last_Name");
String address = rs.getString("Address");
String phone = rs.getString("Phone_Number");
String accNum = rs.getString("Account_Number");
String balance = rs.getString("Balance");
final Customers cust = new Customers();
cust.setFirstName(fName);
cust.setLastName(lName);
cust.setAddress(address);
cust.setPhoneNumber(phone);
cust.setAccountNumber(accNum);
cust.setBalance(balance);
ret.add(cust);
}
return ret;
}
I have removed the part about passing in the instance of Customers (which would have ended up as passing in List<Customers>. If you really need to do that, you can add back in and do all the necessary checks.

UWP: How to map arbitrary data to Telerik RadDataGrid

So I have a situation in which I am receiving a collection of Dictionary(string, string) entries where the key of each entry is the column name & value the, well, value. I want to push these to a RadDataGrid so that each dictionary maps to a row. If I knew what/how many columns I'd be getting in advance, I'd just map them to an object and have done with it. Unfortunately, it could be different every time, so that won't work.
So far I'm having no luck. I've tried mapping it*(the collection) directly, converting it to dynamic objects & XMLDocument, none of which worked. Also just got the Fall Creators Update & tried mapping it to a DataTable, no luck there either.
I've been experimenting with mapping the DataTable's DefaultView to the grid's ItemsSource after manually adding columns, but while I get the right # of columns and headers, I still don't get the field values. Not sure where to go next.
Mind you, I'm not married to Telerik. If someone else knows a suitably usable UWP data grid solution that will let me map arbitrary data like this, I'd love to hear about it.
Example using a standard UWP app:
MainPage.xaml:
<Page xmlns:my="using:Telerik.UI.Xaml.Controls.Grid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestTelerikDataGrid"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ComponentModel="using:System.ComponentModel"
x:Class="TestTelerikDataGrid.MainPage"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="0,0,0,125">
<my:RadDataGrid Margin="0,0,0,-125" x:Name="dataGrid" AutoGenerateColumns="False" >
</my:RadDataGrid>
</Grid>
</Page>
And the back-end:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using Windows.UI.Xaml.Controls;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace TestTelerikDataGrid {
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page {
private ObservableCollection<Dictionary<string, string>> items = new ObservableCollection<Dictionary<string, string>>();
public ObservableCollection<Dictionary<string, string>> ItemDictionary {
get {
return items;
}
set {
items = value;
}
}
public DataTable Items { get; set; }
public MainPage() {
this.InitializeComponent();
CreateItems(); // creates sample data structurally identical to what we'll get in the actual app (i.e., obsv. collection of dictionaries)
CreateTable(); // attempt to take the collection created above and map it to the RadDataGrid
}
private void CreateItems() {
for (int i = 0; i < 5; i++) {
Dictionary<string, string> row = new Dictionary<string, string>();
row["A"] = "A" + i.ToString();
row["B"] = "B" + i.ToString();
row["C"] = "C" + i.ToString();
ItemDictionary.Add(row);
}
}
private void CreateTable() {
Items = new DataTable();
if (ItemDictionary.Count == 0) return;
foreach (KeyValuePair<string, string> entry in ItemDictionary[0]) {
DataColumn column = new DataColumn(entry.Key);
Items.Columns.Add(column);
Telerik.UI.Xaml.Controls.Grid.DataGridTextColumn dgc = new Telerik.UI.Xaml.Controls.Grid.DataGridTextColumn();
dgc.Name = entry.Key;
dgc.Header = entry.Key;
dgc.PropertyName = entry.Key;
dataGrid.Columns.Add(dgc);
}
foreach (Dictionary<string, string> rowEntry in ItemDictionary) {
DataRow row = Items.NewRow();
int col = 0;
foreach (KeyValuePair<string, string> entry in rowEntry) {
row[entry.Key] = entry.Value;
}
Items.Rows.Add(row);
}
DataView dv = Items.DefaultView;
dataGrid.ItemsSource = dv;
}
}
}
Ideally, this will result in a table with 5 rows, 3 columns (A, B, C) and the fields showing the correct value (e.g., first row reading A0, B0, C0).
I've been experimenting with mapping the DataTable's DefaultView to the grid's ItemsSource after manually adding columns, but while I get the right # of columns and headers, I still don't get the field values. Not sure where to go next.
Those are all part of UWP 2.0 that came with the Fall Creators Update. I believe it's build 16299 or something like that. Sorry, should have mentioned that's the build I'm using.
The RaDataGrid doesn't support setting DataTable or DataView as ItemsSource directly. You need to cast to an IEnumerble collection instead of DataView.
Please see this thread on Telerik forum for more details: binding-dictionary-to-raddatagrid
In the end, I wound up creating a generic "GridRow" class with properties "Item00"..."Item99" and just mapped the data to that instead. It's a pill but it works. Just putting this here for the next person.
public class GridRow {
public Int32 Index { get; set; }
public string Item00 { get; set; }
public string Item01 { get; set; }
public string Item02 { get; set; }
...etc
}
public ObservableCollection<GridRow> GridData { get; set; }
And here's how you populate that:
GridData = new ObservableCollection<GridRow>();
foreach (Dictionary<string, string> record in ViewModel.ItemsSource) {
GridRow gridRow = new GridRow();
gridRow.Index = rowIndex;
colIndex = 0;
foreach (DataGridHeader header in ViewModel.Headers) {
gridRow.GetType().GetProperty(string.Format("Item{0:D2}", colIndex)).SetValue(gridRow, record[header.Name]);
colIndex += 1;
}
GridData.Add(gridRow);
rowIndex += 1;
}
You get the idea.

Codename One: Connecting and populating a drop-down menu with an SQLite database

I am trying to connect an SQLite database file to a picker component (accepting strings). This should act similar to a drop-down menu. I have tried to follow previous advice and examples, but without success.
As indicated in a previous post, I have saved the database file in the source folder of the application. View of the source folder where I have saved the database file (highlighted).
The code I have used to implement my app is as follows with the below layout.
//-----------------------
database code
//-----------------------
public class MyApplication {
private Form current;
private Resources theme;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Pro only feature, uncomment if you have a pro subscription
// Log.bindCrashProtection(true);
}
private Container Home() {
Container home = new Container(new BoxLayout(BoxLayout.Y_AXIS));
return home;
}
private Container AddItem() {
Container addItem = new Container(new BoxLayout(BoxLayout.Y_AXIS));
TextArea item = new TextArea("Add Item");
addItem.addComponent(item);
Picker selectItem = new Picker();
selectItem.setType(Display.PICKER_TYPE_STRINGS);
//----------------------------------------------------------------------------------
Database db = null;
Cursor cur = null;
try {
db = Display.getInstance().openOrCreate("FoodAndBeverage.db");
if(selectItem.getText().startsWith("Still Water")) {
cur = db.executeQuery(selectItem.getText());
int columns = cur.getColumnCount();
addItem.removeAll();
if(columns > 0) {
boolean next = cur.next();
if(next) {
ArrayList<String[]> data = new ArrayList<>();
String[] columnNames = new String[columns];
for(int iter = 0 ; iter < columns ; iter++) {
columnNames[iter] = cur.getColumnName(iter);
}
while(next) {
Row currentRow = cur.getRow();
String[] currentRowArray = new String[columns];
for(int iter = 0 ; iter < columns ; iter++) {
currentRowArray[iter] = currentRow.getString(iter);
}
data.add(currentRowArray);
next = cur.next();
}
Object[][] arr = new Object[data.size()][];
data.toArray(arr);
addItem.add(BorderLayout.CENTER, new Table(new DefaultTableModel(columnNames, arr)));
} else {
addItem.add(BorderLayout.CENTER, "Query returned no results");
}
} else {
addItem.add(BorderLayout.CENTER, "Query returned no results");
}
} else {
db.execute(selectItem.getText());
addItem.add(BorderLayout.CENTER, "Query completed successfully");
}
addItem.revalidate();
} catch(IOException err) {
Log.e(err);
addItem.removeAll();
addItem.add(BorderLayout.CENTER, "Error: " + err);
addItem.revalidate();
} finally {
Util.cleanup(db);
Util.cleanup(cur);
}
//---------------------------------------------------------------------------------------------
addItem.addComponent(selectItem);
TextField quantity = new TextField("", "Quantity (ml or g)", 4, TextArea.NUMERIC);
addItem.addComponent(quantity);
Button add = new Button("Add");
addItem.addComponent(add);
TextArea results = new TextArea("Results");
addItem.addComponent(results);
return addItem;
}
private Container Settings() {
Container settings = new Container(new BoxLayout(BoxLayout.Y_AXIS));
TextArea nutrients = new TextArea("Target");
settings.addComponent(nutrients);
TextField volume = new TextField("", "Volume (ml)", 4, TextArea.NUMERIC);
settings.addComponent(volume);
TextArea duration = new TextArea("Hydration Duration");
settings.addComponent(duration);
settings.add("Start:");
Picker start = new Picker();
start.setType(Display.PICKER_TYPE_TIME);
settings.addComponent(start);
settings.add("End:");
Picker end = new Picker();
end.setType(Display.PICKER_TYPE_TIME);
settings.addComponent(end);
Button save = new Button("Save");
settings.addComponent(save);
return settings;
}
public void start() {
if(current != null)
{
current.show();
return;
}
Form home = new Form("Hydrate", new BorderLayout());
Tabs t = new Tabs();
t.addTab("Home", Home());
t.addTab("Intake", AddItem());
t.addTab("Settings", Settings());
home.add(BorderLayout.NORTH, t);
home.show();
}
public void stop() {
current = Display.getInstance().getCurrent();
}
public void destroy() {
}
}
I would therefore appreciate any advice and guidance on exactly where I am going wrong and how to implement the suggested changes in my code.
I'm assuming the file under src does indeed end with the extension db as the Windows hidden extensions nonsense is turned on.
This code will NOT open a db placed in src:
db = Display.getInstance().openOrCreate("FoodAndBeverage.db");
You need to do something like this to implicitly initialize the DB the first time the app is installed:
String path = Display.getInstance().getDatabasePath("FoodAndBeverage.db");
FileSystemStorage fs = FileSystemStorage.getInstance();
if(!fs.exists(path)) {
try (InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/FoodAndBeverage.db");
OutputStream os = fs.openOutputStream(path)) {
Util.copy(is, os);
} catch(IOException err) {
Log.e(err);
}
}
db = Display.getInstance().openOrCreate("FoodAndBeverage.db");
Notice that the code above doesn't check for updates of the DB so assuming the DB is read only you might want to update/merge it with app updates.
The above code doesn't work on Android device, this works only on simulator. I have tested multiple times in the android device. In the real android device ,the database is not loaded at all, shows sql exception error
"No such table sql exception".
Looks like preloaded sqlite .db file is never tested on real Android device.

How to implement Generics in business object class definition with DAL to create a proper user control dropdown

I am woefully new to generics, being tied to the support of a corporate intranet web application whose upgrade process is bound to red tape and slowwwly-changing standards. Consequently, today (thankfully!) I finally find myself scrambling during our upgrade to .Net 3.5 and transitioning all the code I can to a properly tiered model.
I have been reading all morning about generics trying to digest how to transition dropdown user controls into a proper business object that gets its data from a class in the data access layer.
There is a perfectly succinct question here that details exactly what I am interested in exploring: Set selected index in a Dropdownlist in usercontrol.
What I would love to see, however, is what Travel_CarSizes.GetCarSizes() actually looks like inside and how the class Travel_CarSizes is defined. (I am having a hard time with <T> and knowing where it should occur.)
For my own specific circumstance at the moment I need a dropdown user control to contain location directionals (N, S, W, C/O, NW, SE, etc) that are stored in a SQL table in the DB and whose selected index needs to be able to be set by whichever page it happens to be in, when form data exists.
I have begun to implement the model in the example from the link above but right now without using Generics because I can't figure it out:
The dropdown user control:
public partial class DropDownStreetPrefix : System.Web.UI.UserControl
{
public string StreetPrefixValue
{
get { return ddlStreetPrefix.SelectedValue.ToString(); }
set
{
Bind();
ddlStreetPrefix.SelectedIndex = ddlStreetPrefix.Items.IndexOf(ddlStreetPrefix.Items.FindByValue(value));
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Bind();
}
}
private void Bind()
{
if (ddlStreetPrefix.Items.Count == 0)
{
SqlDataReader rdr = StreetDirectionals.GetDirectionals();
ddlStreetPrefix.DataSource = rdr;
ddlStreetPrefix.DataBind();
ddlStreetPrefix.DataValueField = "StreetSuffixPrefixAbbr";
ddlStreetPrefix.DataTextField = "StreetSuffixPrefixAbbr";
ListItem li = new ListItem("", "");
ddlStreetPrefix.Items.Insert(0, li);
ddlStreetPrefix.SelectedIndex = 0;
}
}
}
The StreetDirectionals class:
public class StreetDirectionals
{
private StreetDirectionals () { }
public static SqlDataReader GetDirectionals ()
{
string sqlText = "SELECT StreetSuffixPrefixAbbr FROM common..tblStreetSuffixPrefix " +
"ORDER BY StreetSuffixPrefixAbbr";
SqlDataReader rdr = SqlClient.ExecuteFetchReturnDataReader( theConnectionString, CommandType.Text, sqlText);
return rdr;
}
}
I will separate out the database interaction inside the StreetDirectionals class as soon as I can figure out how to change its code if I were to transform the Bind() method from my dropdown user control into this:
private void Bind()
{
if (!IsPostBack)
{
**List<StreetDirectionals> sd = StreetDirectionals.GetDirectionals();**
ddlStreetPrefix.DataSource = sd;
ddlStreetPrefix.DataTextField = "StreetSuffixPrefixAbbr";
ddlStreetPrefix.DataValueField = "StreetSuffixPrefixAbbr";
ddlStreetPrefix.DataBind();
}
}
Any assistance would be sooo much appreciated!
public class StreetDirectional
{
public string StreetSuffixPrefixAbbr { get; set; }
public static IEnumerable<StreetDirectional> GetDirectionals ()
{
string sqlText = "SELECT StreetSuffixPrefixAbbr FROM common..tblStreetSuffixPrefix "
+ "ORDER BY StreetSuffixPrefixAbbr";
SqlDataReader rdr = SqlClient.ExecuteFetchReturnDataReader( theConnectionString, CommandType.Text, sqlText);
var list = new List<StreetDirectional>();
while (rdr.Read())
{
var item = new StreetDirectional() { StreetSuffixPrefixAbbr = (string)rdr["StreetSuffixPrefixAbbr"] };
list.Add(item);
}
return list;
}
}
then you can do this
ddlStreetPrefix.DataSource = StreetDirectional.GetDirectionals();

Resources