I have tried something like that : but the error appears:
SEVERE: null
null
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'MYUSER' cannot be null
while it shouldn't? Also I would like to ask if there are some bad practices in my program.
any tips?
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
public class Main extends JFrame {
String text;
public Main() throws HeadlessException {
//opis
JLabel opis = new JLabel("Opis: ");
JTextField opisTextField = new JTextField();
opisTextField.setPreferredSize(new Dimension(100, 20));
add(opis);
add(opisTextField);
//jak klikniemy w przycisk program doda wartosci wpisane do bazy danych.
Button z = new Button("Dodaj do bazy danych");
add(z);
z.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e){}
#Override
public void mouseEntered(MouseEvent e){}
#Override
public void mouseExited(MouseEvent e){}
#Override
public void mouseReleased(MouseEvent e){}
#Override
public void mousePressed(MouseEvent e) {
Main m = new Main();
m.text = opisTextField.getText();
});
}
public void readDataBase() throws Exception {
try {
// this will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// setup the connection with the DB.
connect = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
+ "user=sqluser&password=sqluserpw");
// statements allow to issue SQL queries to the database
statement = connect.createStatement();
// resultSet gets the result of the SQL query
// preparedStatements can use variables and are more efficient
preparedStatement = connect
.prepareStatement("insert into FEEDBACK.COMMENTS values (default, ?, ?, ?, ? , ?, ?)");
// "myuser, webpage, datum, summary, COMMENTS from FEEDBACK.COMMENTS");
// parameters start with 1
preparedStatement.setString(1, text);
preparedStatement.executeUpdate();
// remove again the insert comment
} catch (ClassNotFoundException | SQLException e) {
throw e;
} finally {
// close();
}
}
public static void main(String[] args) throws Exception {
new Main().setVisible(true);
}
}
Sorry could not go through all the code but it looks like you declared String text; and you never provided it a value and you are passing this value to username preparedStatement.setString(1, text); which cannot be null as per error.
Related
I have been struggling with this problem for a while where I have two classes namely OrderSearch.java(main class) and CreateOrder.java. I have a JTable on my main class and when a row is doubleclicked it opens a new frame i.e CreateOrder.java with values from jTablein different textfields. I have a SaveButton in CreateOrder.java that saves the changes made in the class and shows it JTable again.
However the problem is I cannot perform refresh table operation i.e some sql queries when the SaveButton is clicked. I want the table in frame OrderSearch is refreshed when the savebutton on CreateOrder is clicked
Problems: Creating an object for class OrderSearch.java in CreateOrder.java gives me a stackoverflow error. Creating an object in the Savebutton opens a whole new frame again.
OrderSearch.java
public class OrderSearch extends CreateOrder{
//declarations for label,text, and buttons
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
OrderSearch window = new OrderSearch();
window.frmXraymanager.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
public OrderSearch () { *Stack overflow error here*
initialize();
}
private void initialize() {
table = new JTable();
scrollPane.setViewportView(table);
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e2) {
if (e2.getClickCount() == 2 && !e2.isConsumed()) {
e2.consume();
try{
int index = table.getSelectedRow();
String table_Click = table.getModel().getValueAt(table.convertRowIndexToModel(index), 0).toString();
String sql = "SELECT ID, Date, Place, UserName FROM TEST.dbo.Intern WHERE ID = '"+table_Click+"'";
PreparedStatement pst = connection.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
if(rs.next()){
String id = rs.getString("ID");
String date = rs.getString("Date").toString();
String place = rs.getString("Place");
String uname = rs.getString("UserName");
frameCreate.setVisible(true); //Frame from CreateOrder.java
Number.setText(id); // textfields from CreateOrder.java
String date1 = startDate;
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
Date date2 = df.parse(date1);
dateChooser.setDate(date2);
jobSite.setText(place);
uName.setText(uname);
Component.setText(component);
Remarks.setText(remarks);
rs.close();
pst.close();
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
}
});
}
public void refresh()
{
query1 = "SELECT * FROM Test.dbo.Intern;
try(PreparedStatement pst = connection.prepareStatement(query1);
ResultSet rs = pst.executeQuery();){
table.setModel(DbUtils.resultSetToTableModel(rs));
table.setRowHeight(40);
}
catch(Exception e){
e.printStackTrace();
}
}
}
CreateOrder.java
public class CreateOrder {
public CreateOrder () {
initialize();
}
OrderSearch one = new OrderSearch(); *Stack overflow error here*
private void initialize() {
button_Save = new JButton("Save");
button_Save.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
*would like to add refresh() here*
}
});
}
}
How should I create an object of OrderSearch in CreateOrder to acces the method refresh() without opening the frame again?
Thanks in advance!
-Ajay
EDIT:
Actually the error is in
OrderSearch one = new OrderSearch();
and public OrderSearch () I totally understand it makes sense because it goes into infinite loop when I call an Object in CreateOrder.java. But is there any way to access the contents of OrderSearch.java in CreateOrder.java without getting the stackoverflow error or opening the whole new frame OrderSearch.java again?
No, there is no way to do it assuming your current setup. This leads us to the conclusion that you need to refactor the code. The main problem is that your code has no way to execute the required db command without creating a frame. You will need to separate the engine from the ui. You will need to be able to execute business logic without being tied to a UI event. The UI should be a user of the business logic, not its wrapper. You will need to move all your business logic into separate class(es) and call the relevant methods from the ui at the appropriate places and events.
How can I show jcalender?
How to get the selected value from it and add it to database?
From google I found a file called jcalender-1.4. I've added it to the jframe but when I try to get selected value from it and add it to the database it shows error. Table is created but error shows while inserting values. The exception in insertion method is shown. I've tried to print the value the value of db9 by commenting the insertData method and it shows null. Below is the link of JCalender jar file that i've used.
https://www.dropbox.com/s/yxe86ylfm4u6be8/jcalendar-1.4.jar?dl=0
JButton btnNewButton = new JButton("New Reservation");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
db1=textField.getText();
db2=textField_1.getText();
db3=textField_2.getText();
db4=textField_3.getText();
db5=textField_4.getText();
db6=textField_5.getText();
db7=textField_6.getText();
db8=(String)comboBox.getSelectedItem();
db9=dateChooser.getDate();
db10=textField_7.getText();
db11=(String)comboBox_1.getSelectedItem();
db12=(String)comboBox_2.getSelectedItem();
db13=dateChooser_1.getDate();
db14=dateChooser_2.getDate();
try {
insertData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
public static void createTable() throws Exception{
try{
Connection con=getConnection();
PreparedStatement create =con.prepareStatement("CREATE TABLE IF NOT EXISTS hotelDetails(_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,name varchar(65),"
+ "surname varchar(65),address varchar(65),cnic varchar(65),mobileNo varchar(65),email varchar(65),city varchar(65),gender varchar(65),dob Date,country varchar(65),roomType varchar(65),"
+ "roomNo varchar(65),checkin Date,checkout Date)");
create.executeUpdate();
System.out.println("Table Created");
}catch(Exception e)
{
JOptionPane.showMessageDialog(null,"Table Not Created.Try Again","Error", JOptionPane.ERROR_MESSAGE);
}
} public static void insertData() throws Exception{
try{
Connection con=getConnection();
PreparedStatement posted=con.prepareStatement("INSERT INTO hotelDetails(name,surname,address,cnic,mobileNo,email,city,gender,dob,country,roomType,roomNo,checkin,checkout)VALUES('"+db1+"','"+db2+"','"+db3+"','"+db4+"','"+db5+"','"+db6+"','"+db7+"','"+db8+"','"+db9+"','"+db10+"','"+db11+"','"+db12+"','"+db13+"','"+db14+"')");
posted.executeUpdate();
System.out.println("Values Inserted");
}catch(Exception e)
{
JOptionPane.showMessageDialog(null,"Can't Insert Data","Error", JOptionPane.ERROR_MESSAGE);
}
}
I'm making a program where you login and it takes you into a into a different frame after you log in.. That part of the program works, but I'm having trouble getting it to return the user's name and other data from the database. It connects to the database, but it won't return the information inside JTextField. If I can find out how to do firstName, I can figure out the rest. I'm using Eclipse as my IDE and SQLite Manager as the database.
There are 2 tables
Login (username,password)
Student(SID,firstName,GradeLevel, and more)
Also username is there ID start with an S (like S01 and so forth).
Here's the code.
public class student extends JFrame {
private JTextField textField;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
student frame = new student();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void ShowInfo() {
try{
String query="SELECT firstName From Student,Login Where firstname=?";
PreparedStatement ps=conn.prepareStatement(query);
ps.setString(1, "firstName");
ResultSet rs= ps.executeQuery();
while (rs.next()) {
textField.setText(rs.getString("firstName"));
System.out.print(""+textField);
}ps.close();
conn.close();
} catch ( Exception ex)
{
JOptionPane.showMessageDialog(null,ex);
}
}
}
private void ShowInfo() {
try{
String query="SELECT firstName From Student,Login Where firstname=?";
PreparedStatement ps=conn.prepareStatement(query);
ps.setString(1, "firstName");
ResultSet rs= ps.executeQuery();
if(rs.next()) {
textField.setText(rs.getString(1));
System.out.print(""+textField); //you are getting data
}ps.close();
conn.close();
} catch ( Exception ex)
{
JOptionPane.showMessageDialog(null,ex); //you have a error
}
}
there were sevral thing which were wrong in the code. first one is there should be something wrong with sql statment Student,Login Where firstname.
you should change this line textField.setText(rs.getString(1));
and you have a while loop to extract the data but and you are planning on having a textfield to store data. that is pointless if you are expecting more than one output from your resultset you need something more than a jtextfield maybe a jtable. bt i have changed your while loop to a if loop to get one single output from the resultset.and the other thing i notice in your application is you are not calling the showInfo method.
I have created two swing.JFrames.
login GUI and user GUI. what I want is when it's switches to login gui to user gui, there is a Jlabel in user GUI which needs to be changed as ("you're logged in as" + username);
I tried this code in userjframe source code.
`loggedInAsLable.setText("you're logged in as" + username);`
in a method and it's called in main method of user jframe. but for some reasons
it doesn't work.
how can I run some methods when a Jframe is becoming visible?
public class CustomerServiceOfficerUI extends javax.swing.JFrame {
private static Statement st;
ResultSet rs;
Connection con = null;
Login loginUI = new Login(); // gets current user Id
Employee cso = new CustomerServiceOfficer(); //creates new customer service officer object
/**
* Creates new form CustomerServiceOfficer
*/
public CustomerServiceOfficerUI() {
initComponents();
}
public void getCSOdetails() {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/flyingcarsdb", "root", "");
System.out.println("database connected");
} catch (ClassNotFoundException | SQLException ex) {
System.out.println("Error: " + ex);
}
try {
// Retrieve customer service officer details
st = con.createStatement();
String query = "select * FROM customerserviceofficer WHERE Id = '" + loginUI.getCurrentUserId() + "'";
rs = st.executeQuery(query);
while (rs.next()) {
//Assign the details with setters
cso.setFname(rs.getString("Fname"));
cso.setEmail(rs.getString("Email"));
}
} catch (Exception ex) {
System.out.println("Error : " + ex);
}
loggedInAsLable.setText("you're logged in as : " + cso.getId());
//this is where LABLE is changed, 'cso.getId()' returns the user ID
}
If you really need to update your JFrame when it becomes visible (as your last statement suggests), you can use the the WindowListener to call your getCSODetails() method.
public CustomerServiceOfficerUI() {
initComponents();
this.addWindowListener(new WindowAdapter() {
#Override
public void windowOpened(WindowEvent e)
{
this.getCSODetails();
}
#Override
public void windowDeiconified(WindowEvent e)
{
this.getCSODetails();
}
#Override
public void windowActivated(WindowEvent e)
{
this.getCSODetails();
}
});
}
I've included three activation events - opening, activation and deiconfication; you can remove any of them to limit the update to a specific event suiting your needs. If you need to update the label only once the window is opened, remove the methods windowDeiconified() and windowActivated().
Note, however, that the getCSODetails() method is designed quite poorly and calling it whenever the window becomes visible/focused would incur a performance penalty and the responsiveness of your GUI will be heavily influenced by performance of your database. I guess that the customer details you're displaying are not changed during a login session, so it would be more appropriate to perform the query once, cache the details and then display them from the cache.
try this:
public class CustomerServiceOfficerUI extends javax.swing.JFrame {
private static Statement st;
ResultSet rs;
Connection con = null;
Login loginUI = new Login(); // gets current user Id
Employee cso = new CustomerServiceOfficer(); //creates new customer service officer object
/**
* Creates new form CustomerServiceOfficer
*/
public CustomerServiceOfficerUI() {
initComponents();
}
public void getCSOdetails() {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/flyingcarsdb", "root", "");
System.out.println("database connected");
// Retrieve customer service officer details
st = con.createStatement();
String query = "select * FROM customerserviceofficer WHERE Id = '" + loginUI.getCurrentUserId() + "'";
rs = st.executeQuery(query);
while (rs.next()) {
//Assign the details with setters
cso.setFname(rs.getString("Fname"));
cso.setEmail(rs.getString("Email"));
}
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
loggedInAsLable.setText("you're logged in as : " + cso.getId());
loggedInAsLable.repaint();
}
});
} catch (Throwable ex) {
System.out.println("Error : " + ex);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
loggedInAsLable.setText("There is a problem with your code : " + ex);
loggedInAsLable.repaint();
}
});
} finally {
}
//this is where LABLE is changed, 'cso.getId()' returns the user ID
}
I have a main frame that has a list and "add" button. When I click on the 'add' button, one frame will be shown that I can enter name, family and id.
And by clicking on the "addAPerson", the name will be stored in the SQL. But when I close the frame, the new person will not be added to my list which is in my main frame but if I close the main frame and run it again, the new person will be added to the list.
How can I update the JList without running the main frame?
My main frame (a part of that):
public class ListFrame extends javax.swing.JFrame {
private InformationClass client;
private DefaultListModel model = new DefaultListModel();
/** Creates new form ListFrame. */
public ListFrame(InformationClass client) {
initComponents();
this.client = client;
fillTable();
}
public void fillTable() {
try {
List<InformationClass> list = null;
list = Manager.getClientListFromMySQL();
if (list == null) {
JOptionPane.showMessageDialog(
this,
"You should add a person to your list",
"Information",
JOptionPane.OK_OPTION);
return;
}
else {
for (int i = 0; i < list.size(); i++) {
InformationClass list1 = list.get(i);
model.add(i, list1.getId());
}
jList1.setModel(model);
}
}
catch (SQLException ex) {
Logger.getLogger(
ListFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
My frame which will be shown when you click on the add button (a part of that):
public class Add extends javax.swing.JFrame {
private InformationClass client;
public Add(InformationClass client) {
initComponents();
this.client = client;
}
private void addAPersonActionPerformed(java.awt.event.ActionEvent evt) {
submit();
clear();
}
private void submit() {
String s1 = nameF.getText();
String s2 = familyF.getText();
String s3 = iDf.getText();
if (s1.equals("") || s2.equals("") || s3.equals("")) {
JOptionPane.showMessageDialog(
this,
"fill the empty name/family/id text fields",
"Error",
JOptionPane.ERROR_MESSAGE);
return;
}
else {
try {
boolean b = Manager.isAddPerson(s1, s2, s3);
if (b == false) {
Manager.addPerson(s1, s2, s3);
JOptionPane.showMessageDialog(
this,
"The person has been added successfully",
"Information",
JOptionPane.INFORMATION_MESSAGE);
}
else {
JOptionPane.showMessageDialog(
this,
"These datas has been added before!!",
"Information",
JOptionPane.INFORMATION_MESSAGE);
}
}
catch (NullPointerException e) {
e.printStackTrace();
}
}
}
}
My Manager class (a part of that):
public static void addPerson(String name, String family, String yahooId) {
PreparedStatement pstmt;
String query;
try {
query = ("INSERT INTO newpersontable(name,family,yahooId) VALUES(?,?,?)");
pstmt = (PreparedStatement) conn.prepareStatement(query);
pstmt.setString(1, name);
pstmt.setString(2, family);
pstmt.setString(3, yahooId);
pstmt.executeUpdate();
}
catch (SQLException e) {
Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, e);
}
}
An implementation of the Observer pattern will do the trick.
Your InformationClass calls the Manager to add a person, if it is not already known. But you want that new person appear in the ListFrame. With the Observer pattern, the ListFrame will observe the Manager if it has some added, changed or deleted records. If it is the case, the ListFrame can update itself with the actual values, that it just requests again from the Manager.
We need one additional interface, a Listener and some methods on the Manager, that's all.
Here's a basic implementation:
public interface PersonsModelChangeListener {
public void modelHasChanged();
}
In Manager, add the following fields and methods:
List<PersonsModelChangeListener> listeners = new ArrayList<PersonsModelChangeListener>();
public void addListener(PersonsModelChangeListener listener) {
listeners.add(listener);
}
private void fireModelChangeEvent() {
for (PersonsModelChangeListener listener:listeners) {
listener.modelHasChanged();
}
}
Add the following line to the add method of Manager:
public void add(String s1, String s2, String s3) {
// existing code
fireModelChanged();
}
Next step: make ListFrame implement the PersonsModelChangeListener interface and implement the modelHasChanged method so that ListFrame can 'get' the actual values whenever the Managers data set has changed.
Edit
public class Manager {
// existing code
private static List<PersonsModelChangeListener> listeners = new ArrayList<PersonsModelChangeListener>();
public static void addListener(PersonsModelChangeListener listener) {
listeners.add(listener);
}
private static void fireModelChangeEvent() {
for (PersonsModelChangeListener listener:listeners) {
listener.modelHasChanged();
}
}
public static void addPerson(String name, String family, String yahooId) {
PreparedStatement pstmt;
String query;
try {
query = ("INSERT INTO newpersontable(name,family,yahooId) VALUES(?,?,?)");
pstmt = (PreparedStatement) conn.prepareStatement(query);
pstmt.setString(1, name);
pstmt.setString(2, family);
pstmt.setString(3, yahooId);
pstmt.executeUpdate();
fireModelChangedEvent();
} catch (SQLException e) {
Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, e);
}
}
public class ListFrame extends javax.swing.JFrame implements PersonsModelChangeListener {
// your fields
/** Creates new form ListFrame */
public ListFrame(InformationClass client) {
initComponents();
this.client = client;
fillTable();
Manager.addListener(this);
}
#Override
public void modelHasChanged() {
// this method will be called when you add something with the
// Manager.
// Add your code here to get the actual data from the Manager
// and update this component
}
}
Hope it helps :)
In the submit method save the created person and create a field for it which you can 'get' from the actionPerformed method for the 'add' button in the ListFrame class. Then just add it to the list model.
you just call the update method at the end of your coding.the update method should display the table.So when you add some thing to the list it will get updated in the database. so at the end of your coding it will call the update method which will display the updated table.Hopu u got my point