How can I immediately see the changed data on my JTable? - java

I have already used the fireDataChanged methods but I think due to the fact that this is connected to my database it will not do anything.
DelBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int selRow = table.getSelectedRow();
Object element = table.getValueAt(selRow, 0);
th = table.getTableHeader();
tcm = th.getColumnModel();
Statement statement = null;
try {
statement = ResultSetTableModelFactory.connection
.createStatement();
if (JisSelected == true) {
String delete = "DELETE FROM J WHERE JNO = '" + element + "';";
statement.executeUpdate(delete);
}
if (SPJisSelected == true) {
String delete = "DELETE FROM SPJ WHERE SNO = '" + element + "';";
statement.executeUpdate(delete);
}
System.out.println(element);
} catch (Exception ex) {
//ex.printStackTrace();
}
model.fireTableDataChanged();
}
});
}

Your ActionListener should perform its work in your implementation of the doInBbackground() method of a SwingWorker. In the interim, you should signify that the operation is pending in whatever way is appropriate to your application, perhaps in a renderer or status indicator. If the database operation succeeds, update the TableModel in your implementation of done(). In no case should you invoke fireTableDataChanged() except from within the model.

Related

How to make column updatable in JDBC?

I'm using JDBC to make a banking system with Java. The user should be able to type in a number in a text field, and deposit said amount of money into the bank account. I would like to then update the account balance in the Microsot Access database.
I currently have this:
try (Connection con = DriverManager.getConnection("jdbc:ucanaccess://C://Users//User//IdeaProjects//Database4.accdb")) {
Statement users = con.createStatement();
ResultSet sr = users.executeQuery("Select * from Registrations");
Boolean duplicate = false;
while (sr.next()) {
if (userID.equals(sr.getString(2))) {
match = sr;
duplicate = true;
System.out.println("Welcome " + match.getString(2));
System.out.println("Your balance is " + match.getString(3));
break;
}
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == depositButton) {
String depositString = depositField.getText();
int depositAmount = Integer.parseInt(depositString);
try {
System.out.println(match.getInt(3) + depositAmount);
match.updateInt("AccBalance", match.getInt(3) + depositAmount);
match.updateRow();
}
catch (SQLException ex) {
ex.printStackTrace();
}
When I try to do this, I get the error 'attempt to assign to non-updatable column'.
I'm very new to Java and tried looking online to find fixes for this issue but couldn't find anything useful.
Try the code below
try (Connection con = DriverManager.getConnection("jdbc:ucanaccess://C://Users//mghosh22//IdeaProjects//Database4.accdb")) {
// Query example UPDATE user SET balance = 10000 WHERE user.id = 1;
PreparedStatement updateBalance = conn.prepareStatement("UPDATE <table> SET balance = ? WHERE <wich row update>");
// For each query parameter, set a value to execute the same
// preparedStatement.setParameterType(countEach?StartingWithOne, yourQueryParameter);
updateBalance.setDouble(1, 10,000.00);
// Execute update return the amount of rows your query affected, how we are talking about account balance, the number of rows affected may be ever one
if (updateBalance.executeUpdate() == 1) {
System.out.println("Row updated");
}
}

How to extract specific information from the selected item in a JComboBox?

I have a form that has a ComboBox which it gets its items from a database. The combobox takes numerous column-items from a table inside the database.
I want to take only one of these items (from the combobox) and copy it to a JTextField.
Here's the code of the creation of the ComboBox in the Order.java file:
cbinv = new JComboBox<>();
cbinv.setModel(new InvComboModel(con));
and the code from the InvComboModel.java:
public InvComboModel(Connection con) {
try {
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String query = "SELECT * FROM inventory";
rs = stmt.executeQuery(query);
} catch (SQLException e) {
System.out.println("InvComboModel: " + e.getMessage());
}
}
#Override
public String getElementAt(int index) {
String lstn = null;
try {
rs.absolute(index + 1);
lstn = rs.getString("category") + ", " + rs.getString("description") + ", "
+ rs.getInt("price") + ", " + rs.getInt("quantity");
} catch (SQLException e) {
System.out.println("getElementAt(): " + e.getMessage());
}
return lstn;
}
#Override
public int getSize() {
int cnt = 0;
try {
rs.last();
cnt = rs.getRow();
} catch (SQLException ex) {
System.out.println("getSize(): " + ex.getMessage());
}
return cnt;
}
public int getIdInvAt(int index) {
int idInv = 0;
try {
rs.absolute(index + 1);
idInv = rs.getInt("idinv");
} catch (SQLException e) {
System.out.println("getElementAt(): " + e.getMessage());
}
return idInv;
}
So, I want when I select something on the Inventory Item to take the third value (which in this case is 500, example image) and copy it to the JTextField of the ItemPrice.
[example][1]: https://i.stack.imgur.com/BWQVw.jpg
In the Order.java file I have the following command but it copies all the selected item in the combobox:
tip.setText((String) cbinv.getSelectedItem());
and when I use the following command it takes the whole line again. It seems that I can't use any other method from the InvComboModel.java file
tip.setText((String) cbinv.getModel().getElementAt());
Thanks in advance.

Java - jTable sort numbers

I have searched for very long time so I have decided to write finally here. I have problem with sorting numbers (Integers, doubles, shorts) in a jTable, I have overwritten the getColumnClass method, however it still does not sort numbers correctly.
Here is what I did:
List<Class> types = new ArrayList();
types.add(String.class);
types.add(String.class);
types.add(String.class);
for (int s = 0; s < sloupce.size(); s++) {
try {
Statement st = log.getSt();
ResultSet r = st.executeQuery("SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '" + table + "' AND COLUMN_NAME = '" + sloupce.get(s) + "'");
if (r.next()) {
String typ = r.getString("DATA_TYPE");
if (!typ.equals("varchar")) {
types.add(Integer.class);
} else {
types.add(String.class);
}
}
} catch (Exception e) { System.out.println(e.toString()); }
}
DefaultTableModel tm = new DefaultTableModel(new Object[0][], new String[] {" first column ", " second ", " another "}) {
#Override
public Class getColumnClass(int columnIndex) {
return types.get(columnIndex);
}
};
Then I fill types array withproper classes, when I test the getColumnClass method it really returns proper class (java.lang.Integer), but it still sorts the values incorrectly.
//UPDATE:
I am representing a table from MySQL DB so I have updated my exact code how I am doing it.

Java: Check auto-generated ID

My Java program adds items into database. I have a code for generating random string that will be used as an item ID. I want to make IDchecker(id) that will check whether the ID already exists into database.
If I have codeIDgenerator() and IDchecker(id) methods, how do I make a loop that will generate new code if the ID already exists, or will exit the loop if the ID is unique and doesn't come up in the database?
Also I'm having trouble with my IDchecker(id) method, I'm using ResultSet to bring back the data from SQL, but I can't find a way to determine how many rows does ResultSet has (if at all). There is no isEmpty() for resultSet?
Here's the code:
public void AddItem() {
boolean checkCode = false;
while (checkCode == false) {
Random r = new Random();
int numbers = 100000 + (int) (r.nextFloat() * 899900);
String ID= Integer.toString(numbers);
try {
if (DatabaseConnection.checkID(ID) == false) {
checkCode = true;
System.out.println("ID is unique");
} else if (DatabaseConnection.checkID(ID) == true) {
System.out.println("ID is NOT unique");
}
} catch (SQLException ex) {
Logger.getLogger(ModelTabeleIntervencija.class.getName()).log(Level.SEVERE, null, ex);
}
}
And here is the ckeckID(ID) method
public boolean CheckID(String ID) throws SQLException {
String query = "SELECT itemId FROM items WHERE itemID= '"+ID+"'";
Statement dbStatement = connection.createStatement();
ResultSet rsItems= dbStatement .executeQuery(query);
if (rsItems.isEmpty( )== true){
return false;
// ID not found - is unique
} else{
return true;
// ID found - is not unique
}
}
Thanks
While generating unique id is best done in your database, I can help you simplify your code. You shouldn't need to check your database twice.
private final Random r = new Random();
public String getUniqueId() {
try {
while (true) {
int n = r.nextInt(1000 * 1000) + 1000 * 1000;
String id = ("" + n).substring(1); // number between 000000 and 999999
if (DatabaseConnection.checkID(id))
return id;
}
} catch (SQLException ex) {
throw new IllegalStateException("Cannot access database", ex);
}
}
However, instead of generating a random id, you could just get the next id.
public String getUniqueId() {
try {
String maxId = DatabaseConnection.selectMaxId();
int n = Integer.parseInt(maxId) + 1;
return ("" + n).substring(1); // number between 000000 and 999999
} catch (SQLException ex) {
throw new IllegalStateException("Cannot access database", ex);
}
}

problem w/ multiple jcombobox

I've been working with a project that requires me to use mutiple jcombobox. I did try to chain three jcombobox but failed to show all necessary drop-down lists.
In one of my combobox I have lists of Banks (Bank1, Bank2), the other one is the list of all branches in a specific Bank that has been selected (Bank1(branch1-1, branch1-2), Bank2(branch2-1, branch2-2)) and the last one are the account # for all specific branches that has been selected. Each branches has a multiple accounts.
I have no problem working with 2 comboboxes, all branches are shown for a specific Bank that has been selected, but, when I added the third combobox which is the account #, only one branch is being queried from my db. ex. if I select Bank1 only "branch1" will be on the list, and if Bank2 only branch2-1 will be on the list also, but account # for that specific branches are on the drop-down lists.
private void populateSavingsAccountComboBox() {
accountNo.removeAllItems();
bankBranch.removeAllItems();
selectBank();
bankName.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String bank = bankName.getSelectedItem() == null ?
"" : bankName.getSelectedItem().toString();
selectBranch(bank);
}
});
bankBranch.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
Object source = e.getSource();
JComboBox target = (JComboBox) e.getSource();
String branch = target.getSelectedItem() == null ?
"" : target.getSelectedItem().toString();
if (e.getStateChange() == ItemEvent.SELECTED) {
selectAccountNo(bankName.getSelectedItem().toString(), branch);
}
}
});
}
private void selectBank() {
List bankList = new ArrayList();
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(" SELECT bankName FROM bank_tbl ");
bankName.removeAllItems();
while (rs.next()) {
String bank = rs.getString("bankName");
bankList.add(bank);
Object bankElement = bankList.get(bankList.size() - 1);
bankName.addItem(bankElement);
}
} catch (SQLException ex) {
Logger.getLogger(addSavings.class.getName()).log(Level.SEVERE, null, ex);
}
}
private String selectBranch(String bank) {
try {
List branchList = new ArrayList();
rs = stmt.executeQuery(" SELECT branch FROM bank_branch_tbl WHERE "
+ " bankName = '" + bank + "' ");
bankBranch.removeAllItems();
while (rs.next()) {
branchList.add(rs.getString("branch"));
Object branchElement = branchList.get(branchList.size() - 1);
bankBranch.addItem(branchElement);
}
} catch (SQLException ex) {
Logger.getLogger(addContact.class.getName()).log(Level.SEVERE, null, ex);
}
return bank;
}
private String selectAccountNo(String bank, String branch) {
List accountNoList = new ArrayList();
try {
rs = stmt.executeQuery(" SELECT accountNo FROM account_no_tbl WHERE "
+ " bankName = '" + bank + "' AND "
+ " branch = '" + branch + "' ");
accountNo.removeAllItems();
while (rs.next()) {
accountNoList.add(rs.getString("accountNo"));
Object accountNoElement = accountNoList.get(accountNoList.size() - 1);
accountNo.addItem(accountNoElement);
}
} catch (SQLException ex) {
Logger.getLogger(addSavings.class.getName()).log(Level.SEVERE, null, ex);
}
return branch;
}
problem solved. I was using one-single variable for all ResultSet. tsk! thank you for replying to my post.

Categories