I want to get information about user from the JTable. Everything is okay, but when I sort the array by name, the objects get read wrong. Example:
Here is everything ok
Above everything is ok. I choose 4 value from the table, shows me 4 items from the Users list. Two books are displayed. But now I sort by 'number of loans', and i choose user with two loans. But the array reads as 'you chose the first value' and shows the first value from the User list.
After sorting
I'd like to receive a specific user after selecting from the board. Thanks.
My code:
tablicaWypozyczen.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int row = tablicaWypozyczen.rowAtPoint(e.getPoint());
int col = tablicaWypozyczen.columnAtPoint(e.getPoint());
if (row >= 0 && col >= 0) {
JOptionPane.showMessageDialog(null, Dane.uzytkownicyZWypozyczeniami.get(row).toString(), "Informacje o użytkowniku", 1);
System.out.println(tablicaWypozyczen.getSelectedRow());
}
}
}
});
but when I sort the array by name,
Why are you sorting the Array?
Data is stored in the TableModel. The sorting should be done on the table, not on data in some external array. You don't want data in two places, it is too hard to keep the data in sync.
Read the section from the Swing tutorial on Sorting and Filtering for more information.
If you want to get the sorted value from the table you use:
table.getValueAt(table.getSelectedRow(), theColumn);
Related
I'm trying to figure out how to iterate through the rows of a JTable and get the cell values if the row is selected (multiple rows can be selected), pass the values to a method then continue iteration. The table rows contain values entered by the user. Rows are added to the table, which is displayed in the UI one by one as the user inputs each entry. The entries consist of an int and 2 doubles. The int identifies the type and the two doubles are added to two running tallies (quantity and volume) for the type, for use elsewhere in the application. If the user selects a row (or multiple rows) and presses Delete, the rows are deleted from the table. The values of the deleted rows also need to be deducted from the running tallies. For deleting the rows, I am assigning the selected rows to an array and iterating through it to delete each row.
int[] selectedRows = entryTable.getSelectedRows();
if (selectedRows.length > 0) {
for(int i = selectedRows.length - 1; i >= 0; i--) {
entryTable.removeRow(selectedRows[i]); } }
If it is possible to get the cell values during this iteration, that would be ideal but after extensive searching, I have not yet found a way to do so. Any other way would be fine as long as the end result is the same. Any thoughts on the most efficient way to accomplish this would be appreciated.
Well you can try like this.
public void myMethod(JTable entryTable) {
DefaultTableModel model = (DefaultTableModel) entryTable.getModel();
if (entryTable.getRowCount() > 0) {
if (entryTable.getSelectedRowCount() > 0) {
int selectedRow[] = entryTable.getSelectedRows();
for (int i : selectedRow) {
int id = Integer.parseInt(entryTable.getValueAt(i, 0).toString());
double val1 = Double.parseDouble(entryTable.getValueAt(i, 1).toString());
double val2 = Double.parseDouble(entryTable.getValueAt(i, 2).toString());
model.removeRow(i);
}
}
}
}
I have a program which uses a JTable.
I have given it a RowSorter so that when you click on the column headings the table sorts by that column.
I want to capture the user clicking on the column header and output a debug message.
e.g.
System.out.println("You have sorted by first name ascending");
System.out.println("You have sorted by first name descending");
System.out.println("You have sorted by last name ascending");
So I need to respond to the sort event.
I have searched for examples online but I can't find any.
Yes, but it is not part of JTable but RowSorter. You can add a RowSorterListener:
table.getRowSorter().addRowSorterListener(new RowSorterListener() {
#Override
public void sorterChanged(RowSorterEvent e) {
// Sorting changed
}
});
I have a JTable displaying contents in this format:
Part Number Quantity Price
SD1131 7 1,000
SD6534 6 2,000
On the same frame I have a JTextfield(txtNo). I need it such that when the user types the Part Number on the JTextfield, the corresponding record is selected on the JTable. So far I have only been able to select records based on the row number like this:
txtNo.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
int index1 = 0;
int index2 = 0;
try {
index1 = Integer.valueOf(txtNo.getText());
tbStore.setRowSelectionInterval(index2, index1);
} catch (Exception ae) {
ae.printStackTrace();
}
}
});
How can I implement the same method to select the JTable row based on the input of the JTextfield?
You will need to find the item in your table for which the part number is equal to the part number entered in the textfield. Steps to take:
Read the contents of your textfield
Search the index of the matching element in the TableModel
Convert that index to the corresponding row index in the JTable using the convertRowIndexToView method (to take in account sorting, filtering, ... )
Use the setRowSelectionInterval method of the JTable to select that row
As an alternative, you can use the JXTable of the SwingX project which has searching capabilities built-in. The SwingX library also includes a component which allows to search such a JXTable (see JXSearchPanel and JXSearchField)
You should interrogate the TableModel and find out which row contains the part number you are looking for:
for(int i=0;i<tbStore.getRowCount();i++) {
// 0 is for the column Part number
if(tbStore.getValueAt(i, 0).equals(Integer.valueOf(txtNo.getText())) {
tbStore.setRowSelectionInterval(i, i);
break;
}
}
Caveats: I haven't tested this code, but it should give you at least the basic idea.
I'm having difficulties getting the following code to preserve the logically selected row in the model if the JTable has been sorted.
It works as intended when no sorting is applied.
private void updateAccountTable() {
accountsTable = guiFrame.getAccountsTable();
// Preserve selected model row
String accountNumber = "";
int selectedRow = accountsTable.getSelectedRow();
if(selectedRow >= 0){
accountNumber = (String)accountsTable.getValueAt(selectedRow, 0);
}
// Preserve sort order
// Keep eclipse happy. better way??
List <? extends SortKey> keys = accountsTable.getRowSorter().getSortKeys();
// Update displayed accounts
DefaultTableModel model = (DefaultTableModel) accountsTable.getModel();
model.getDataVector().clear();
Object[][] tableContents = accountList.getAccountsAsArray(true);
model.setDataVector(tableContents, tableHeaders);
model.fireTableDataChanged();
// reset sort order
accountsTable.getRowSorter().setSortKeys(keys);
// If updated model contains previously selected account, reselect
if (!accountNumber.equals("") && null != accountList.getAccount(accountNumber)){
for (int row=0; row<accountsTable.getRowCount(); row++){
String an = (String)accountsTable.getValueAt(row, 0);
if (an.equalsIgnoreCase(accountNumber)){
accountsTable.setRowSelectionInterval(row, row);
break;
}
}
}
else {
accountsTable.clearSelection();
}
}
Unfortunately setRowSelectionInterval() doesn't updated the selected row as expected, despite being called with the correct view row number. It seems to do nothing.
.....So,
Why is setRowSelectionInterval() failing to updated the selection, or what have I missed?
The row obtained from getSelectedRow() is in view coordinates, while the model coordinates have been changed by the intervening update. Quoting from the relevant tutorial section:
This distinction does not matter unless your viewed data has been rearranged by sorting, filtering, or user manipulation of columns.
You will need to use the conversion methods described near the end of Sorting and Filtering, which suggests:
When using a sorter, always remember to translate cell coordinates.
When you click on Jtable header to sort it, and click on a row (ex. 3rd row), you will get the value of unsorted JTable's row. To avoid this situation, use this LOC.(ik this is irrelvant to what you're trying to do but for others w/ similar problems)
int row = tblUser.getSelectedRow();
//Without below line, the value you get would be the row before sorting
int correctModel = tblUser.convertRowIndexToModel(row);
//Get username and use it to find its corresponding tuple
String username = (tblUser.getModel().getValueAt(correctModel, 1)).toString();
My table looks like this and Im trying to get the username of the selected row and w/o the 2nd LOC, I'd get the unsorted JTable's row value even after sorting it:
---------------------
| id | username |
---------------------
| | |
I am searching through an array and matching the users entered date with ones stored in the array.
The code is working fine and finds dates or gives appropriate error messages perfectly, the only issue is due to the nature of my program it leaves the possibility of multiple records having the same date.
Now, I only have one form displaying each search result in this format:
lbl txtField
lbl txtField
etc, if the date is matched, it will display the REST of the data matching the record in the text fields.
Now, how would it be possible to display every record's data that has matched a date?
My Code:
public void searchDay() {
String idInputString = JOptionPane.showInputDialog(null, "Please enter the Date you're searching for using the format: DD/MM/YYYY");
for (int i = 0, count = 0; i < orderID.length; i++) {
if (idInputString.equals(startDate[i])) {
txtOrderID.setText(orderID[i]);
txtOrderForename.setText(customerForename[i]);
txtOrderSurname.setText(customerSurname[i]);
txtOrderAddress1.setText(address1[i]);
txtOrderAddress2.setText(address2[i]);
txtOrderTown.setText(town[i]);
txtOrderCounty.setText(county[i]);
txtOrderPost.setText(postCode[i]);
txtOrderCarModel.setText(carModel[i]);
txtOrderCarReg.setText(carReg[i]);
txtOrderStartDate.setText(startDate[i]);
txtOrderStartTime.setText(startTime[i]);
txtOrderSerial.setText(serialNum[i]);
count++;
}
if(i == orderID.length - 1 && count==0){
JOptionPane.showMessageDialog(null, "Order ID Doesn't Exist", "Error!", JOptionPane.WARNING_MESSAGE);
break;
}
}
}
Thank you.
Create more text fields on the fly, or drop results into a JTable.
The final UI could have a JList at the PAGE_START of the GUI that lists the orders for a day or range, but only displays the 'order number'. Then have a JPanel that contains a group of labels and field in the CENTER to display the details of an order selected in the list.
A JTable as suggested by #Ray might be a viable alternative, but I sometimes feel the data is more complex than can be well presented in a single table row (using one row per order).