NullPointerException in Java TableRowSorter - java

I made a jtable for the list of chemicals in the inventory where I can sort each columns using the following code (chemicalTable is the name of the jTable):
chemicalTable.setAutoCreateRowSorter(true);
TableRowSorter<TableModel> sorter1
= new TableRowSorter<TableModel>(chemicalTable.getModel());
chemicalTable.setRowSorter(sorter1);
Then I used a jTextfield to create a searchbox with a keyTyped Listener so that whenever the user types a certain character the table refreshes. And it usually works.
I used this code in the keyTypedListener for the searchbox:
DefaultTableModel dm = (DefaultTableModel) chemicalTable.getModel();
str = searchChemicalText.getText();
try {
String url = "jdbc:mysql://localhost/chemical inventory";
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, "root", "");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Error Occurred.", "Error", JOptionPane.ERROR_MESSAGE);
}
int ctr = 0;
while (ctr < chemicalTable.getRowCount()) {
chemicalTable.getModel().setValueAt(null, ctr, 0);
chemicalTable.getModel().setValueAt(null, ctr, 1);
chemicalTable.getModel().setValueAt(null, ctr, 2);
ctr++;
}
int count = 0;
try {
Statement stmt = conn.createStatement();
String query = "Select * FROM chemicallist where name_of_reagent like '%" + str + "%'";
ResultSet rs = stmt.executeQuery(query);
if (rs.next()) {
rs = stmt.executeQuery(query);
while (rs.next()) {
String qty = null, qtyunit = null, chemstate = null, reagentName = null;
reagentName = rs.getString("name_of_reagent");
qty = rs.getString("quantity");
qtyunit = rs.getString("quantity_unit");
chemstate = rs.getString("state");
chemicalTable.getModel().setValueAt(reagentName, count, 0);
chemicalTable.getModel().setValueAt(qty + " " + qtyunit, count, 1);
chemicalTable.getModel().setValueAt(chemstate, count, 2);
if (count + 1 > chemicalTable.getRowCount() - 1) {
dm.setRowCount(chemicalTable.getRowCount() + 1);
dm.fireTableRowsInserted(0, 5);
}
count++;
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Error Occurred.", "Error", JOptionPane.ERROR_MESSAGE);
}
My problem is: Whenever I sort first any columns (col1, col2, or col3) and I insert a character in the searchbox, I got this error message:
"Exception occurred during event dispatching:
Java.lang.NullPointerException"

Although it's not possible to debug your code fragments, several things stand out:
In the same section, you reference the TableModel as dm and chemicalTable.getModel(); use a single reference or verify that they refer to the same instance.
Instead of meddling with setRowCount(), use one of the addRow() methods.
The DefaultTableModel methods that alter the model fire the correct event for you and the table will automatically update itself accordingly; you shouldn't have to do this yourself.

Related

Unable to query database correctly using JDBC

I am trying to update a database using input from user and saving it in jtable, then using jtable I am updating the database, but I am not able to get fetch and update 2nd row in database.
please suggest a solution, Thanks in advance.
try {
Class.forName("com.mysql.jdbc.Driver");
con = myconnection.getConnection();
String name;
for (int i = 0; i < jTable2.getRowCount(); i++) {
name = (String) jTable2.getModel().getValueAt(i, 0);
String abcd = "select * from medicine where Name=? ";
stmt = conn.prepareStatement(abcd);
stmt.setString(1, name);
rs = stmt.executeQuery();
if (rs.next()) {
name = (String) jTable2.getModel().getValueAt(i, 0);
String stock = rs.getString("qty");
int nowstock = Integer.parseInt(stock);
int qty1 = Integer.parseInt(jTable2.getValueAt(i, 2).toString());
int newstock = nowstock - qty1;//Integer.parseInt(jTable2.getValueAt(i, 2).toString());
String sqlupdate = "UPDATE medicine SET qty='" + newstock + "'WHERE Name='" + name + "' "; //
stmt = conn.prepareStatement(sqlupdate);
stmt.executeUpdate();
}
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(Bill.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(Bill.class.getName()).log(Level.SEVERE, null, ex);
}
The select serves no purpose, and you can just iterate all names and update directly:
for (int i=0; i < jTable2.getRowCount(); i++) {
String name = (String) jTable2.getModel().getValueAt(i, 0);
int qty1 = Integer.parseInt(jTable2.getValueAt(i, 2).toString());
String update = "UPDATE medicine SET qty = qty - ? WHERE Name = ?";
PreparedStatement ps = conn.prepareStatement(update);
ps.setInt(1, qty1);
ps.setString(2, name);
ps.executeUpdate();
}
If your JTable happens to have more than say 10 or so names, then a more efficient way to do this would be to use a single update with a WHERE IN clause containing all names which appear in the table, i.e.
UPDATE medicine SET qty = qty - ? WHERE Name IN (...);

How to make one mySQL's table column invisible

I am running a query on ID column but I don't want it to be visible in my frame/pane. How can I achieve this? Shall I make another table, is there a function in sql/mysql which allows to hide columns? I tried to google it but havent found anything yet.
Here is the code:
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int col = e.getColumn();
model = (MyTableModel) e.getSource();
String stulpPav = model.getColumnName(col);
Object data = model.getValueAt(row, col);
Object studId = model.getValueAt(row, 0);
System.out.println("tableChanded works");
try {
new ImportData(stulpPav, data, studId);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
public class ImportData {
Connection connection = TableWithBottomLine.getConnection();
public ImportData(String a, Object b, Object c)
throws ClassNotFoundException, SQLException {
Statement stmt = null;
try {
String stulpPav = a;
String duom = b.toString();
String studId = c.toString();
System.out.println(duom);
connection.setAutoCommit(false);
stmt = connection.createStatement();
stmt.addBatch("update finance.fin set " + stulpPav + " = " + duom
+ " where ID = " + studId + ";");
stmt.executeBatch();
connection.commit();
} catch (BatchUpdateException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (stmt != null)
stmt.close();
connection.setAutoCommit(true);
System.out.println("Data was imported to database");
}
}
}
public class MyTableModel extends AbstractTableModel{
int rowCount;
Object data [][];
String columnNames [];
public MyTableModel() throws SQLException{
String query ="SELECT ID, tbl_Date as Date, Flat, Mobile, Food, Alcohol, Transport, Outdoor, Pauls_stuff, Income, Stuff FROM finance.fin";
ResultSet rs ;
Connection connection = TableWithBottomLine.getConnection();
Statement stmt = null;
stmt = connection.createStatement();
rs = stmt.executeQuery(query);
rs.last();
rowCount = rs.getRow();
data = new Object[rowCount][11];
rs = stmt.executeQuery(query);
for (int iEil = 0; iEil < rowCount; iEil++){
rs.next();
data[iEil][0] = rs.getInt("ID");
data[iEil][1] = rs.getDate("Date");
data[iEil][2] = rs.getFloat("Flat");
data[iEil][3] = rs.getFloat("Mobile");
data[iEil][4] = rs.getFloat("Food");
data[iEil][5] = rs.getFloat("Alcohol");
data[iEil][6] = rs.getFloat("Transport");
data[iEil][7] = rs.getFloat("Outdoor");
data[iEil][8] = rs.getFloat("Pauls_stuff");
data[iEil][9] = rs.getFloat("Income");
data[iEil][10] = rs.getFloat("Stuff");
}
String[] columnName = {"ID", "Date","Flat","Mobile"
,"Food","Alcohol","Transport", "Outdoor", "Pauls_stuff", "Income", "Stuff"};
columnNames = columnName;
}
This has solved my problem:
table.removeColumn(table.getColumnModel().getColumn(0));
I placed this in my class contructor. This lets remove the column from the view of the table but column 'ID' is still contained in the TableModel. I found that many people looking for an option to exclude specific column (like autoincrement) from SELECT statement in sql / mysql but the language itself doesn't have that feature. So I hope this solution will help others as well.
Don't put ID in the select part of the query
String query ="SELECT tbl_Date as Date, Flat, Mobile, Food, Alcohol, Transport,
Outdoor, Pauls_stuff, Income, Stuff FROM finance.fin";

populate SWT table with database content

I am using PhpMyAdmin to save my data in database. I have a SWT table to populate with database content.
here is my code..
public static void fetchDatafromDB(String StartIndex, String FinalIndex) {
try {
Class.forName(GlobalVariables.SQL_driver).newInstance();
Connection conn = DriverManager.getConnection(GlobalVariables.DB_url + GlobalVariables.DB_name, GlobalVariables.DB_Username, GlobalVariables.DB_password);
Statement st = conn.createStatement();
String query = "SELECT `From`, `To`, `IDno`, `TimeStamp` FROM `callsheet` WHERE TimeStamp BETWEEN '" + StartIndex + "' AND '" + FinalIndex + "'";
ResultSet rs = st.executeQuery(query);
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
while (rs.next()) {
for (int i = 1; i <= columnsNumber; i++) {
// System.out.print(rs.getString(i));
item.setText(i, rs.getString(i));
}
// System.out.println();
}
} catch (Exception P) {
P.printStackTrace();
}
}
it worked.
Now I am getting some problem with tabling the DB content in my swt table. What my program does, is that, it sets the selected (defined by limit in program above) content of DB in one row (one by one manner) but I want the next row of DB table to be tabled in next row of SWT table. Could you suggest something about this? ! Screenshot of my swtTable
It should look something like this:
public static void fetchDatafromDB(String startIndex, String finalIndex) {
try {
Class.forName(GlobalVariables.SQL_driver).newInstance();
Connection conn = DriverManager.getConnection(GlobalVariables.DB_url + GlobalVariables.DB_name, GlobalVariables.DB_Username, GlobalVariables.DB_password);
Statement st = conn.createStatement();
String query = "SELECT `FROM`, `To`, `IDno`, `TimeStamp` FROM `callsheet` WHERE TimeStamp BETWEEN '" + startIndex + "' AND '" + finalIndex + "'";
ResultSet rs = st.executeQuery(query);
java.sql.ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
TableItem item;
while (rs.next()) {
// Create a new TableItem for each entry in the result set (each row)
item = new TableItem(table, SWT.NONE);
for (int i = 1; i <= columnsNumber; i++) {
// Populate the item (mind the index!!)
item.setText(i - 1, rs.getString(i));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

how to fetch multiple rows from mysql to java table in swings

i have a swing application which consists of a text box and a button.On entering the emp_id and clicking the button it connects to mysql and fetch all the rows corresponding to the emp_id entered in a table. my code is fetching only 1 row of the mysql data, even though there is 3 rows corresponding to the emp_id
my code is:
try {
Class.forName(driverName);
Connection con = DriverManager.getConnection(url, userName,password);
String sql = "select * from devices where emp_id = " + textvalue;
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
int i = 0;
if (rs.next()) {
asset_id = rs.getString("asset_id");
name = rs.getString("name");
project = rs.getString("project");
emp_id = rs.getString("emp_id");
emp_name = rs.getString("emp_name");
model.addRow(new Object[] { asset_id, name, project, emp_id,emp_name });
// i++;
}
if (i < 1) {
JOptionPane.showMessageDialog(null, "No Record Found", "Error",JOptionPane.ERROR_MESSAGE);
}
if (i == 1) {
System.out.println(i + " Record Found");
} else {
System.out.println(i + " Records Found");
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
}
frame1.add(scroll);
frame1.setVisible(true);
frame1.setSize(400, 300);
you are fetching only first row.. fetch it in a loop
while(rs.next())
{
asset_id = rs.getString("asset_id");
name = rs.getString("name");
project = rs.getString("project");
emp_id = rs.getString("emp_id");
emp_name=rs.getString("emp_name");
model.addRow(new Object[]{asset_id, name, project, emp_id,emp_name});
//i++;
}
You get only one row from ResultSet :
if (rs.next()) {
asset_id = rs.getString("asset_id");
name = rs.getString("name");
project = rs.getString("project");
emp_id = rs.getString("emp_id");
emp_name = rs.getString("emp_name");
model.addRow(new Object[] { asset_id, name, project, emp_id,
emp_name });
// i++;
}
replace if with while, for getting all rows in loop.
For centring frame use frame.setLocationRelativeTo(null);.
According to docs
If the component is null, or the GraphicsConfiguration associated with this component is null, the window is placed in the center of the screen. The center point can be obtained with the GraphicsEnvironment.getCenterPoint method.
Also:
1) replace next code:
if (i == 1) {
System.out.println(i + " Record Found");
} else {
System.out.println(i + " Records Found");
}
with System.out.println(i + " Record Found"); because its code duplication.
2)Don't use setSize(...) use pack() method.
3)Call frame1.setVisible(true); in last line of construction or like next:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
frame.setVisible(true);
}
});

How can I pass string to a JOptionPane?

I have tried to write a code that searches a database of students and shows the searched result on a option pane. And I ended up writing the following. The expected result is:
Name: "something"
Roll: "something"
Registration: "Something"
But actually the output is something like this:
Name: null
Roll: null
Registration: null
public class Search
{
JFrame sw = new JFrame("Search Students' Info"); //search window
JTable stable;
JLabel stfl = new JLabel("Roll"); //search text field label
JTextField stf = new JTextField(8); //search text field
JButton sb = new JButton("Search"); //search button
public void exsearch() //Execute Search
{
sw.setLayout(new GridLayout(2,2));
sw.add(stfl);
sw.add(stf);
sw.add(sb);
sw.setSize(200, 100);
sw.setLocation(100, 100);
sw.setVisible(true);
sb.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost/srsdb";
try
{
Class.forName(driver).newInstance();
java.sql.Connection con = DriverManager.getConnection(url, "root", "");
JOptionPane.showMessageDialog(null, "Connected", "Connection Confirmation", JOptionPane.PLAIN_MESSAGE);
String str ="SELECT* FROM students WHERE Roll="+stf.getText();
java.sql.Statement st = con.createStatement();
java.sql.ResultSet rs = st.executeQuery(str);
rs.first();
int n = rs.getMetaData().getColumnCount();
// String[] columnnNames;
String[] attributes= new String[10];
int j;
while(rs.next())
{
for(j=0; j<3; j++)
{
attributes[j] = rs.getString(j);
}
}
JOptionPane.showMessageDialog(null, "Name :"+attributes[0]+"\nRoll :"+attributes[1]+"\nRegistration :"+attributes[2], "Search Result", JOptionPane.PLAIN_MESSAGE);
}
catch(Exception f)
{
f.printStackTrace();
JOptionPane.showMessageDialog(null, "Not Found", "Search Result", JOptionPane.PLAIN_MESSAGE);
}
}});
}
public static void main (String[] args)
{
new Search();
}
}
I would use a debugger to check which part of your code is omitted.
One wierd thing I see is, that you jump to the first record in your result set:
rs.first();
And then you read the data from all subsequent records in a while loop
while(rs.next())
{
for(j=0; j<3; j++)
{
attributes[j] = rs.getString(j);
}
}
This ensures, that you get the data from the last matching record if there is more than one.
Better would be to check if there is zero or more than one record. If that is the case, issue a warning because probably there is something wrong with your code (use a debugger to find out what).
If there is only one record, read the data from that record and print it (more or less like you try with rs.getString())
Class.forName ensures that the driver class is on the class path, without needing to compile against the class. It loads the class. No instantiation needed.
A PreparedStatement is better against SQL injection.
Column numbers in the SQL API are 1-based: 1, 2, 3, ... A bit of an exception.
When using first the query loop is as follows. You skipped the first row I think.
Do not forget the miscellaneous close().
Better style to list the columns instead of `*'.
Hence:
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost/srsdb";
try
{
Class.forName(driver);
Connection con = DriverManager.getConnection(url, "root", "");
JOptionPane.showMessageDialog(null, "Connected",
"Connection Confirmation", JOptionPane.PLAIN_MESSAGE);
String str ="SELECT Name, Registration FROM students WHERE Roll=?";
PreparedStatement st = con.createPreparedStatement(str);
String roll = stf.getText();
st.setString(1, roll);
String message = "";
java.sql.ResultSet rs = st.executeQuery();
int recno = 0;
if (rs.first()) {
do {
String name = rs.getString(1);
String registration = rs.getString(2);
++recno;
message += "- " + recno + " -\nName: " + name
+ "\nRoll: " + roll
+ "\nRegistration: " + registration + "\n";
} while (rs.next());
}
rs.close();
JOptionPane.showMessageDialog(null, message, "Search Result",
JOptionPane.PLAIN_MESSAGE);

Categories

Resources