I'm learning JavaFX 8 and working on Tableview.
I know we can add data to table view by using following steps.
ObservableList<PersonCode> data =
FXCollections.observableArrayList(
new PersonCode("Jacob", "Smith"),
new PersonCode("Isabella", "Johnson"),
new PersonCode("Ethan", "Williams"),
new PersonCode("Emma", "Jones"),
new PersonCode("Michael", "Brown")
);
Then set Column cellValueFactory
TableColumn<PersonCode, String> firstName = new TableColumn<PersonCode, String>("First Name");
firstName.setCellValueFactory(new PropertyValueFactory<PersonCode, String>("aName"));
TableColumn<PersonCode, String> lastName = new TableColumn<PersonCode, String>("Last Name");
lastName.setCellValueFactory(new PropertyValueFactory<PersonCode, String>("aNameLast"));
and then table.setItems(data);
But my question is, can we add data to table's column without creating another class? As in my previous example I have created PersonCode class. But I want to add following data to tableview.
ObservableList<String> data = FXCollections.observableArrayList("Good","Luck","Bad");
As I was reading Tableview Doc there I found this line.
When you create a table in a JavaFX application, it is a best practice
to implement a class that defines the data model and provides methods
and fields to further work with the table. Example 13-3 creates the
Person class to define data in an address book.
So I'm expecting we can add data without creating a separate class. How? any idea?
Related
I am trying to create an "add Employee form" with basic attributes like name gender email etc which users can fill in
in the form, there will be a drop down options for departments available where the list will be pre-populated by a linkedhashmap that will be sent over from the controller
I have already added an attribute object type "Employee" onto my model so when i fill in the form
and return to controller, the employee object will be set automatically
Controller.java
#GetMapping("/showFormForAdd")
public String showFormForAdd(Model theModel) {
//fetch new list(if any) of departments added
List<Department> theDepartments = departmentService.getDepartments();
//Create a linkedhash map to hold our department_id-department name information
final LinkedHashMap<Integer, String> departmentOptions = departmentService.generateDepartmentOptions(theDepartments);
// create new employee object and attach to our model atrribute.
//how to add multiple objects?? doing this so i can pre-populate available departments for selection
theModel.addAttribute("employee", departmentOptions);
Employee theEmployee = new Employee();
//how to add multiple objects?? doing this so when program return control to controller it will help me set the attribute of employees so I can save it into the database
theModel.addAttribute("employee", theEmployee);
return "customer-form";
}
The problem:
How do i add multiple attributes for example, the employee object and the linkedhashmap onto my model so I can prepopulate the selection box and at the same time have methods available for my controller to set attributes for my employee object and save into my database when I return control to the controller?
any help will be appreciated..thanks!
EDIT:
just an update, every answer provided works..i was getting mixed up.
Instead of using same key to add different object, use different key for different object
for example :
//use key "departmentOptions" for LinkedHashMap
theModel.addAttribute("departmentOptions", departmentOptions);
Employee theEmployee = new Employee();
//use key "employee" for employee object
theModel.addAttribute("employee", theEmployee);
If I got it correct(from your code's comment)
//how to add multiple objects?? doing this so i can pre-populate
available departments for selection
You have to simply set different name for each object in your modelAttribute. In your code, you used same name twice, so the departmentOptions employee object will be replaced by the later employee object. To overcome this, just set their unique name and you can send list of objects or different single type object like:
//adding multiple object to modelAttribute.
theModel.addAttribute("departmentOptions", departmentOptions);
Employee theEmployee = new Employee();
theModel.addAttribute("employee", theEmployee);
-----
theModel.addAttribute("anotherObject", anotherObject);
I will need create custom widget for search products from our database product table. I can create and use ComboBox widget but there is products table many rows so as then way do not right. I will need same ComboBox itself first only show 50 rows and after LookUp search gets some data from product tables. Give me some ideas or library made for LookUp widget!
You should use JFXAutoCompletePopup.
Here is a simple example of JFXAutoCompletePopup:
JFXTextField field = new JFXTextField();
field.setLabelFloat(true);
field.setPromptText("Type Something");
JFXAutoCompletePopup<String> autoCompletePopup = new JFXAutoCompletePopup<>();
autoCompletePopup.setSelectionHandler(event -> field.setText(event.getObject()));
autoCompletePopup.getSuggestions().addAll("Film", "Book", "Paper");
field.textProperty().addListener(observable ->{
autoCompletePopup.filter(s -> s.contains(field.getText()));
if(!autoCompletePopup.getFilteredSuggestions().isEmpty()){
autoCompletePopup.show(field);
}else{
autoCompletePopup.hide();
}
});
Regards,
I want to put the data from a TableView into a Collection of Maps. Each Map represents a row in the table and contains the columnName-entry-pairs of all visible columns.
Now the tricky part for me is to get the data from the visible columns only.
On the TableView, I could call getItems(), but how could I then check which column is visible?
With getColumns(), I can check which column is visible, but how could I then get the corresponding data?
The easiest thing would be a way to iterate through all visible columns - but I can't find a way to do this.
Can anyone give me a hint or a pointer in the right direction?
You can try this, though I did not test this:
final ObservableList<Map<String, Object>> collection = FXCollections.observableArrayList();
tableView.getItems().forEach(item -> {
final Map<String, Object> itemMap = new HashMap<>();
tableView.getVisibleLeafColumns().forEach(column -> {
itemMap.put(column.getText(), column.getCellObservableValue(item).getValue());
}
collection.add(itemMap);
});
I want a certain column of a TableView to be sorted by default. How would I do this? I tried doing column.setSortType(SortType.ASCENDING);, as well as putting it in a runLater call. I looked at the JavaDocs and stuff and all I can see that may be of interest is the peculiar setSortPolicy method.
To perform a "one-off" sort, call
tableView.getSortOrder().setAll(...);
passing in the TableColumn(s) by which you want the data sorted.
To make the sort persist even as the items in the list change, create a SortedList and pass it to the table's setItems(...) method. (To change the items, you will still manipulate the underlying list.)
As an example, using the usual contact table example you could do:
TableView<Person> table = new TableView<>();
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
TableColumn<Person, String> lastNameCol = new TableColumn<>("
Last Name");
firstNameCol.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());
ObservableList<Person> data = FXCollections.observableArrayList();
SortedList<Person> sortedData = new SortedList<>(data);
// this ensures the sortedData is sorted according to the sort columns in the table:
sortedData.comparatorProperty().bind(table.comparatorProperty());
table.setItems(sortedData);
// programmatically set a sort column:
table.getSortOrder().addAll(firstNameCol);
// note that you should always manipulate the underlying list, not the sortedList:
data.addAll(new Person(...), new Person(...));
Called at the end of the table initialisation...
colChecked.setSortType(TreeTableColumn.SortType.DESCENDING);
colDate.setSortType(TreeTableColumn.SortType.DESCENDING);
treeView.getSortOrder().setAll(colChecked, colDate);
i hav a ArreayList which is contain PRIvariable(name of the class) class data. Below shows my part of the java code. So now i want to put this Arraylist data to Jtable. how can i do that. Here i already added pri.dateText , pri.sum , pri.count to ar(arraylist)
PRIvariable pri=new PRIvariable();
while (reader.ready()) {
String line = reader.readLine();
String[] values = line.split(",");
if(values[2].equals(pri.incDate)){
if(values[4].equals("KI")){
pri.dateText=values[2]+" "+values[4];
pri.count=pri.count+1;
pri.sum = pri.sum+Integer.parseInt(values[7]);
}
}
}
System.out.println(pri.dateText+" "+pri.sum+" "+pri.count);
ar.add(pri);
Like all Swing components, a JTable relies upon the MVC pattern (at multiple levels, but that's not the subject).
You have one view (the JTable), one model (I'll come back on it later), and a controller (implemented here as a set of event listeners : one controller for each kind of control).
The array you have could be a good model starting point. However, Swing provides far better way to inject your data in JTable. Indeed, a JTable uses as model an implementation of TableModel. Hopefully, there already exist an implementation : DefaultTableModel.
So, here is what I suggest to you : create DefaultTableModel, put in its rows/columns all the data you want to display in your table, then call JTable#setModel(TableModel) to have thze table display your data.
Obviously, you'll soon find various misfits between DefaultTableModel and what you want to do. It will then be time for you to create our very own table model. But that's another question.
Besides, don't forget to take a look at Swing tutorial, it's usually a good thing when dealing with Swing components.
I don't see where you have an ArrayList anywhere.
First you create a PRIvariable object. Then you keep looping as you read a line of data from the file. For each line of data you split it into individual tokens and then add some of the token data to the PRIvariable ojbect. The problem is that you only have a single PRIVariable object. So every time you read a new line of data you change the values of the PRIvariable object. After all the looping you add this single PRIvariable object to your ArrayList, but you will only ever have one object in the ArrayList.
The easier solution is to update the TableModel as you get the data. Something like:
DefaultTableModel model = new DefaultTableModel(...);
JTable table = new JTable( model );
...
...
while (reader.ready())
{
String line = reader.readLine();
String[] values = line.split(",");
String[] row = new String[3];
row[0] = values[?];
row[1] = values[?];
row[2] = values[?];
model.addRow( row );
}
Look into GlazedLists. They make it extremely easy to create a suitable TableModel object from your list.
ArrayList< PRIvariable> myList = new ArrayList<PRIvariable>();
... fill up the list ...
// This assumes your object has a getName() and getAge() methods
String[] propertyNames = {"name","age"};
String[] columnLabels = {"Name","Age"};
// Are these columns editable?
boolean[] writeable = {false, false};
EventList<PRIvariable> eventList = GlazedLists.eventList(myList);
EventTableModel<PRIvariable> tableModel = new EventTableModel<PRIvariable>(eventList,propertyNames,columnLabels,writable);
JTable table = new JTable(tableModel);