Mistakes with table clicked fetching from DB - java

can you help me. I got stock in my project..
when I retrieve Resultset, it doesn't appear in field when I click on the table..
the code is below..
private void table_lectureKeyPressed(java.awt.event.KeyEvent evt) {
if(evt.getKeyCode()==KeyEvent.VK_DOWN || evt.getKeyCode()==KeyEvent.VK_UP ){
try {
int row=table_lecture.getSelectedRow();
String Table_Clicked=table_lecture.getModel().getValueAt(row, 0).toString();
String sql="Select * from Lectures where Lecture_ID='"+Table_Clicked+"' ";
ps=con.prepareStatement(sql);
rs=ps.executeQuery();
if (rs.next()) {
try {
String add1=rs.getString("Lecture_ID").toString();
txt_LectureNO.setText(add1);
String add2=rs.getString("Lecture_Name");
txt_lecture.setText(add2);
String add3=rs.getString("Lecture_Date");
dtc_Date.setDateFormatString(add3);
String add4=rs.getString("Lecture_Time");
txt_Time.setText(add4);
String add5=rs.getString("Lecturer");
txt_Lecturer.setText(add5);
String add6=rs.getString("Lecture_Place");
txt_Place.setText(add6);
String add7=rs.getString("Audiance");
txt_Audiance.setText(add7);
String add8=rs.getString("Remark");
txp_Remarks.setText(add8);
} catch(Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
} catch(Exception e ){
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
}
Any help appreciated.

Note your SQL statement:
"Select * from Lectures where Lecture_ID='"+Table_Clicked+"' "
This statement will be parsed in something like this:
Select * from Lectures where Lecture_ID = '1'
Tipically an ID is a numerical data type, so I suspect the problem is in your SQL statement giving you an empty result set (or causing an SQLException). In addition your query is vulnerable to SQL injection attacks.
To avoid these issues you need to use PreparedStatement properly:
int row = table_lecture.getSelectedRow();
Object tableClicked = table_lecture.getValueAt(row, 0);
String sql = "SELECT * FROM Lectures WHERE Lecture_ID = ?";
ps = con.prepareStatement(sql);
ps.setObject(1, tableClicked);
rs = ps.executeQuery();
Some hints on your code:
int row = table_lecture.getSelectedRow();
String Table_Clicked = table_lecture.getModel().getValueAt(row, 0).toString();
Here row is the selected row number in the view not the model, so you should request the proper value. You have two options:
Request value to the table
int row = table_lecture.getSelectedRow();
String Table_Clicked = table_lecture.getValueAt(row, 0).toString();
Convert view index in its respective model index
int row = table_lecture.getSelectedRow();
int modelIndex = table_lecture.convertRowIndexToModel(row);
String Table_Clicked = table_lecture.getModel().getValueAt(modelIndex , 0).toString();
It's preferable use Keybinding over KeyListeners when you're working with Swing for the reasons discussed in this topic: Key bindings vs. key listeners in Java.
In this particular case I wouldn't use keybinding either but use ListSelectionListener instead:
table_lecture.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
// your code here
}
});
Database calls are time consuming tasks and may block the Event Dispatch Thread (a.k.a. EDT) causing the GUI become unresponsive. The EDT is a single and special thread where Swing components creation and update take place. To avoid block this thread consider use a SwingWorker to perform database calls in a background thread and update Swing components in the EDT. See more in Concurrency in Swing trail.
I'd suggest you take a look to the hints exposed in this answer. Summarized:
Wrap data in a domain class.
Use a SwingWorker to do the database calls in a background thread and
update Swing components in the EDT.
Finally but not less important, alway follow Java Code Conventions

Related

Problem populating a Jlist based on two Jcomboboxes connected to a PostgreSQL database

Good afternoon
I'm working on a project in witch I have to calculate the performance of a pump for certain parameters like rotation, number of stages, diameter and viscosity. At first I created a database using PostgreSQL with several commercial pumps. The database contains schemas as the companies that manufacture the pumps, in each schema there are tables representing the different series of pumps and the tables have several pumps organized as lines. The lines contains coefficients that represent the pumps and that are necessary to calculate the performance.
I tried to code the application in C++, but was too hard to connect with Postgre, so I ended working with Java and Netbeans (I think it's easier to newcomers). The application is running quite good so far, but I have found two problems that I cannot solve.
To select the pump to make the calculations I had to use two Jcomboboxes and a Jlist. The first Jcombobox is for selecting the manufacturer, the second to select the serie. Finally, the Jlist displays all the pumps in that serie so the user can select one.
I was able to populate the first Jcombobox with the schemas of the database (thanks to you guys, actually), the second with the tables of the schema selected in the first and the Jlist with the names of the pumps.
The first problem is that I cannot clear the second Jcombobox (the series one) after changing the selected manufacturer in the first Jcombobox, it will add more itens every time that I change the first Jcombobox, even if I re-select an item that was already selected. I tried using the command "removeAllItems()", but then it displays just one table and stop filling the Jcombobox.
The second problem is that, when I select a serie in the second Jcombobox, it doesn't immediately display the pumps in the Jlist, the Jlist starts displaing after I select another serie. So, I have to select one and then change to another so the pumps start appearing in the Jlist.
I'm sorry for the long text and the english errors, I hope its enough for you guys to understand. I know the code is not pretty, that's because I'm not so good at this yet and I'm in a bit of a hurry to deliver it.
Here is the code, without all the generated code that Netbeans does.
public final class LabPump extends javax.swing.JFrame {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
public LabPump() {
initComponents();
con = ConnectPump.connect();
FillSelectFabricante();
}
public void FillSelectFabricante(){
try {
rs = con.getMetaData().getSchemas();
while(rs.next()){
String schemas = rs.getString("TABLE_SCHEM");
if(schemas.equals("information_schema") || schemas.equals("pg_catalog")){
}
else{
selectFabricante.addItem(schemas);
}
}
}
catch(SQLException error){
JOptionPane.showMessageDialog (null,error);
}
}
public void FillSelectSerie(String fabricante){
//selectSerie.removeAllItems();
try {
String[] sql = {"TABLE"};
rs = con.getMetaData().getTables(null, fabricante, "%", sql);
while(rs.next()){
String tables = rs.getString(3);
selectSerie.addItem(tables);
}
}
catch(SQLException error){
JOptionPane.showMessageDialog (null,error);
}
}
public void FillListBomba(String fabricante, String serie){
DefaultListModel dlm = new DefaultListModel();
dlm.removeAllElements();
try{
String sql = "select * from " + fabricante + "." + serie;
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
while(rs.next()){
String bomba = rs.getString("bomba");
dlm.addElement(bomba);
}
listBomba.setModel(dlm);
}
catch(SQLException error){
JOptionPane.showMessageDialog (null,error);
}
}
private void selectSerieActionPerformed(java.awt.event.ActionEvent evt) {
selectSerie.addActionListener((ActionEvent e) -> {
String fabricante = selectFabricante.getSelectedItem().toString();
String serie = selectSerie.getSelectedItem().toString();
FillListBomba(fabricante, serie);
});
}
private void selectFabricanteActionPerformed(java.awt.event.ActionEvent evt) {
String fabricante = selectFabricante.getSelectedItem().toString();
FillSelectSerie(fabricante);
}
Thank you all.
I managed to solve the problem just now. When the selectSerie.removeAllItems() line was uncommented the program returned a NullPointerException error.
To solve the problem I used the DefaultComboBoxModel class and then used the RemoveAllElements() method. I'm not quite sure why the other method didn't work though.
Thanks for your time and help Peter.
public void FillSelectSerie(String fabricante) {
DefaultComboBoxModel box;
box = new DefaultComboBoxModel();
box.removeAllElements();
try {
String[] sql = {"TABLE"};
rs = con.getMetaData().getTables(null, fabricante, "%", sql);
box.addElement("-");
while (rs.next()) {
String tables = rs.getString(3);
box.addElement(tables);
}
selectSerie.setModel(box);
} catch (SQLException error) {
//JOptionPane.showMessageDialog (null,error);
}
}

Java JDBC - Navigate Through Records Within Database

I am having some trouble in returning the NEXT record within the database, my code currently only returns the last record entered. I have tried creating an instance of a List/ArrayList, tried adding statements to my createStatement(); and just tried everything. I've searched the web, however, I always seem to get the last value returned. I was hoping as to whether someone could help me out. I am using .Swing and this is all executed within an ActionListener.
Essentially I want this function to get the next record in the database. As opposed to returning the last record.
nextEmployee.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Connection connection = null;
Statement statement = null;
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:employeeDatabase.sqlite");
connection.setAutoCommit(false);
System.out.println("Read operation - database successfully opened");
statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
ResultSet resultset = statement.executeQuery( "SELECT * from employees" );
while (resultset.next()) {
ArrayList<Employee> selectAllEmployees = new ArrayList<Employee>();
String id = resultset.getString("id");
String name = resultset.getString("name");
String email = resultset.getString("email");
String gender = resultset.getString("gender");
String dob = resultset.getString("dob");
String Address = resultset.getString("address");
String Postcode = resultset.getString("Postcode");
String NIN = resultset.getString("NIN");
String JobTitle = resultset.getString("JobTitle");
String StartDate = resultset.getString("StartDate");
String Salary = resultset.getString("Salary");
idTextField.setText(id);
nameTextField.setText(name);
genderTextField.setText(gender);
dobTextField.setText(dob);
addressTextField.setText(Address);
postcodeTextField.setText(Postcode);
ninTextField.setText(NIN);
jobtitleTextField.setText(JobTitle);
startdateTextField.setText(StartDate);
salaryTextField.setText(Salary);
emailTextField.setText(email);
}
resultset.close();
statement.close();
connection.close();
} catch ( Exception e1 ) {
System.err.println( e1.getClass().getName() + ": " + e1.getMessage() );
System.exit(0);
}
}});
Thank you for your time and effort.
One of two things is happening. Either:
You have a bug in the code which populates the database, so you think you have rows A, B, and C in the database, but in fact you only have row C
Or:
Your code as listed populates your controls with the contents of row A, then it repeats to populate the exact same controls with contents of row B, and then the exact same controls once more with the contents of row C. So, naturally, the values you are left with are the values of the last row.
It helps to think precisely what it is that you are trying to do, precisely what is happening, precisely what you expected to happen instead, and most importantly, what makes you believe that the code should do that which you expect it to do rather than what it actually does.

Select item from JCombobox and delete the row in database

I am working on a project in which I have a SQLite database with a table called Table1 and values title/location without an ID as column etc...
My form has a combobox which I've managed to get it display my DB each entry in one row . Now I want with a button "Delete" to delete the row that I have selected in the combobox and I am kind of lost.
Here is my code for the combobox (I think it's fine):
private void FillCombo(){
try {
String newLine = System.getProperty("line.separator");
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:C:\\users\\Kajou\\momentsdb.sqlite");
statement = connection.createStatement();
resultSet = statement.executeQuery("SELECT * FROM Table1");
while (resultSet.next()) {
comboBox1.addItem(resultSet.getString("Title") + " " + "Date:" + resultSet.getString("Day")+"/"+ resultSet.getString("Month") +"/" + resultSet.getString("Year") + " " + resultSet.getString("Location")+ " " + resultSet.getString("Mood"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
resultSet.close();
statement.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
And now about the button delete. I've tried few things but looks like not going well:
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
try {
Class.forName("org.sqlite.JDBC");
connection = DriverManager.getConnection("jdbc:sqlite:C:\\users\\Kajou\\momentsdb.sqlite");
statement = connection.createStatement();
String sql = "DELETE FROM Table1 WHERE col_string=Title";
int deleteCount = statement.executeUpdate(sql);
sql = "DELETE FROM Table1 WHERE col_string=?";
pst = connection.prepareStatement(sql);
pst.setString(1,"a string");
deleteCount=pst.executeUpdate();
} catch (ClassNotFoundException ex) {
Logger.getLogger(DeleteImportantMomentsForm.class.getName()).log(Level.SEVERE, null, ex);
} catch (SQLException ex) {
Logger.getLogger(DeleteImportantMomentsForm.class.getName()).log(Level.SEVERE, null, ex);
}
}
You need something like:
Object item = comboBox.getSeletedItem();
pst.setString(1, item.toString());
First off, sorry for the extension but I have several advices for you :)
1) My form has a combobox which i managed to get it display my DB each
entry in one row
Here is the way you're adding an entry to the combo box:
comboBox1.addItem(resultSet.getString("Title") + " " + "Date:" +
resultSet.getString("Day")+"/"+
resultSet.getString("Month") +"/" +
resultSet.getString("Year") + " " +
resultSet.getString("Location")+ " " +
resultSet.getString("Mood"));
This way you'll get a very large string added to your combo box, which is not bad but can be highly improved if you map this info into a domain class. For instance:
class MyClass {
int day, month, year;
String title, location, mood;
public MyClass(int day, int month, int year,
String title, String location, String mood) {
this.day = day;
this.month = month;
this.year = year,
this.title = title;
this.location = location;
this.mood = mood;
}
// getters and setters are up to you :)
}
Next step is adding new MyClass objects to your combo box:
while (resultSet.next()) {
MyClass myClass = new MyClass(resultSet.getInt("Day"),
resultSet.getInt("Month"),
resultSet.getInt("Year"),
resultSet.getString("Title"),
resultSet.getString("Location"),
resultSet.getString("Mood"));
comboBox1.addItem(myClass); // see note below
}
Note: Swing components (such as JComboBox) must be created and updated in the Event Dispatching Thread (a.k.a. EDT) which is a single and special thread. If you have a heavy task running in the EDT (for instance database connections) then this task may block the EDT and your GUI will freeze and Swing components won't be able to work (or even display) untill this task is done. To avoid this issue there are some tools you can use to make the heavy tasks in a separate thread and update Swing components in the EDT, for instance SwingWorker. For further information take a look to Concurrency in Swing.
So I would suggest you make database calls using a SwingWorker:
SwingWorker<Void,MyClass> worker = new SwingWorker<Void,MyClass>() {
#Override
protected Void doInBackground() throws Exception { // this take place in a background thread
// connect to the database and execute the query here
while (resultSet.next()) {
MyClass myClass = new MyClass(resultSet.getInt("Day"), ...);
publish(myClass);
}
return null;
}
#Override
protected void process(List<MyClass> chunks){ // this take place in the EDT
for(MyClass myClass : chunks){
comboBox1.addItem(myClass);
}
}
}
Well now you have the items properly added to your combo box. Next step is make the combo box display the text as you wish. To do so you'll need to implement a ListCellRenderer. Take a look to Providing a Custom Renderer section in How to Use Combo Boxes tutorial. Take a look to this example. It's about setting a custom renderer to a JList but exactly the same applies to JComboBox.
2) Now i want with a button "delete" to delete the row that i have
selected in the combobox and i am kind of lost
Please note you're trying to execute two different delete queries:
String sql = "DELETE FROM Table1 WHERE col_string=Title"; // This doesn't make sense
int deleteCount = statement.executeUpdate(sql);
sql = "DELETE FROM Table1 WHERE col_string=?"; // This looks better I guess
pst = connection.prepareStatement(sql);
I suspect one of these queries (if not both of them) throws an Exception.
As your combo box will contain MyClass objects, you can make this change at the action performed method:
MyClass myClass = (MyClass)comboBox1.getSelectedItem();
String sql = "DELETE FROM Table1 WHERE Title = ?"; //If Title is the name of the column, of course
PreparedStatement pst = connection.prepareStatement(sql);
pst.setString(1,myClass.getTitle());
Note: Once again, the action performed method is executed in the EDT. You should move the database call to a background thread to avoid blocking the EDT.

Fitting a whole row of a MySQL table onto a single JLabel in Java

I have Java code the successfully connects Java to MySQL.
I have two classes. One that creates the GUI with Java and another class that specifically gets information from MySQL.
I'm trying to find a good way to put a whole row of information as a String into each JLabel on MyGUI.
Here is my code in each class (excluding connecting to the database):
CLASS 1
String result = "";
contactsList()
{
//extra classes
db=new database();
result = db.getContact();
label1 =new JLabel(result);
CLASS 2
PreparedStatement pst, pst2;
ResultSet rs, rs2;
pst2 = con.prepareStatement("select LastName, FirstName from contacts");
public String getContact()
{
String result2 = "";
try {
rs2=pst2.executeQuery();
while (rs2.next())
{
result2 = rs2.getString(1);
}
return result2;
}
catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("error while validating"+e);
return "";
}
}
Right now the rows in my Contacts table in MySQL has columns separated by commas
1, Rivera, Angelo, 2890 something st. ventura 93003, Null
2, Person, Random, 1223 I dunno ave. Camairllo 93001, 423-123-5313
Right now when I try to put a whole row in the "label1" the only text it shows is "Person".
How do I make it so it shows the whole Row in the JLabel?
Also how would I format the code so I can call the the function to get the next row of information and put it into another label?
Thanks.
You are only asking it to retrieve one column from your result set by the looks of things :
result2 = rs2.getString(1);
If you want to display more data, you just need to retrieve it and format it somehow :
result2 = rs2.getString(1) + " : " + rs2.getString(2);
for example.
But there are other problems with the select statement I think.
select LastName, FirstName from contacts
will retrieve the LastName and FirstName from every row in the database. The way your loop construct works means that result2 will contain the data for the last row in the table only. Is that what you are trying to achieve?
I would suggest using a JTable for this. Read the section from the Swing tutorial on How to use JTable for more information.
Then you might want to check out Table From Database. The Table From Database Example code may be the easiest way to start.

JComboBox selects the first item by iteself

I have made a combobox which is being filled up with the database entries. The problem that i'm currently facing is that when I write "H" the list gets filled with all the names starting with "H" as required but the first name in the list automatically gets selected. How to avoid this problem?
String ch = text.getText();
if (ch.equals("")) {
combo.setVisible(false);
} else {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connect = DriverManager.getConnection("jdbc:mysql://localhost:3306/userlogin", "root","12345");
Statement st = connect.createStatement();
ResultSet rs = st.executeQuery("SELECT author_name FROM scrpd_authors WHERE author_name LIKE '"+ ch + "%'");
while (rs.next()) {
String name = rs.getString("author_name");
if (name.equals("")) {
searchitems.addItem("");
} else {
searchitems.addItem(rs.getString("author_name"));
searchitems.setVisible(true);
}
}
connect.close();
} catch (Exception ex) {
}
}
Please note the combobox is being filled with all my desired entries based on the mysql query, the problem is just with the selection of the first entry by itself.
the first name in the list automatically gets selected. How to avoid this problem?
Then use:
comboBox.setSelectedIndex(-1);
after the data has been loaded.
Or maybe you could use a Combo Box Prompt.
that's a quirk of the not-editable JComboBox when adding to an empty box:
using addItem(item) will select that item
using insertItemAt(item, 0) will not select that item
That quirk is independent on whether the filling happens on the model or on the view-
So if deselecting after filling the model (as suggested by Rob) is not an option, you can use the insert method (either on the view or on the model):
// model
model.addElementAt(item, model.getSizes();
// alternatively view
combo.insertItemAt(item, combo.getItemCount());
Generally, it's recommended to do model manipulations on the model (vs. on the cover methods on the view) - this way you can implement and test your model handling independent of the view.

Categories

Resources