Select item from JCombobox and delete the row in database - java

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.

Related

JComboBox error blocking another field display

I have a problem with JComboBox. It's blocking another field in a frame meant to display another value that is linked through a foreign key in a database, a value that depends on the combo box already pop out. But somehow, after the user clicks the combo box it is blocking another field. The app is using MySql.
Here's the code:
ComboBox method to fill value from DB
public void comboBoxBerat(){
DbConnection DB = new DbConnection();
DB.DbConnection();
con = DB.con;
stat = DB.stmt;
try {
sql = "SELECT * FROM weight_of_services";
rs = stat.executeQuery(sql);
while (rs.next()) {
jComboBoxBerat.addItem(rs.getString("weight"));
}
con.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(this, e.getMessage());
}
}
Action when selection is made from combo box, its get the value that linked with foreign key
private void jComboBoxBeratActionPerformed(java.awt.event.ActionEvent evt) {
DbConnection DB = new DbConnection();
DB.DbConnection();
con = DB.con;
stat = DB.stmt;
String item = (String)jComboBoxBerat.getSelectedItem();
String sql = "SELECT price FROM weight_of_services WHERE weight = ?";
try {
pst = con.prepareStatement(sql);
pst.setString(1, item);
rs = pst.executeQuery();
if (rs.next()) {
String price = rs.getString("price");
txtHargaBerat.setText(price); //put value from combobox to txtField
}
con.close();
} catch (Exception e) {
}
}
The problem after I select from the box its blocking another field.
This is the combo box problem in the frame
It's solved. This because i am using jpanel for customizing color for the frame. Its just so messed up with the stacking one panel on top of the other one. That's why my dropdown list get blocked. So what I did, removed all the panel. Custom and sorting it more carefully and tidy from the start.

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);
}
}

JTree database node select and display in textfield in java

I have a JTree populated with a list of tasks from a database, I am trying to create a mouse clicked listener so that when a node is clicked, the id and task are displayed into JTextfields,
below is my code
private void jTree1MouseClicked(java.awt.event.MouseEvent evt) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) jTree1.getLastSelectedPathComponent();
Object nodeInfo = node.getUserObject();
try {
String query = "select * from Task where task=" + nodeInfo + "";
pst = con.prepareStatement(query);
rs = pst.executeQuery();
if (rs.next()) {
int id = rs.getInt("id");
String task = rs.getString("task");
parentIdTxt.setText("" + id);
childTxt.setText("" + task);
}
} catch (Exception e) {
}
}
My problem is that even tho my program runs without any issues, whenever I click the node nothing happens? any help in pointing out what I missed will be appreciated
In fact you get an error but you don't see it, because you don't print it, you can check the error using :
} catch (Exception e) {
e.printStackTrace();
}
String should be between 'nodeinfo' so instead you have to use :
String query="select * from Task where task= '" + nodeInfo + "'";
But you don't implement PreparedStatement correctly you can use this :
String query="select * from Task where task = ?";
insert.setString(1, nodeinfo);
rs = pst.executeQuery();
...
You have to repaint the textfields or update their layout so they have enough space to show the contents. Try adding the following code after setting the contents of your textfields:
parentIdTxt.validate();
parentIdTxt.repaint();
childTxt.validate();
childTxt.repaint();
Firstly you need to check if you get the task and the id correctly using Debug mode or just by printing them into the console.
I recomended you to test just this code in the `JTree1MouseClicked.
private void jTree1MouseClicked(java.awt.event.MouseEvent evt) {
childTxt.setText(jTree1.getLastSelectedPathComponent().toString());
}
that should display the selected node, that should work, then you need to check your request, I think that the problem is there

Mistakes with table clicked fetching from DB

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

How to populate JList with data from another JList

I have a MySQL database which contains data i would like to populate into a JList in my java program. I have two JList, one which is fill with Events Title and the second is to be fill with Guest Name.
What i would like is when the user click on any of the Events Title, the second JList will show all the Guest Name that belong to that Event.
I have already successfully populate the first JList with all the Events Title. What I'm having trouble with is when the user click on the Events Title, the Guests Name will show twice on the second JList. How can i make it to show only once?
Here is what i got so far...
Java Class
private JList getJListEvents() {
if (jListEvents == null) {
jListEvents = new JList();
Border border = BorderFactory.createTitledBorder(BorderFactory.createBevelBorder(1, Color.black, Color.black), "Events", TitledBorder.LEFT, TitledBorder.TOP);
jListEvents.setBorder(border);
jListEvents.setModel(new DefaultListModel());
jListEvents.setBounds(new Rectangle(15, 60, 361, 421));
Events lEvents = new Events();
lEvents.loadEvents(jListEvents);
jListEvents.addListSelectionListener(new ListSelectionListener(){
public void valueChanged(ListSelectionEvent e){
EventC eventC = new EventC();
//eventC.MonitorRegDetailsInfo(jListEvents, jTextFieldEventName, jTextFieldEventVenue, jTextFieldEventDate, jTextFieldEventTime, jTextAreaEventDesc);
//eventC.MonitorRegPackageInfo(jListEvents, jTextFieldBallroom, jTextFieldBallroomPrice, jTextFieldMeal, jTextFieldMealPrice, jTextFieldEntertainment, jTextFieldEntertainmentPrice);
eventC.MonitorRegGuest(jListEvents, jListGuest);
}
});
}
return jListEvents;
}
Controller Class
public void MonitorRegGuest(JList l, JList l2){
String event = l.getSelectedValue().toString();
Events retrieveGuest = new Events(event);
retrieveGuest.loadGuests(l2);
}
Class with all the sql statement
public void loadGuests(JList l){
ResultSet rs = null;
ResultSet rs2 = null;
ResultSet rs3 = null;
MySQLController db = new MySQLController();
db.getConnection();
String sqlQuery = "SELECT MemberID FROM event WHERE EventName = '" + EventName + "'";
try {
rs = db.readRequest(sqlQuery);
while(rs.next()){
MemberID = rs.getString("MemberID");
}
} catch (SQLException e) {
e.printStackTrace();
}
String sqlQuery2 = "SELECT GuestListID FROM guestlist WHERE MemberID = '" + MemberID + "'";
try {
rs2 = db.readRequest(sqlQuery2);
while(rs2.next()){
GuestListID = rs2.getString("GuestListID");
}
} catch (SQLException e) {
e.printStackTrace();
}
String sqlQuery3 = "SELECT Name FROM guestcontact WHERE GuestListID = '" + GuestListID + "'";
try {
rs3 = db.readRequest(sqlQuery3);
while(rs3.next()){
((DefaultListModel)l.getModel()).addElement(rs3.getString("Name"));
}
} catch (SQLException e) {
e.printStackTrace();
}
db.terminate();
}
Thanks in advance!
Please for the time being forget about the SQL. Then follow the steps below:
Start with the example --- the corresponding Java Web Start link.
Play with the sample, to see how to add elements to a list.
Then all you need to do is grab a reference to the one you want to copy and for each element copy it then add to the 2nd list.
Enjoy Java.
EDIT:
I am still looking at your code and I am still confused of what is going on (Please consider making a SSCCE). But let me guess, as something is telling me that when you are calling the ListSelectionListener you are not using getIsValueAdjusting() of the ListSelectionEvent, right? Therefore, this might be as well it, for more read here.
As far as I can see, you aren't clearing the list before populate it, you could try to clear the model first, like:
String sqlQuery3 = "SELECT Name FROM guestcontact WHERE GuestListID = '" + GuestListID + "'";
try {
rs3 = db.readRequest(sqlQuery3);
DefaultListModel lm = (DefaultListModel)l;
lm.clear();
while(rs3.next()){
(lm.getModel()).addElement(rs3.getString("Name"));
}
} catch (SQLException e) {
e.printStackTrace();
}

Categories

Resources