Unable select Javafx combobox items programmatically which uses objects - javafx

In the JavaFx ComboBox which uses a class object list .I want to select items in the ComboBox programmatically using getSelectionModel().select(object or index). i am not getting the desired result Although the value is set but it is something like this main.dao.Company.Company.CompanyTableData#74541e7b.
The code is somewhat like this.
ComboBox<CompanyTableData> company = new ComboBox<>();
company.setItems(GetCompany.getCompanyTableData());//where Observable list is set..
GetCompany.getCompanyTableData() returns observablelist of CompanyTableData class.
The ComboBox Looks as follows.
The CompanyTableData Class is as.
public class CompanyTableData {
private SimpleStringProperty itemCompanyId;
private SimpleStringProperty itemCompanyName;
private SimpleStringProperty createBy;
private SimpleStringProperty createdOn;
public CompanyTableData(CompanyData companyData){
this.itemCompanyId = new SimpleStringProperty(companyData.getItemCompanyId());
this.itemCompanyName = new SimpleStringProperty(companyData.getItemCompanyName());
this.createBy = new SimpleStringProperty(companyData.getCreatedBy());
this.createdOn = new SimpleStringProperty(companyData.getCreatedOn());
}
public String getItemCompanyId() {
return itemCompanyId.get();
}
public SimpleStringProperty itemCompanyIdProperty() {
return itemCompanyId;
}
public void setItemCompanyId(String itemCompanyId) {
this.itemCompanyId.set(itemCompanyId);
}
public String getItemCompanyName() {
return itemCompanyName.get();
}
public SimpleStringProperty itemCompanyNameProperty() {
return itemCompanyName;
}
public void setItemCompanyName(String itemCompanyName) {
this.itemCompanyName.set(itemCompanyName);
}
public String getCreateBy() {
return createBy.get();
}
public SimpleStringProperty createByProperty() {
return createBy;
}
public void setCreateBy(String createBy) {
this.createBy.set(createBy);
}
public String getCreatedOn() {
return createdOn.get();
}
public SimpleStringProperty createdOnProperty() {
return createdOn;
}
public void setCreatedOn(String createdOn) {
this.createdOn.set(createdOn);
}
}
The Cell Factory is set
company.setCellFactory(param -> new CompanyCell());
And the CompanyCell
public class CompanyCell extends ListCell<CompanyTableData> {
#Override
protected void updateItem(CompanyTableData item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null || item.getItemCompanyName() == null) {
setText(null);
} else {
setText(item.getItemCompanyName());
}
}
}
After all this when i try to set the items programmetically as
company.getSelectionModel().select(getSelectedCompanyIndex());
The getSelectedCompanyIndex() function is as follows.
public static CompanyTableData getSelectedCompanyIndex(){
CompanyTableData c = null,i;
Iterator<CompanyTableData> itr = GetCompany.getCompanyTableData().iterator();
while (itr.hasNext()){
i = itr.next();
if (i.getItemCompanyName().equals(Element.getItemTableData().getCompany())){
c = i;
}
}
return c;
}
And the result i am getting is
And
At the end it should select a name or item in the list but it has set some type of object i think.
Now what should i do. Is there any type of string conversion required.

The buttonCell used to display the item when the combobox popup is not shown is not automatically created using the cellFactory. You need to set this property too to use the same cell implementation:
company.setCellFactory(param -> new CompanyCell());
company.setButtonCell(new CompanyCell());

Related

Javafx: Reduce events of checkable Listbox

I have a generic Javafx Listbox with checkable items (up to 20 items).
When I (de-)select an item, a property change is released to update other parts of the program.
It works all fine so far.
But I have additionally 2 buttons to (de-)select all items at once.
Also this working as expected, but I get an event for each item, which means that up to 20 property change events are fired, when one would be enough.
It is not a performance problem, not much is done on the events, but it is bad style.
Can anybody suggest a better solution?
public class FilterBox extends AnchorPane {
ListView<Item> listFilter;
Button buttonAll;
Button buttonNone;
public FilterBox() {
init();
place();
action();
getChildren().addAll(listFilter, buttonAll, buttonNone);
handleChange();
}
private void init() {
listFilter = new ListView<>();
buttonAll = new Button("All");
buttonNone = new Button("None");
}
private void place() {
setTopAnchor(listFilter, 0d);
setBottomAnchor(listFilter, 40d);
setLeftAnchor(listFilter, 0d);
setRightAnchor(listFilter, 0d);
setBottomAnchor(buttonAll, 5d);
setLeftAnchor(buttonAll, 0d);
buttonAll.setPrefWidth(75d);
setBottomAnchor(buttonNone, 5d);
setRightAnchor(buttonNone, 0d);
buttonNone.setPrefWidth(75d);
}
private void action() {
listFilter.setCellFactory(CheckBoxListCell.forListView((Item item) -> item.selectedProperty()));
buttonAll.setOnAction((t) -> {
changeAll(true);
});
buttonNone.setOnAction((t) -> {
changeAll(false);
});
}
private void changeAll(Boolean state) {
for (Item i : listFilter.getItems()) {
i.setSelected(state);
}
}
private void setListener(Item item) {
item.selectedProperty().addListener((o, ov, nv) -> {
Trigger.setNewFilterEvent();
});
}
private void handleChange() {
HashSet<String> list = InputData.getSportList();
for (String s : list) {
Item item = new Item(s, true);
listFilter.getItems().add(item);
setListener(item);
}
}
public static class Item {
private final StringProperty name = new SimpleStringProperty();
private final BooleanProperty selected = new SimpleBooleanProperty();
public Item(String name, boolean on) {
setName(name);
setSelected(on);
}
public final StringProperty nameProperty() {
return this.name;
}
public final String getName() {
return this.nameProperty().get();
}
public final void setName(final String name) {
this.nameProperty().set(name);
}
public final BooleanProperty selectedProperty() {
return this.selected;
}
public final boolean isSelected() {
return this.selectedProperty().get();
}
public final void setSelected(final boolean sel) {
this.selectedProperty().set(sel);
}
#Override
public String toString() {
return getName();
}
}
}
Assuming Trigger.setNewFilterEvent() is what you want called only once when the "select all" or the "deselect all" actions are fired, then you can use a boolean flag for this.
public class FilterBox {
private boolean ignoreIndividualChanges;
// other fields omitted for brevity
private void changeAll(boolean state) {
ignoreIndividualChanges = true;
try {
for (Item i : listFilter.getItems()) {
i.setSelected(state);
}
Trigger.setNewFilterEvent(); // fire one event
} finally {
ignoreIndividualChanges = false;
}
}
private void setListener(Item item) {
item.selectedProperty().addListener((obs, ov, nv) -> {
if (!ignoreIndividualChanges) {
Trigger.fireNewFilterEvent();
}
});
}
// other methods omitted for brevity
}
Also, note I changed the parameter type for changeAll from Boolean to boolean. There's no reason to use the reference type here, so you should stick with the primitive type.

CellValueFactory not populate data with inner object in property (JavaFX )

I populate Employees pojo in TableView colums. Employer contains rate property, that contains doubleDomainObject which not populate in tableView.
Implementation of comboBox i not showing because it good working with CellFactory. It is desirable to focus with CellValueFactory.
DoubleDomainObject
public class DoubleDomainObject extends DomainObject {
private SimpleObjectProperty<Double> doubleValue =new SimpleObjectProperty(this, "doubleValue", null);
public Double getDoubleValue() {return doubleValue.get(); }
public SimpleObjectProperty<Double> doubleValueProperty() {return doubleValue;}
public void setDoubleValue(Double value) {this.doubleValue.set(value);}
}
ColumnDoubleComboBox
public class ColumnDoubleComboBox extends ColumnWrapper{
protected TableColumn<DomainObject, DoubleDomainObject> column;
#SuppressWarnings("unchecked")
public ColumnDoubleComboBox(Bulder builder) {
super(builder);
this.column = new TableColumn<>(columnName);
setCellValueFactory();
setCellFactory();
}
public void setCellValueFactory(){
column.setCellValueFactory(new PropertyValueFactory<>(propertyName));
}
}
Employees
public class Employees extends DomainObject {
private SimpleObjectProperty<DoubleDomainObject> rate =new
SimpleObjectProperty<>(this, "rate", null);
public DoubleDomainObject getRate() {
return rate.get();
}
public SimpleObjectProperty<DoubleDomainObject> rateProperty() {
return rate;
}
public void setRate(RatePerHour rate) {
this.rate.set(rate);
}
}
---Сlient code---
tableViewWrapper = AppNode.NodeBuilder.create()
.<Employees>createTableViewWrapper()
.setDataMapper(this.dataMapperFabric.getEmployeesDataMapper())
.setColums(
columnFabric.createColumnDoubleComboBox(ColumnWrapper.Bulder.create()
.setColumnName("RATE").setColumnSize(0.2).setPropertyName("rate")
.............................etc
);

In javafx table view doesn't display

//Database is Sucessfully Connected
I am trying to Create a table in which I want to display the contents of my 'student' table in tableView of Javafx but I could not get the desired output.
ObservableList<Student> list = FXCollections.observableArrayList();
#FXML
//Initializes the controller class.
#Override
public void initialize(URL url, ResourceBundle rb)
{
// TODO
initCol();
loadTable();
}
//A view Table has been made with fx:id-table
//Variable name for 2 columns are 'fx:id-rollnoColand' & 'fx:id-nameCol'
#FXML
private TableView<Student> table;
#FXML
private TableColumn<Student,String> rollnoCol;
#FXML
private TableColumn<Student,String> nameCol;
private void initCol()
{
rollnoCol.setCellValueFactory(new PropertyValueFactory<>("s_rollno"));
nameCol.setCellValueFactory(new PropertyValueFactory<>("s_name"));
}
//Name of the Table is 'student' with Columns 'rollno' and 'name'
private void loadTable()
{
String selectAll = "select * from student";
try
{
Statement stmt = connectdb.createStatement();
ResultSet rs = stmt.executeQuery(selectAll);
while(rs.next())
{
String getrollno = rs.getString("rollno");
String getname = rs.getString("name");
list.add(new Student(getrollno,getname));
}
}
catch(SQLException exp)
{
System.out.println(exp);
}
table.getItems().setAll(list);
}
public static class Student
{
private final String s_rollno;
private final String s_name;
Student(String rollno,String name)
{
this.s_rollno = rollno;
this.s_name = name;
}
}
PropertyValueFactory works with getters or property methods. In your case you need to add getters for your properties in the Student class to enable PropertyValueFactory to retrieve the values:
public static class Student {
private final String s_rollno;
private final String s_name;
Student(String rollno, String name) {
this.s_rollno = rollno;
this.s_name = name;
}
public String getS_rollno() {
return s_rollno;
}
public String getS_name() {
return s_name;
}
}
I had this problem before,and it has many reason.First ,you may remove final keyword from your model,because your variables are changing.Second, TableView shows empty cells because you make your variables private in class Student and you can not access them from init method in parent class.So you need add getter and setter methods for access to these variables.
public static class Student
{
private String s_rollno;
private String s_name;
Student(String rollno,String name)
{
this.s_rollno = rollno;
this.s_name = name;
}
public String getS_rollno() {
return s_rollno;
}
public void setS_rollno(String s_rollno) {
this.s_rollno = s_rollno;
}
public String getS_name() {
return s_name;
}
public void setS_name(String s_name) {
this.s_name = s_name;
}
}

Android changing order of items run-time in Realm Recyclerview

I need to order the list of items based on a field say starredAt
I am loading the data in the recyclerview from Realm DB using RealmRecyclerView by thorbenprimke
The field changes it value on user's action i.e when user presses star button the item should be moved to top.
For this I am just updating the starredAt field of the object.
The items are already sorted by starredAt so realm loads the updated list but it randomly adds one more item to the recyclerview.
CheatSheet.java
public class CheatSheet extends RealmObject {
#PrimaryKey
private String id;
private RealmList<Item> items;
private String title;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public RealmList<Item> getItems() {
return items;
}
public void setItems(RealmList<Item> items) {
this.items = items;
}
}
Item.java
public class Item extends RealmObject {
#PrimaryKey
private String id;
private String description;
private Date starredAt;
public Item() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getStarredAt() {
return starredAt;
}
public void setStarredAt(Date starredAt) {
this.starredAt = starredAt;
}
}
CheatSheetActivity.java
public class MainActivity extends AppCompatActivity {
RealmRecyclerView revItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setData();
}
private void setData() {
rvItems = (RealmRecyclerView) findViewById(R.id.rev_items);
RealmResults<Item> items = Realm.getDefaultInstance().where(CheatSheet.class)
.equalTo("id", "some-id").findFirst().getItems()
.where()
.findAllSorted("starredAt", Sort.DESCENDING);
ItemRealmListAdapter itemRealmListAdapter =
new ItemRealmListAdapter(this, items,
true, true);
rvItems.setAdapter(itemRealmListAdapter);
}
ItemRealmListAdapter.java
public class ItemRealmListAdapter extends RealmBasedRecyclerViewAdapter<Item,
ItemRealmListAdapter.ItemViewHolder> {
RealmResults<Item> mItems;
public ItemRealmListAdapter(Context context, RealmResults<Item> realmResults,
boolean automaticUpdate, boolean animateResults) {
super(context, realmResults, automaticUpdate, animateResults);
this.mItems = realmResults;
}
#Override
public ItemViewHolder onCreateRealmViewHolder(ViewGroup viewGroup, int i) {
return new ItemViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.item_layout_cs_text, viewGroup, false));
}
public Item getItem(int position) {
return mItems.get(position);
}
#Override
public void onBindRealmViewHolder(ItemViewHolder itemViewHolder, int position) {
itemViewHolder.txtBody.setText(getItem(position).getDescription());
if (getItem(position).getStarredAt() != null) {
itemViewHolder.imvStar.setImageResource(R.drawable.ic_star_yellow);
}
itemViewHolder.imvStar.setOnClickListener(v -> handleStarClick(v,position));
}
private void handleStarClick(View v, int position) {
if (getItem(position).getStarredAt() != null) {
((ImageView) v).setImageResource(R.drawable.ic_star);
CheatSheetStorage.unStarItem("some-id", getItem(position));
} else {
((ImageView) v).setImageResource(R.drawable.ic_star_yellow);
CheatSheetStorage.starItem("some-id", getItem(position));
}
}
public static class ItemViewHolder extends RealmViewHolder {
#Bind(R.id.txt_cheat_sheet)
TextView txtBody;
#Bind(R.id.img_star)
ImageView imvStar;
public ItemViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
CheatSheetStorage.java
public class CheatSheetStorage {
public static void unStarItem(String cheatSheetId, Item item) {
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
CheatSheet cheatSheet = getCheatSheetById(cheatSheetId);
Item itemDB = cheatSheet.getItems().where().equalTo("id", item.getId()).findFirst();
itemDB.setStarredAt(null);
realm.commitTransaction();
}
public static void starItem(String cheatSheetId, Item item) {
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
CheatSheet cheatSheet = getCheatSheetById(cheatSheetId);
Item itemDB = cheatSheet.getItems().where().equalTo("id", item.getId()).findFirst();
itemDB.setStarredAt(new Date());
realm.commitTransaction();
}
}
Please refer following screenshots for clearer idea :
Screenshot before starring
Screenshot after starring the sixth item
#Rohan-Peshkar - You will have to provide a animateExtraColumnName value to the adapter. For the animations, the adapter keeps track of the items and since that item's id doesn't change, the list isn't updated. With an additional column (in your case that should be the starredAt column - as long as it is stored as an Integer), the diffing algorithm will detect a change and the order is updated.
For reference: https://github.com/thorbenprimke/realm-recyclerview/blob/2835a543dce20993d8f98a4f773fa0e67132ce52/library/src/main/java/io/realm/RealmBasedRecyclerViewAdapter.java#L177
You can also check out the MainActivity in the example folder. The example changes a row's text from "ABC" to "Updated ABC" and the list recognizes the change because both the primary key and the quote field are used to basically create a composite key for diffing purposes.

JavaFX - Incompatible parameter type with using TreeView.EditEvent in lambda

In a JavaFX TreeView I'm using 'custom' classes which extend TreeItem. This makes me able to edit the items in the TreeView (I can double click them and edit the contents when running the application) but I can't seem to be able to set the .setOnEditCommit() method properly. I was hoping it'd work similar as the function in a tableview but I didn't have any luck yet.
This is my code in my controller in which I try to set the setOnEditCommit() method. In my TreeView called 'trvDivisies' I display football team divisions / competitions and one level lower I display all the teams that are in a certain division.
private void setUpTreeView() {
trvDivisies.setEditable(true);
trvDivisies.setShowRoot(false);
TreeItem<String> root = new TreeItem<>();
for (Divisie d : divisies) {
TreeItem<String> divisieTreeItem = d;
divisieTreeItem.valueProperty().set(d.getNaam());
for (VoetbalTeam vt : d.getVoetbalTeams()) {
TreeItem<String> voetbalTeamTreeItem = vt;
voetbalTeamTreeItem.valueProperty().setValue(vt.getTeamNaam());
divisieTreeItem.getChildren().add(voetbalTeamTreeItem);
}
root.getChildren().add(divisieTreeItem);
}
trvDivisies.setRoot(root);
trvDivisies.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
#Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
System.out.println(newValue);
}
});
trvDivisies.setCellFactory(TextFieldTreeCell.forTreeView());
// I get an error at the following line when compiling
trvDivisies.setOnEditCommit((TreeView.EditEvent p) -> {
TreeItem<String> selectedItem = p.getTreeItem();
if (selectedItem instanceof Divisie) {
updateDivisie((Divisie)selectedItem);
} else if (selectedItem instanceof VoetbalTeam) {
updateTeam((VoetbalTeam)selectedItem);
}
});
}
This is what my 'custom' classes look like.
public class Divisie extends TreeItem<String> {
private static int idCount = 0;
private int id;
private String naam;
private List<VoetbalTeam> voetbalTeams;
public int getId() {
return id;
}
public String getNaam() {
return naam;
}
public List<VoetbalTeam> getVoetbalTeams() {
return voetbalTeams;
}
public Divisie(int id, String naam) {
super(naam);
this.id = id;
this.naam = naam;
}
public Divisie(String naam) {
this.id = ++idCount;
this.naam = naam;
}
public void addTeam(VoetbalTeam toBeAdded) {
if (voetbalTeams == null) {
voetbalTeams = new LinkedList<>();
}
voetbalTeams.add(toBeAdded);
}
#Override
public String toString() {
return this.naam;
}
}
Second 'lower level' class
public class VoetbalTeam extends TreeItem<String> {
private static int idCount = 0;
private int id;
private String teamNaam;
private List<Speler> spelers;
public int getId() {
return id;
}
public String getTeamNaam() {
return teamNaam;
}
public List<Speler> getSpelers() {
return this.spelers;
}
public VoetbalTeam(int id, String teamNaam) {
super(teamNaam);
this.id = id;
this.teamNaam = teamNaam;
}
public VoetbalTeam(String teamNaam) {
super(teamNaam);
this.id = ++idCount;
this.teamNaam = teamNaam;
}
public void addSpeler(Speler nieuweSpeler) {
if (spelers == null) {
spelers = new LinkedList<>();
}
this.spelers.add(nieuweSpeler);
}
#Override
public String toString() {
return this.teamNaam;
}
}
When trying to run the application WITH the .setOnEditCommit() method I get an error saying:
Error:(97, 37) java: incompatible types: incompatible parameter types in lambda expression
I was hoping you guys can tell me what I need to change my TreeView.EditEvent lambda to or help me find an easier solution.
For a TreeView<T>, the signature of setOnEditCommit is
void setOnEditCommit(EventHandler<TreeView.EditEvent<T>> value)
Since you have (apparently) a TreeView<String>, you need
trvDivisies.setOnEditCommit((TreeView.EditEvent<String> p) -> {
// ...
});
Or, of course, you can just let the compiler do the work for you:
trvDivisies.setOnEditCommit(p -> {
// ...
});

Resources