Hello everybody I just created two JTable components and two array lists.
The first ArrayList contains questions' data (question ID, question Description, Key answer) and another array list contains options' data (option Id, option description).
First table gets questions data from first array list and shows it.
And each question in this table has multi options.
enter image description here
I want when I select row in questions' table, the options of this question will appear. How can I do that?
Below I post two functions that are used to show data:
private void showQuestions(){
int rowCount= question_table.getRowCount();
Object question[]=null;
DefaultTableModel t = (DefaultTableModel) question_table.getModel();
for(int i=0;i<examQuestions.size();i++){
question =new Object[]{examQuestions.get(i).question_id,examQuestions.get(i).questionDescription,examQuestions.get(i).keyAnswer};
t.addRow(question);
}
question_table.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
public void valueChanged(ListSelectionEvent event) {
}
});
}
private void showOption(){
int rowCount = option_table.getRowCount();
Object option[]=null;
DefaultTableModel t = (DefaultTableModel) option_table.getModel();
for(int i = 0;i <=examQuestions.size()-1;i++){
for(int j = 0; j <=examQuestions.get(i).answerOptions.size()-1;j++){
option = new Object[]{ j+1, examQuestions.get(i).answerOptions.get(j)};
t.addRow(option);
}
}
}
Related
I have a void method that prints the data in a nice table in another class. I would like to ask how can I print the contents of this void method on a JFrame?
public void printInformation(Person[] data) {
for (int i=0, i<data.length' i++){
System.out.println(data[i].getName() + " | " data[i].getSurname());
}
}
The data can be printed in JFrame by using the JTable class.
JTable table;
public void createTable(Person[] data) {
String[] columnNames = {"Name", "Surname"};
String[][] people = new String[data.length][2];
for (int i=0, i<data.length, i++){
people[i] = {data[i].getName(), data[i].getSurname());
}
table = new JTable(people, columnNames);
}
JTable have the constructor:
JTable(Object[][] rowData, Object[] columnNames)
You can create two arrays: one containing your data set and one containing the column names. Using the two arrays you can output a table in JFrame
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 written a GUI Java program that manages a MySQL database. The user selects which columns (which tables and columns will be selected from the database) he/she wants to populate the JTable with.
I hard-coded the column names for the JTable so even if the user chooses to only display the data from a subset of columns, all of the column-names will be visible.
The problem is that when the user chooses columns in a different order than my JTable is anticipating, the data gets displayed in the wrong column.. It's a bit hard to explain so here's a screenshot of the genre data being loaded into the length column:
tableGenerator class:
package gui;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Vector;
public class TableGenerator
{
private ArrayList columnNames = new ArrayList();
private ArrayList data = new ArrayList();
private Vector columnNamesVector = new Vector();
private Vector dataVector = new Vector();
private int columns = 0;
private int rows = 0;
#SuppressWarnings("unchecked")
public TableGenerator(ResultSet rs)
{
try{
ResultSetMetaData md = rs.getMetaData();
columns = md.getColumnCount();
// Get column names
columnNames.add("Title");
columnNames.add("Year");
columnNames.add("Length");
columnNames.add("Genre");
columnNames.add("Actor");
columnNames.add("Producer");
columnNames.add("Director");
columnNames.add("Writer");
// Get row data
while (rs.next())
{
ArrayList row = new ArrayList(columnNames.size());
for (int i = 1; i <= columns; i++)
{
row.add(rs.getObject(i));
}
data.add( row );
rows++;
}
}
catch (SQLException e)
{
System.out.println( e.getMessage() );
}
// Create Vectors and copy over elements from ArrayLists to them
// Vector is deprecated but I am using them in this example to keep
// things simple - the best practice would be to create a custom defined
// class which inherits from the AbstractTableModel class
for (int i = 0; i < data.size(); i++)
{
ArrayList subArray = (ArrayList)data.get(i);
Vector subVector = new Vector();
for (int j = 0; j < subArray.size(); j++)
{
subVector.add(subArray.get(j));
}
dataVector.add(subVector);
}
for (int i = 0; i < columnNames.size(); i++ )
columnNamesVector.add(columnNames.get(i));
}
public Vector getColumns(){
return columnNamesVector;
}
public Vector getData(){
return dataVector;
}
public ArrayList getColumnNames(){
return columnNames;
}
public int getNumberOfRows(){
return rows;
}
}
I'm using the DefaultTableModel with some modifications.. :
model = new DefaultTableModel(rows, columns){
private static final long serialVersionUID = 1L;
#Override
public boolean isCellEditable(int row, int column) {
return false;
}
#Override
public Class<?> getColumnClass(int column) {
if (column < classes.length)
return classes[column];
return super.getColumnClass(column);
};};
Your query should always return the data for all columns. This means the data will be stored in the same manner in the TableModel.
You can then change the view for the columns to be displayed. That is you can remove TableColumns from the TableColumnModel of the JTable and only the data the user want to view will be displayed, even though it is still available in the model. Then means the user can click on any check box at any time and you don't need to redo the database query, only add the TableColumn back to the table.
Check out Table Column Manager for an example of this approach. This class uses a popup menu to manage the columns, but you can still use your check boxes. You just need to invoke the appropriate method of the TableColumnManager to hide/show a column. That is, assuming the labels of the check boxes match the headings in the table you can just use the check box text to hide/show a column.
The other approach is to NOT hard code the column names (if you build your query to only get specific columns) but instead get the column names from the meta data of the ResultSet. The TableFromDatabaseExample.java from Table From Database shows how this can be done. The code is generic so that appropriate renderers are used for Dates, Integers etc.
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.
I have a JTable using setAutoCreateRowSorter(true) and a RowSorterListener attached, per below, because I need to perform some operations elsewhere in my application upon a sort of the JTable.
I find that whenever I click a column header to sort, the JTable redisplays the rows in the proper order and the listener is called, but the TableModel I pull out is always the original pre-sort table model.
table.getRowSorter().addRowSorterListener(new RowSorterListener() {
#Override
public void sorterChanged(RowSorterEvent rsevent) {
rsevent.getSource().getModel(); // Nope, original ordering here
table.getModel(); // Same thing
}
};
How do I get the new post-sort ordering of the rows, as is now displayed in the JTable?
The data in the TableModel never changes, only the view of the data changes.
If you want the data from the model in the order it is displayed in the table then you just use:
table.getValueAt(row, column);
In other words you need to iterate through all the rows and columns to get the data in the currently viewed order.
I think you can use table.convertRowIndexToModel(int ...), however I think that there's a better solution available.
If you define your own convertRowIndexToModel() that's a quick lookup (perhaps through a map, O(1)), that solution should be sufficient. If it's O(n), then that's what needs to be fixed.
Simply go through a loop of the rows, convert each one and do the lookup using the resulting index.
Here's 2 methods in TableSorter that should be of interest:
private Row[] getViewToModel() {
if (viewToModel == null) {
int tableModelRowCount = tableModel.getRowCount();
viewToModel = new Row[tableModelRowCount];
for (int row = 0; row < tableModelRowCount; row++) {
viewToModel[row] = new Row(row);
}
if (isSorting()) {
Arrays.sort(viewToModel);
}
}
return viewToModel;
}
and:
private int[] getModelToView() {
if (modelToView == null) {
int n = getViewToModel().length;
modelToView = new int[n];
for (int i = 0; i < n; i++) {
modelToView[modelIndex(i)] = i;
}
}
return modelToView;
}
Hi I know this is a really late answer, but I tried the code used on the comment of #LazyCubicleMonkey and it did work here is my code in getting the row when the jTable is sorted.
DefaultTableModel search_model = (DefaultTableModel) jTable.getModel();
search_model.removeRow(jTable.convertRowIndexToModel(row));
jTable.setModel = (search_model)