I'm designing a project about cataloging something. In this project user must be able to create his own table as he wish. Therefore I do not have any static class and instance of it.
I'm creating a diaglog pane and I can create textfields for user inputs according to column names of database table dynamically but how can i add those user's inputs into the tableView ?
As I can add any String input into the ListView can I add user String inputs into tableView columns?
ListView<String> listView = new ListView();
public ObservableList<String> listCatalogNames = FXCollections.observableArrayList();
listCatalogNames.add("Books");
More details with an example;
There is listview that contains all catalog names and according to lisview selection tableview will be created dynamically center of borderpane.
User have books(name, author, page) and movies(name, year, director, genree) catalogs.
Lets say user selected movies and tableView appeared with 4 columns and clicked add button. Diaglog pane created with 4 textfield. I built everything until that point but I cannot add user's input into the tableView because i dont have any static class for Movies or Books etc.
Is there any way to create dynamic class ?
Please give me an idea and help me about that situation.
here is the github link of our project
Just use String[] storing the Strings for every column of a row (or a similar data structure) as item type for the TableView. It should be simple enough to create a String[] from the inputs and add it to this TableView:
static TableView<String[]> createTable(String... columnNames) {
TableView<String[]> table = new TableView<>();
for (int i = 0; i < columnNames.length; i++) {
final int index = i;
TableColumn<String[], String> column = new TableColumn<>(columnNames[i]);
column.setCellValueFactory(cd -> new SimpleStringProperty(cd.getValue()[index]));
table.getColumns().add(column);
}
return table;
}
Adding a String[] userInputs to a TableView<String[]> table would be done like this:
table.getItems().add(userInputs);
A similar issue (creating a TableView based on the metadata of a ResultSet) can be found here: How to fill up a TableView with database data
Easiest solution that comes to my mind is to make use of polymorphism. You can create a super class of both Book and Movie, let's call it Item. Then you can declare your table to contain Item and cast to one of the concrete classes when you need to.
Related
Basically what I'm trying to do is, I create a type object with a name and attribute names (I tried to collect those attribute names in a tableview). Then I create items by selecting those types I created before. The Item object i create has its name,type and attribute names. What I want is, when I'm creating an item, I select a type. When I select that type, I want the tableview in item creating page to show selected types attribute names.item creating page is something like that
I tried something like this. Those are my initialize method and creatType methods.
any suggestions?
ObservableList<Types> list2 = FXCollections.observableArrayList();
ObservableList<Items> list3 = FXCollections.observableArrayList();
public void initialize(URL url, ResourceBundle resourceBundle) {
typeAttributesNames.setCellValueFactory(new PropertyValueFactory<Types, String>("typeAttributesNames"));
this.itemAttrValue.setCellValueFactory(new PropertyValueFactory<Items,String>("attributeValues"));
typeAttrNameColumn.setCellValueFactory(new PropertyValueFactory<Types,String>("typeAttributesNames2"));
attrNameTableView.setItems(list2);
itemsAttrTableView.setItems(list3);
}
public void createType(){
ObservableList<Types> typesObservableList=list2;
Types types= new Types(typesTextField.getText(),typesObservableList);
types.getTypesTitledPane().setText(typesTextField.getText());
typeTitledPaneVbox.getChildren().addAll(types.getTypesTitledPane());
typeNameComboBox.getItems().addAll(typesTextField.getText());
Types.typesArrayList.add(types);
typesTextField.clear();
typeNameComboBox.setOnAction(e ->
typeAttrTableView.setItems(typesObservableList));
attrNameTableView.getItems().clear();
}
so I'm stuck on something probably pretty basic. I've got data stored in an SQLite database table and want to display that in an expandable list view. The data basically forms as headings and subheadings. There's many sub-headings to a single heading.
Retrieving the data is pretty straightforward. The part I'm stuck at is taking that data and giving it to the expandable list view.
I want the expandable list view to display the headings as the item that can be expanded, with the subheadings as the child items. How can I do this?
Thanks in advance.
You must provide an adapter to ExpandableListView. There is a base class adapter that you can extend it for your needs.
For creating the data lists. Assume Column1 is Heading, Column2 is SubHeading, try this in activity/fragment:
ArrayList<String> headings = new ArrayList<>();
HashMap<String, ArrayList<String>> subheadings = new HashMap<>();
String heading, subheading;
do{
heading = cursor.getString(1);
subheading = cursor.getString(2);
ArrayList<String> tmpChild;
if(headings.contains(heading)){
tmpChild = subheadings.get(heading);
}else{
headings.add(heading);
tmpChild = new ArrayList<>();
}
tmpChild.add(subheading);
subheadings.put(heading, tmpChild);
}while (cursor.moveToNext());
For the adapter, try my answer here: Tree with checkBox
Hope that helps!
I have two JTables which share a TableModel.
This is so that I can set them up in a scroll pane such that one of them has a few columns showing on the left and does not scroll sideways, visually 'freezing' those columns, and the other contains the rest of the columns.
They are always sorted the same so that the rows match up. This is done using a RowSorter listener, shown below. (frozenTable and tableView are the names of my JTables).
RowSorterListener rowSorterListener = new RowSorterListener() {
#Override
public void sorterChanged(RowSorterEvent e) {
if (RowSorterEvent.Type.SORT_ORDER_CHANGED == e.getType()) {
RowSorter source = e.getSource();
if (source == tableView.getRowSorter()) {
frozenTable.getRowSorter().removeRowSorterListener(this);
frozenTable.getRowSorter().setSortKeys(source.getSortKeys());
frozenTable.getRowSorter().addRowSorterListener(this);
} else {
tableView.getRowSorter().removeRowSorterListener(this);
tableView.getRowSorter().setSortKeys(source.getSortKeys());
tableView.getRowSorter().addRowSorterListener(this);
}
}
}
};
At another point in my code, I want to be able to get the TableColumn objects that are currently being sorted on. Before I added the frozentable, I was able to do this with the following code:
List<? extends SortKey> sortKeys = tableView.getRowSorter().getSortKeys();
for(SortKey key : sortKeys){
TableColumn column = tableView.getColumnModel().getColumn(key.getColumn());
// other stuff in the loop
}
It seems as though a SortKey only has two things in it, a column index and a SortOrder. This raises two questions:
How is my RowSorterListener even managing to sort the tables based on columns from one or the other table? If all I'm passing when I say 'setSortKeys' is 'sort by column 3' and column 3 is different for each JTable, then how is this working in the first place? Because it does work. If I have a Name column in the frozenTable and an Age column in the tableView and I sort by Age, it does sort both JTables by the Age column.
How do I get the TableColumn object associated with a SortKey?
Check out the Fixed Column Table which is a reusable class that allows you to share a model between two tables
The code to create the fixed column table is:
JTable table = new JTable(...);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
JScrollPane scrollPane= new JScrollPane( table );
FixedColumnTable fct = new FixedColumnTable(2, scrollPane);
JTable fixed = fct.getFixedTable();
I don't think you need the sorter listener.
You should just be able to share the RowSorter using code something like:
table.setAutoCreateRowSorter(true);
fixed.setRowSorter(table.getRowSorter());
table.setUpdateSelectionOnSort(true);
fixed.setUpdateSelectionOnSort(false);
I have a JTable in which I can add users with several attributes like age, name, etc. This works and the users are added to my arraylist and JTable.
Now what I want is when I choose the JTable row, to be able to get the object stored in the user's arrayList so that I can modify or delete them.
Here is the example of my code when I add users to the JTable:
private void jButtonAddAUserActionPerformed(java.awt.event.ActionEvent evt) {
User obj=new User();
obj.setName(jTextFieldName.getText());
obj.setAdress(jTextFieldAdress.getText());
obj.setNumCC(Integer.parseInt(jTextFieldNumCC.getText()));
obj.setTele(Integer.parseInt(jTextFieldTele.getText()));
obj.setUserName(jTextFieldUserName.getText());
obj.setPassword(jTextFieldPassword.getText());
DefaultTableModel model=(DefaultTableModel) jTableUsers.getModel();
model.addRow(new Object[]{
jTextFieldName.getText(),
jTextFieldAdress.getText(),
jTextFieldTele.getText(),
jTextFieldNumCC.getText(),
obj.isAdmin
});
usersList.add(obj);
JOptionPane.showMessageDialog(null,"Data inserted correctly.");
jTextFieldName.setText("");
jTextFieldAdress.setText("");
jTextFieldNumCC.setText("");
jTextFieldTele.setText("");
jTextFieldPassword.setText("");
jTextFieldUserName.setText("");
}
Edit:
Here is the code for removing users already working:
private void jButtonRemoverActionPerformed(java.awt.event.ActionEvent evt) {
DefaultTableModel model = (DefaultTableModel) jTableInvestidores.getModel();
User u = userList.get(jTableUsers.getSelectedRow());
userList.remove(u);
model.removeRow(jTableUsers.getSelectedRow());
JOptionPane.showMessageDialog(null,"Data removed.");
}
And here is the code for updating user that is still not working, im trying to update it from the jTextFields:
private void jButtonUpdateActionPerformed(java.awt.event.ActionEvent evt) {
DefaultTableModel model = (DefaultTableModel) jTableUsers.getModel();
userList.get(jTableUsers.getSelectedRow());
model.setValueAt(jTextFieldName.getText(), jTableUsers.getSelectedRow(),0);
model.setValueAt(jTextFieldAdress.getText(), jTableUsers.getSelectedRow(),1);
model.setValueAt(jTextFieldPhone.getText(), jTableUsers.getSelectedRow(),2);
model.setValueAt(jTextFieldNumCC.getText(), jTableUsers.getSelectedRow(),3);
User u =userList.get(jTableUsers.getSelectedRow());
JOptionPane.showMessageDialog(null,"Data updated.");
}
Can anyone please give me some help on this? Thanks!
you could use something similar to this. sadly you didn't specify how you want to edit the user.
User u=userList.get(table.getSelectedRow()); //get user for editing
int location=table.getSelectedRow(); //get location in list to maintain order
userList.remove(u); //remove selected user to edit variables
//modify user u
userList.add(location,u); //insert user at previous location in list
model.setRowCount(0); //reset table model
for (int i = 0; i < userList.size(); i++) { //refill table model
User u = userList.get(i); /7get user
Vector<Object> vhelp = new Vector<>(); //create vector to store the values of the variables from user
vhelp.add(/*your data*/); // 1 add per variable that should be displayed in table
model.addRow(vhelp); //add the data to the table model (fills the table with data)
}
your method should look like this:
DefaultTableModel model = (DefaultTableModel) jTableUsers.getModel();
User u = userList.get(jTableUsers.getSelectedRow());
int location=jTableUsers.getSelectedRow();
userList.remove(u);
u.setName(jTextFieldName.getText());
u.setAdress(jTextFieldAdress.getText());
u.setNumCC(Integer.parseInt(jTextFieldNumCC.getText()));
u.setTele(Integer.parseInt(jTextFieldTele.getText()));
//u.isAdmin can't tell what this has to be
userlist.add(location,u);
model.setRowCount(0);
for (int i = 0; i < userList.size(); i++) {
User u = userList.get(i);
Vector<Object> vhelp = new Vector<>();
vhelp.add(u.getName());
vhelp.add(u.getAddress());
vhelp.add(u.getTele());
vhelp.add(u.getNumCC());
vhelp.add(u.isAdmin);
model.addRow(vhelp);
}
JOptionPane.showMessageDialog(null, "Data updated.");
the users are added to my arraylist and JTable.
Don't store the data in two separate places. The data should only be stored in the TableModel of the JTable.
So you can create a custom "User" object to contain the data about each user. Then you can create a custom TableModel to hold "User" object which can be displayed and access by the JTable.
Now what I want is when I choose the JTable row, to be able to get the object stored in the user's arrayList so that I can modify or delete them.
Check out Table Row Model for a step by step approach on create the custom TableModel. It contains all the methods you need to dynamically add, access and delete objects from the TableModel.
I have a JTable defined in this way:
public JTable table_1;
model_3 = new DefaultTableModel();
table_1 = new JTable(model_3);
scrollPane_5.setViewportView(table_1);
Add row:
model_3.addRow(new Object[]{table.getValueAt(row,0) , table.getValueAt(row,1) ,table.getValueAt(row,2) , commentFood });
Remove Row:
model_3.removeRow(row); //row is an integer
Until here, it used to work properly. As you can see this table is defined as public because sometimes I need to fill it up from another JFrame in this way:
takeOrder to = new takeOrder();
//Get data from DB to resultSet
to.table_1.setModel(DbUtils.resultSetToTableModel(resultSet));
If I fill up the table in this way and try to add or remove my model_3, it will not work! Any suggestion that how I can add or remove to the table after using DbUtils.resultSetToTableModel(resultSet) will be appreciated.
As I couldn't find any information on the internet and I saw couple of people asked same question with no answer. I came up with this solution:
if (formOut) {
for (int i = 0; i < table_1.getRowCount(); i++) {
model_3.addRow(new Object[]{table_1.getValueAt(i,0),
table_1.getValueAt(i, 1), table_1.getValueAt(i, 2)});
}
}
formOut = false;
table_1.setModel(model_3);
fromOut is a boolean to check if I have used another model for my table. If so I add data from table to previous model, and then I reference that model to my table. Now I can add to that model as well.