I have a singleton EmployeeDatabase that contains an ObservableList of employees.
This ObsList populates the contents of an editable combobox.
When a user selects one of the employees from the combo box and hits a button, I want that employee (from the database) to be displayed in a toString() in the console.
The problem is, the editable combobox does not let me select an employee directly. I'm supposed to use a StringConverter to turn that String into an Employee.
But the Employee already exists in the singleton database! Do I have to search for them in the database? Or is there an easier way to get the Employee as if the combobox weren't editable, and all I would have to do is cmbx.getSelectionModel().getSelectedItem()?
You don't need to go back to the database, since you already have an ObservableList which contains the Employees that are in there. You should be able to do something like:
final ComboBox<Employee> employeeCombo = new ComboBox<>();
employeeCombo.setItems(EmployeeDatabase.getInstance().getEmployees());
employeeCombo.setConverter(new StringConverter<Employee>() {
#Override
public Employee fromString(String string) {
for (Employee employee : employeeCombo.getItems()) {
if (string.equals(employee.getName())) { // may need more logic...
return employee ;
}
}
Employee employee = new Employee(string);
// if things are set up correctly, this call should both update the database
// and the observable list to which the combo box points
EmployeeDatabase.getInstance().add(employee);
return employee ;
}
#Override
public String toString(Employee employee) {
return employee == null : null ? employee.getName();
}
});
employeeCombo.setEditable(true);
Related
I have a TableView that has its items property bound to a class Group's applications property which is declared as :
ObjectProperty<ObservableList<Application>> applications = new SimpleObjectProperty();
it is initialised as :
applications.set(new FXCollections.observableArrayList<Application>());
applications.get().add(new Application());
applications.get().add(new Application());
The class Application class contains some properties and another class Customer declared and initialised as :
ObjectProperty<Customer> customer = SimpleObjectProperty<>(new Customer());
Now there are four columns in the tableView that are editable they are 'ApplicationNo', 'ApplicationDate', 'CustomerId' and 'CustomerName'. The first 2 column's cell value factory is set to Application class's applicationNo and applicationDate properties. and the last 2 column's cell value factory are set to the Application class's customer property's customerId and customerName properties. All the four columns are editable with combobox control that are populated with values from the database.
In addition to the above stated table view, I have a form in the FXML consisting of fields that are there in the Application class and the Customer class. This form is disabled when no table row is selected and is enabled with the values of the Application instance, when any of the table view row is selected.
Now my problem is when I select any row and edit the values in the form or in the table, all the row attain the new value that I enter.
I am not uploading the code because it is very lengthy.
the code for updateItem method of table cell editor
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (isEmpty()) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (control != null) {
updateControl();
}
setGraphic(control);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getItemText());
setGraphic(null);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
Code for cell factory and cell value factory of column applicationNo
applicationNo.setCellValueFactory(
new Callback<TableColumn.CellDataFeatures<GroupRow, ApplicationModel>, ObservableValue<ApplicationModel>>() {
//GroupRow is the object that contains the Application object
#Override
public ObservableValue<ApplicationModel> call(CellDataFeatures<GroupRow, ApplicationModel> param) {
return param.getValue().getApplicationProperty();
}
});
applicationNo.setCellFactory(
new Callback<TableColumn<GroupRow, ApplicationModel>, TableCell<GroupRow, ApplicationModel>>() {
#Override
public TableCell<GroupRow, ApplicationModel> call(TableColumn<GroupRow, ApplicationModel> param) {
return new ApplicationTableCellEditor();
//ApplicationTableCellEditor is custom TableCell
}
});
applicationNo.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<GroupRow, ApplicationModel>>() {
#Override
public void handle(CellEditEvent<GroupRow, ApplicationModel> event) {
event.getRowValue().setApplication(event.getNewValue());
tableChanged();
applicationChanged(event.getNewValue());
}
});
Actually I have figured out the actual problem and its solution. For changing Row selection I was using :
tableView.getSelectionModel().selectedItemProperty().addListener(.....);
This actually when I selected the 2nd row after selecting the first row as both the rows contained and equal instance of Application resulting in row1.equals(row2) which in turn did not allow the above listener to fire. So, The unbinding of values never happened and result that the controls remained bound to both the rows.
So as a solution I changed the above to:
tableView.getSelectionModel().selectedIndexProperty().addListener(......);
Here this fired every time I selected a different row thereby unbinding the controls and the properties of the previous row and binding the controls to the properties of the new row. This solved my problem. I would request If any one has any other suggestions please post the answer.
I have oracle adf and jdeveloper.
I have a table(multiselection) in jsf page with .
I want to disable selected rows by cliching a button.
Can anyone help me?
I'm assuming you want to disable selection of rows in a table. Your question is not very clear.
Create a bean and an attribute inside it which will handle the table selection. This can have the values "single", "none" etc. Read more about it here:
https://docs.oracle.com/cd/E28280_01/apirefs.1111/e12419/tagdoc/af_table.html
Drag and drop a button, double click it to create the code in the backing bean. Write logic in the button such that it will change the value of the previously defined variable.
Point the rowSelection attribute of the table in your page to the value in the bean.
public class MyBean {
private String rowSelection="multiple"
public String getRowSelection{
return this.rowSelection;
}
public void setRowSelection(String rowSelection){
this.rowSelection=rowSelection;
}
public String DisableRowSelection {
this.rowSelection="none";
return null;
}
public String EnableRowSelection {
this.rowSelection="multiple";
return null;
}
}
The table:
<af:table value="#{bindings.myViewObject.collectionModel}" ...//other attributes
rowSelection="#{myBean.rowSelection}" ...//other attributes
Add a transient attribute to your ViewObject called for example IsSelected then iterate through your view Object and set IsSelected attributte to Y for all selected rows .
and set inline-style for all columns
inlineStyle="#{row.IsSelected eq 'Y' ?'background-color:white;' : '' }"
I have a java class:
public Task {
private int id;
private Company sender;
private Company receiver;
//Getter and Setter
...
}
As you can see, I have 2 other custom classes in the task class. And a company has for example Adress and Directory.
I have a CompanyPanel which will reusable be used on the Page. Here is some code from the panel.
public class CompanyPanel extends Panel {
protected List<Company> companies;
public CompanyPanel(String id, IModel<Company> model) {
super(id,new CompoundPropertyModel<Company>(model));
companies = new ArrayList<Company>();
Company company_1 = new Company();
//Setting default predefined values for the company, so I can select it from the dropdown and to set fields automatically
company_1.setFtpAdress("adress1.com");
company_1.setFtpDir("/MusterDir/");
companies.add(company_1);
//SAME for another company
...
companies.add(comany_2);
...
final DropDownChoice<Company> companyList = new DropDownChoice<Company>("companies", model,
new LoadableDetachableModel<List<Company>>() {
#Override
protected List<Company> load() {
return companies;
}
}){
protected boolean wantOnSelectionChangedNotifications() {
return true;
}
};
add(companyList);
final TextField<String> ftpAdress = new TextField<String>("ftpAdress");
ftpAdress.setOutputMarkupId(true);
add(ftpAdress);
final TextField<String> ftpDir = new TextField<String>("ftpDir");
ftpDir.setOutputMarkupId(true);
add(ftpDir);
//added Ajax to dropdown to update textfields automatically, based on selection of dropdown
companyList.add(new AjaxFormComponentUpdatingBehavior("onchange")
{
#Override
protected void onUpdate(AjaxRequestTarget target)
{
target.add(ftpAdress);
target.add(ftpDir);
}
});
}
}
In the Page I use reuseable CompanyPanels.
...
CompanyPanel senderPanel = new CompanyPanel("senderPanel", new PropertyModel(task,"sender"));
senderPanel.setOutputMarkupId(true);
form.add(senderPanel);
CompanyPanel receiverPanel = new CompanyPanel("receiverPanel", new PropertyModel(task,"receiver"));
receiverPanel.setOutputMarkupId(true);
form.add(receiverPanel);
...
When I submit the form I do:
public void onSubmit(AjaxRequestTarget target, Form<?> form) {
//doSomething
target.add(senderPanel);
target.add(receiverPanel);
}
The problem: The company panel is not being rerendered. And I don't really know why.
Workflow:
I select a company from the dropdown panel
The TextFields(which are inside the companyPanel) will be set correctly, based on the dropdown
I modify a textField (which belongs to a company)
I submit the form
I change the company from the dropdown list
I change back to the first company -> PROBLEM: the modified textfields displays still the modified text inside. It was not reseted to the default values.
Any help very appreciated.
Of course they will display the modified values. You create a list of companies in the CompanyPanel constructor. When you modify a company's data, the object is modified inside that list.
A quick way to fix this would be to replace the CompanyPanel panel with a new instance of CompanyPanel in your onSubmit method. That would recreate the list of companies with your default values. You would of course lose the modified values.
Another possibly better fix is to move the companies list creation into the loadabledetachablemodel:
final DropDownChoice<Company> companyList = new DropDownChoice<Company>("companies", model,
new LoadableDetachableModel<List<Company>>() {
#Override
protected List<Company> load() {
List<Company>companies = new ArrayList<Company>();
Company company_1 = new Company();
//Setting default predefined values for the company, so I can select it from the dropdown and to set fields automatically
company_1.setFtpAdress("adress1.com");
company_1.setFtpDir("/MusterDir/");
companies.add(company_1);
//SAME for another company
...
companies.add(comany_2);
...
return companies;
}
This way the list of companies is recreated on every request with the default values.
Make sure you implement a proper equals() and hashCode() method in Company though for DropDownChoice to show the proper selected element though - because in this scenario the object in your model and the objects in the list may never be ==.
You have to provide more code. If you submit the correctly so that the model changes try:
senderPanel.modelChanged();
receiverPanel.modelChanged();
target.add(senderPanel);
target.add(receiverPanel);
I am making a web application on MVC3, and I am using linq to communicate with the database.
I made a checkboxlist, where a user can select some options according to their choice and it gets saved in the databse table. The problem is in the Edit part.
The whole scenario is something like this:
The user can register as a restaurant owner or a Motel owner, I have assigned different Business_Type_Id as 1 and 2 for differentiating these two, I have assigned '2' for the Restaurant Business Type, and mapped the cuisines with the perticular business type in the same "Cuisines" table, by adding the "BusinessType" column into the table. the user will be assigned a Business_Id for their Business. I am providing a checkboxlist which generates its options from the database table "Cuisines" where I have given the cuisine list. From the front end the user can choose multiple cuisines according to their chioce what ever they provide in their restaurant. The choices may vary from one restaurant owner to the other, so I am storing the selected values for each and every Restaurant owner in a "BusinessCuisinesMapping" table, where I map the perticular BusinessId with the selected CuisineId by that perticular user.
Now to populate that cuisine list for edit or update I wrote a linq join, but I need to compare it with the Business_Id which is passed to the [HttpGet] ActionResult Edit. And this is point where I got stuck.
This is my linq join code which I am using in the controller:
[HttpGet]
public ActionResult Edit(int id)
{
using (var chkl = new BusinessEntities())
{
var data = (from CuisinesData in chkl.Cuisines
join BusinessCuisineMappingData in chkl.BusinessCuisineMapping
on new { CuisinesData.Id, id } equals new { BusinessCuisineMappingData.CuisinesId, BusinessCuisineMappingData.BusinessId }
where CuisinesData.BusinessTypeId == 2
select new CusinesDTO
{
Id = CuisinesData.Id,
Name = CuisinesData.Name,
IsSelected = BusinessCuisineMappingData.CuisinesId == null ? false : true
}).Distinct().ToList();
ViewBag.CuisineList = data;
}
return View();
}
This is my DTO class:
public class CusinesDTO
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
I want to comape the "id" with the "BusinessCuisineMappingData.BusinessId" field in my LINQ join, which I am getting through the [HttpGet] Actionresult Edit(int id). It prompts me an error while I try to implement it.
You cannot use a local variable in the join. However, you can use it in a Where clause. So if you do
join ...
on CuisinesData.Id equals BusinessCuisineMappingData.CuisinesId
...
where BusinessCuisineMappingData.BusinessId == id
you'll have the same effect.
"The type of the expressions in join clause is incorrect. Type inference failed in the call to 'Join'"
This suggests the types on either side of your JOIN are not equal. You are getting a compiler error; should be relatively easy to check the types on either side of your JOIN clause.
edit: rereading what you have put, I think something like the below is what you want to do:
[HttpGet]
public ActionResult Edit(int id)
{
using (var chkl = new BusinessEntities())
{
var data = (from CuisinesData in chkl.Cuisines
join BusinessCuisineMappingData in chkl.BusinessCuisineMapping
on CuisinesData.Id equals BusinessCuisineMappingData.CuisinesId
where CuisinesData.BusinessTypeId == id
select new CusinesDTO
{
Id = CuisinesData.Id,
Name = CuisinesData.Name,
IsSelected = BusinessCuisineMappingData.CuisinesId == null ? false : true
}).Distinct().ToList();
ViewBag.CuisineList = data;
}
return View();
}
I have am Emp table that looks like this:
.
I have created a stored procedure which looks like this
ALTER PROCEDURE [dbo].[GetAllEmployees]
AS
BEGIN
OPEN SYMMETRIC KEY TestTableKey DECRYPTION
BY CERTIFICATE EncryptTestCert
SELECT
EMPId,
Firstname,
Lastname,
AddessId,
JobId,
DateofBirth,
CONVERT(NVARCHAR(50),DECRYPTBYKEY(EncryptFirstname)) AS [EncryptFirstname],
CONVERT(NVARCHAR(50),DECRYPTBYKEY(EncryptLastname)) AS [EncryptLastname]
FROM
EMPloyee
END
The reason I have created a stored procedure is to convert some of the varbinary columns in the table to strings and use it with EF in MVC3.
The way I have mapped the procedure in the model is as below.
In my EmployeeViewModel this is the way I am mapped the properties to fields
[Description("EmployeeDetails")]
public class EmployeeViewModel: IEmployeeModel
{
public Guid EmpId { get; set; }
[Display(Name = "EncryptLastName")]
public byte[] EncryptLastName { get; set; }
[Display(Name = "EncryptFirstName")]
public byte[] EncryptFirstName { get; set; }
[Display(Name = "LastName")]
public string LastName { get; set; }
}
In access the stored procedure in my service method, this is the way I am accessing it.
public List<EmployeeViewModel> GetEmpList()
{
var ent = new EncryptionEntities();
List<Employee> allEmp = new List<Employee>();
allEmp = ent.GetEmployees().ToList();
ConvertViewModelObject cvmo = new ConvertViewModelObject();
List<EmployeeViewModel> empVM = new List<EmployeeViewModel>();
foreach (var item in allEmp)
{
empVM.Add(cvmo.ConvertFromEmployee(item));
}
return empVM.ToList();
}
ERROR in this method:
The 'EncryptFirstname' property on 'Employee' could not be set to a
'String' value. You must set this property to a non-null value of type
'Byte[]'.
In my stored procedure if I am simply display the EncryptFirstname as it islike, with out converting to string, no error occurs, but the value I will be getting is system.byte[].
But it needs to be in string format so that I can understand what value it is of?
Please advise, what should I do to display it correctly.
This is the way I am converting the entity to entityViewmodel.
public EmployeeViewModel ConvertFromEmployee(Employee emp)
{
if (emp == null)
return null;
var evm = new EmployeeViewModel();
evm.LastName = emp.Lastname;
evm.EncryptFirstName = emp.EncryptLastName;
return evm;
}
I found this article to be very helpful and I found the answer in the section titled "Importing Stored Procedures that Return Types Other than Entities". So the solution is in your last screen shot above where you are in the dialog box "Add Function Import" instead of selecting the Entities radio button, first click on the "Get Column Information", then click on the "Create New Complex Type" button. Now you can go back up and select the "Complex" radio button and select this new type from the drop down. Now you can just set your view to use this model and you will be all set.