JTable - Filter data - java

I'm trying to filter a JTable but the results are not as expected.
Below is the JTable with the added elements (I'm using MySQL to store the Data)
JTable with contents - Picture
When I try to filter the list for someone specific, I do not get the data from the table. For example, I search for "Ana" and nothing appears.
Search results for "Ana" - Picture
If I try to search using some "numbers", like the salary, I get the right result but the ID is not right. Pictures to clarify the issue below.
Wrong ID
Right ID
The Code to generate the ArrayList with the employees :
public static ArrayList<Angajat> listaAngajati() {
ArrayList<Angajat> listaAngajati = new ArrayList<>();
try (java.sql.Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/angajati", "root", "***");) {
Statement st = conn.createStatement();
st.executeQuery("select * from angajati");
ResultSet rs = st.getResultSet();
Angajat angajat;
while (rs.next()) {
angajat = new Angajat(rs.getInt("id"), rs.getString("nume"), rs.getString("prenume"), rs.getInt("varsta"), rs.getString("adresa"), rs.getDouble("salariu"));
listaAngajati.add(angajat);
}
} catch (SQLException ex) {
System.out.println("Error in database connection: \n" + ex.getMessage());
}
return listaAngajati;
}
public static void arataAngajati() {
ArrayList<Angajat> arataAngajati = listaAngajati();
DefaultTableModel model = (DefaultTableModel) tabelangajati.getModel();
Object[] rand = new Object[6];
for (int i = 0; i < arataAngajati.size(); i++) {
rand[0] = arataAngajati.get(i).getID();
rand[1] = arataAngajati.get(i).getNume();
rand[2] = arataAngajati.get(i).getPrenume();
rand[3] = arataAngajati.get(i).getVarsta();
rand[4] = arataAngajati.get(i).getAdresa();
rand[5] = arataAngajati.get(i).getSalariu();
model.addRow(rand);
}
}
Code to filter the JTable
private void cautaInTabelKeyReleased(java.awt.event.KeyEvent evt) {
DefaultTableModel tabel = (DefaultTableModel) tabelangajati.getModel();
String query = cautaInTabel.getText().toLowerCase();
TableRowSorter<DefaultTableModel> sort = new TableRowSorter<DefaultTableModel>(tabel);
tabelangajati.setRowSorter(sort);
sort.setRowFilter(RowFilter.regexFilter(query));
}
Question : How can I modify the code so when I try to search for a an employee using his name to get the right result (not like now - no results) and when trying to modify the employee data, to get the right ID as shown in the JTable (example in the pictures above) ?
EDIT
In order to filter the data from the table accordingly I had to use
sort.setRowFilter(RowFilter.regexFilter("(?i)" + query));
When I was filtering the table, only the view modified and not the values from the row (Even if I saw the values from the row 3 and values on the backend where from the row 1). I managed to modify the following row and the table works perfectly.
From :
int row = tabelangajati.getSelectedRow();
To :
int row = tabelangajati.convertRowIndexToModel(tabelangajati.getSelectedRow());

Related

Get Multiple columns in Result Set from sparql in Netbeans JTable

I am trying to select multiple columns in Jena result set and then binding the same to Java table.
When I select only one column, the result set is working fine but when I select two columns then the result set does not have any row although it has only columns:
Here is my Java code:
private void btnExecuteSPARQLActionPerformed(java.awt.event.ActionEvent evt) {
try
{
System.out.println("Executing SPARQL..."); // get the name list query
String queryString;
queryString = "PREFIX ssuet:<http://www.semanticweb.org/alinaanjum2/ontologies/2021/6/untitled-ontology-4#> "
+ txtQuery.getText();
com.hp.hpl.jena.query.ResultSet results = OpenOWL.ExecSparQl(queryString); //all method ExecSparQl from OpenOWL class
ResultSetFormatter.out(results);
// It creates and displays the table
JTable table = new JTable(buildTableModel(results));
JOptionPane.showMessageDialog(null, new JScrollPane(table));
}
catch (Exception ex)
{
System.out.println(ex);
}
}
//CODE ADDITION BY ALINA ANJUM STARTED ON 03-AUGUST-2021
public static DefaultTableModel buildTableModel(com.hp.hpl.jena.query.ResultSet rs)
throws SQLException {
List<String> metaData = rs.getResultVars();
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.size();
System.out.println(columnCount);
for (int column = 0; column <columnCount; column++)
{
columnNames.add(metaData.get(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.hasNext())
{
QuerySolution sol = rs.nextSolution();
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 0; columnIndex < columnCount; columnIndex++)
{
//vector.add(rs.getObject(columnIndex));
String columnName = columnNames.get(columnIndex);
vector.add(sol.getLiteral(columnName).getString());
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
}
The following Query is Perfectly returning values:
SELECT (str(?x) as ?name)
WHERE {
?Person ssuet:hasname ?x.
}
The following Query is working fine in Protege but not returning values in Result Set in Java:
SELECT (str(?x) as ?name)
(str(?y) as ?phone)
WHERE {
?Person ssuet:hasname ?x.
?Person ssuet:hasPhoneNumber ?y.
}
Screen shot of the OutPut in Netbeans:
Results for 2nd Query in protege:
ResultSets are iterators.
Calling ResultSetFormatter.out(results) exhausts the iterator (no more rows).
If you want to use the result twice, use ResultSetFactory.makeRewindable to get a result set that can be reset to the start.

Java ArrayIndexOutOfBounds Exception -

I have 2 panels in my form which bound to a parent panel which has its layout set to card layout.
In the JFrame's constructor, a database operation is performed and data is taken and used to fill a JList.
Then when a user clicks on an item, a new panel ( as part of CardLayout ) shows up with a JTable filled with data taken from a database according to the selection made by the user in the listbox .
The program is basically a clinic management system.
In this JFrame, the cashier can see the id numbers of patients who are to pay their bills . These id numbers are displayed as a list in the JList.
On clicking the list, a patient id is selected and then the drugs prescribed are queried from the database and displayed in the table along with drug id & price.
The problem is that I get an ArrayOutOfBoundsException whenever I try to add a row to the JTable.
These are declared outside the mouseclick event (globally)
private Connection medDbConn = Connect("medicines.db");
private PreparedStatement mPst = null;
private ResultSet mRs = null;
private Connection conn = Connect("bills.db");
private PreparedStatement pst = null;
private ResultSet rs = null;
private ArrayList medicines_fine = new ArrayList();
private ArrayList medicines_fine_name = new ArrayList();
private ArrayList medicines_fine_qty = new ArrayList();
private ArrayList medicines_id = new ArrayList();
private ArrayList medicines_price = new ArrayList();
private ArrayList medicines_subtotal = new ArrayList();
private Double cf = 0.00;
/**
* Creates new form ViewBills
*/
private DefaultListModel listmodel;
private DefaultListModel model;
The following is executed in the mouseclick event of the JList .
// GET SELECTED VALUE FROM LIST
String listvalue = (String) jList1.getSelectedValue();
// SPLIT THE SELECTED LIST VALUE INTO ID AND DATETIME
String[] datas = listvalue.split("=");
// datas[0] = id and datas[1] = datetime
// STORE PATIENTID and DATETIME
String Patient_Id = datas[0].trim();
String DateTime = datas[1].trim();
String medicines_raw = null;
String[] medicines;
String[] keypair;
try {
// CONNECT THE DATABASE & PREPARE IT . THEN SET THE VALUES & FURTHER EXECUTE QUERY TO GET RESULT INTO "rs"
pst = conn.prepareStatement("SELECT CONSULTFEE,MEDICINES FROM VIEWBILLS WHERE ID=? AND DATETIME=?");
pst.setString(1, Patient_Id);
pst.setString(2, DateTime);
rs = pst.executeQuery();
// IF THERE IS A RECORD , THEN DO SOMETHING
if (rs.next()) {
cf = rs.getDouble("consultfee");
// GET THE RAW VALUE IN THE FORMAT Aspirin=12,sdsd=1,asdasd=2
medicines_raw = rs.getString("medicines");
// SPLIT THE WORD BY COMMAS AND STORE INTO ARRAY , SO EACH INDEX has Aspirin=12 kind of values
medicines = medicines_raw.split(",");
for (int i = 0; i < medicines.length; i++) {
medicines_fine.add(medicines[i]);
}
for (int i = 0; i < medicines_fine.size(); i++) {
keypair = medicines_fine.get(i).toString().split("=");
medicines_fine_name.add(keypair[0]);
System.out.println(keypair[0]);
System.out.println(keypair[1]);
medicines_fine_qty.add(keypair[1]);
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
CardLayout cl = (CardLayout) Parent.getLayout();
cl.show(Parent, "card3");
// SECOND DATABASE CONNECTION STARTS HERE ...
for (int i = 0; i < medicines_fine_name.size(); i++) {
try {
pst = medDbConn.prepareStatement("SELECT ID,SELLPRICE FROM MEDICINES WHERE NAME=?");
pst.setString(1, (String) medicines_fine_name.get(i));
rs = pst.executeQuery();
if (rs.next()) {
medicines_id.add(rs.getString("id"));
medicines_price.add(rs.getDouble("sellprice"));
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
for ( int i = 0; i < medicines_fine_name.size() ; i++) {
tblmodel.addRow(new Object[] {medicines_id.get(i),medicines_fine_name.get(i),medicines_price.get(i),medicines_fine_qty.get(i)});
}
}
The whole thing sometimes run without error if the last for loop is removed . ( but that beats the purpose )
And Yeah , I said "sometimes" .. I am very much confused and as you can see, this code is written in a very ugly manner. I had written it the normal way, but this ArrayIndexOutOfBoundsException made me re-write the whole code 3 time, which ended in me writing pretty bad & ugly code but with the error still hanging on.
Pls let me know if anything is still unclear
Edit1: Basically what i'm trying to do is from the selected string in jlist , separate the datetime part and id part using split() function and store them to an array . Then use this id and name to select medicines from database . "medicines" is a string containing comma separated values like Aspirin=2,Amoxylin=5,etc=2,etc=10 where =10 means 10 of them ( indicating quantity . Then the drug name is stored into an arraylist and qty into another . Then use this medicine_name to get the medicine_id and sellprice. Finally set all this into a table .
The problem is here:
for ( int i = 0; i < medicines_fine_name.size() ; i++) {
tblmodel.addRow(new Object[] {medicines_id.get(i),medicines_fine_name.get(i),medicines_price.get(i),medicines_fine_qty.get(i)});
}
You are iterating over index in arraylist where there are no elements present.
What you are doing is you are firing two queries, in first query say you got 10 records.
Now in second query you iterate over your 10 records (processed and passed in arrayList from first query result) and fire in query 10 times. You may or may not get record and you do:
if (rs.next()) {
medicines_id.add(rs.getString("id"));
medicines_price.add(rs.getDouble("sellprice"));
}
if out of 10 you get record for 5 then size of medicines_id, medicines_price arraylist would be just 5.
Now comes your final loop as above. Here in the for loop you try to iterate over medicines_id,medicines_fine_name,medicines_price,medicines_fine_qty until size of 10 as per first query (medicines_fine_name.size()).
so when your i goes to index 6, you try to get on say
medicines_id.get(6)
but this element you never populated as per your second query hence ArrayIndexOutOfBoundException.
To fix this, one way would be to use else part to populate dummy value to id and price like below:
if (rs.next()) {
medicines_id.add(rs.getString("id"));
medicines_price.add(rs.getDouble("sellprice"));
} else {
medicines_id.add(rs.getString("9999"));
medicines_price.add(rs.getDouble("10.00"));
}

Populating a JTable from Access Database

I am trying to populate a JTable with data from a database. I've tried so many different ways and it just doesn't want to work. Currently I have a class which returns a resultset with the entire database to my UIClass which then uses the resultset to populate the JTable. Bellow is my method that retrieves the resultset and then populates the JTable.
private void SetJTable()
{
int count = 0;
String boatclass, senior, under23, junior;
try
{
ResultSet results = object.AllWorldBestTimes();
DefaultTableModel model = (DefaultTableModel) Times.getModel();
model.addColumn("Boat Class");
model.addColumn("Senior");
model.addColumn("Under 23");
model.addColumn("Junior");
while(count<24)
{
boatclass = results.getString(1);
senior = results.getString(2);
under23 = results.getString(3);
junior = results.getString(4);
System.out.println(boatclass + senior + under23 + junior);
model.insertRow(Times.getRowCount(), new Object[]{boatclass, senior, under23, junior});
count++;
}
Times = new JTable(model);
}
catch (SQLException e)
{
System.out.println("Ef");
}
}
Here is the method of retrieving data from the database:
public ResultSet AllWorldBestTimes() throws SQLException
{
DatabaseConnection connection = new DatabaseConnection();
ResultSet result = connection.SelectStatements("SELECT * FROM WorldBestTimes");
return result;
}
there is no crash so i cannot give the stack trace, nor does it go into the catch statement.
any help would be appreciated!
model.insertRow(Times.getRowCount(), ...
Times.getRowCount() is always going to return zero, since it's empty.
Times = new JTable(model);
Reassigns the reference Times, but it doesn't take the old table out of the form or add the new one into the form.
Try this...
model = new DefaultTableModel();
...and this...
model.insertRow(model.getRowCount(), ...
...and this...
Times.setModel(model);
Hard to say if that will do it or not. The code sample isn't exactly SCCE.

JTable correct row number after filtering

Here is a try block which serves the purpose of filtering through table_job to find rows which match keyword. However, when the table model changes, I am struggling to obtain the correct row index. It always picks the the first row, even though the filtered result shows a row which is not first.
I understand you can do something with fireTableDataChanged(), but I am not sure HOW and WHERE to do this, in the try and catch block OR in the setLabelText() method which displays the content of the table as . JLabel
try
{
sql = "SELECT Job.jobID as 'Job ID', Employer.name as'Company', Job.title as 'Role', Job.description as 'Description', Job.type as 'Type', Job.benefits as 'Benefits', Job.closing as 'Closing Date' FROM Job INNER JOIN Employer ON Job.employerID=Employer.employerID ORDER BY Employer.name";
pst = conn.prepareStatement(sql);
rs = pst.executeQuery();
TableModel model = DbUtils.resultSetToTableModel(rs);
table_job.setModel(model);
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
table_job.setRowSorter(sorter);
searchJob.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String text = keyword.getText();
if (text.length() == 0)
{
sorter.setRowFilter(null);
}
else
{
sorter.setRowFilter(RowFilter.regexFilter(text));
}
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
private void setLabelText()
{
try
{
String table_click0 = (table_job.getModel().getValueAt(
row, 0).toString());
String sqlSt = "SELECT Employer.name, * FROM Job INNER JOIN Employer ON Job.employerID = Employer.employerID WHERE jobID='"+table_click0+"' ";
//rest of code to Label text...
}
The String table_click0 = (table_job.getModel().getValueAt(row, 0).toString()); is picking up the wrong row, not the updated selected row. How can I take this into account?
You probably need to convert your "row" value to a model index value (if your row value is retrieved from a "view" point of view), using convertRowIndexToModel. So just replace
String table_click0 = (table_job.getModel().getValueAt(row, 0).toString());
with
String table_click0 = table_job.getModel().getValueAt(table_job.
convertRowIndexToModel(row), 0).toString());
Quick fix: how to get the actual row in a filtered list
int row=getjTable().getSelectedRow();
if (getjTable().getRowSorter()!=null) {
row = getjTable().getRowSorter().convertRowIndexToModel(row);
}

extra column automatically appended in jtable (how to remove it )

I am working on a java project
I am using jdk 1.6
I am want to add data from database in jtable
I have achieved this by using DefaulTableModel
and I got the column names by using ResultSetMetadata
but the problem is
**I am getting a extra column name A at the 0th index of jtable
I want to remove this column
it looks like this
A | deptno
I only need deptno
**
the code used for creating this model is
private void updateTable() throws Exception {
String sqlrow = "Select count(*) from emp";
rs= db.sta.executeQuery(sqlrow);
rs.next();
int rows=rs.getInt(1);
System.out.println(""+rows);
String sqldata = "SELECT deptno FROM emp";
rs =db.sta.executeQuery(sqldata);
rsMD = rs.getMetaData();
numberOfColumns = rsMD.getColumnCount();
ColumnNames = new String[numberOfColumns+1];
System.out.println(""+numberOfColumns);
for(int i=1;i<=numberOfColumns;i++)
{
String colName=rsMD.getColumnName(i);
ColumnNames[i] = colName;
System.out.println(""+ColumnNames[i]);
}
//Cj is a method which takes sqlQuery , rows, column
Object[][] rowData=CJ(sqldata,rows,numberOfColumns);
//jt is table name
jt.setModel(new DefaultTableModel(rowData,ColumnNames));
}
// code for cj()
public Object[][] CJ(String sql,int rows,int cols)
{
Object[][] obj=new Object[rows][cols+1];
ResultSet rs=null;
try{
rs= db.sta.executeQuery(sql);
int c=0;
while(rs.next())
{
for(int i=1;i<=cols;i++)
{
obj[c][i]=rs.getString(i);
}
c++;
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
return obj;
}
I am using this code on
button click
updateTable();
jsp = new JScrollPane(jt); // jt is Jtable
jp.add(jsp); //jp is jpanel
please help me out
Not following the naming convention makes it hard to read, but I would suggest to take a closer look at the following piece of code
numberOfColumns = rsMD.getColumnCount();
ColumnNames = new String[numberOfColumns+1];
System.out.println(""+numberOfColumns);
for(int i=1;i<=numberOfColumns;i++)
{
String colName=rsMD.getColumnName(i);
ColumnNames[i] = colName;
System.out.println(""+ColumnNames[i]);
}
Here you explicitly use more column names then numberOfColumns. Idem for your CJ method, where you start at index 1.
Just start all those for loops at index 0, make the arrays one shorter and everything should work

Categories

Resources