This is my first question here and I hope I am not repeating someone else's question. I will try and explain the problem as much as I can in the next few lines. Pardon my English if its really bad .
So I have here a JTable in which I would like to retrieve values from a database. So far I can add 1 value and I know why this is. The question is . How do I add multiple values to this table ?
This is the method I use in my operations to find a gun in a specific shop with its quantity
public ResultSet gunSearch(String id, int qty, int storeId) {
try {
String s = "SELECT gunID, gunName AS \"Gun Name\", gunPrice AS \"Price\", SellCost AS \"Cost\", availableQty AS \"Amount Available\", "+qty+" AS \"Quantity\" FROM Guns WHERE gunId = '" + id + "'AND storeId='"+storeId+"'";
pstmt = conn.prepareStatement(s);
rset = pstmt.executeQuery(s);
} catch (Exception ex) {
System.out.println("Error here at searchByProdId Operation "+ex);
}
return rset;
}
For my GUI I use the following code to display the information entered by the user
public void actionPerformed(ActionEvent e){
if(e.getSource().equals(enterBtn)){
String gunID = gunIdText.getText();
int qty = Integer.parseInt(quantityText.getText());
table.setModel(DbUtils.resultSetToTableModel(op.gunSearch(gunID, qty, storeId)));
Whenever I click the Enter button the column of data is retrieved from the database. However if I re-enter another gunId and quantity , the previous column disappears and the new column of data is retrieved from the database.
How could I possibly , enter couple of different gunId's and quantitie's into the JTable ?
Your gunSearch method only returns one result. You then completely recreate the TableModel from this one result, erasing whatever you had in the old model.
You'll need to concoct a new method that can take a Collection<String> (a collection of gun ids) and return a row for each id provided.
Alternatively, you can create a method that adds a gun to an existing TableModel rather than recreating the whole model from scratch every time. It depends on how you want the application to work, which option is better.
Related
I am using ucanaccess to link my database to my code but whenever I run it it doesnt work as I intend it to if it even runs at all. I just want to reorder the primary key (ID) into numerical order using ORDER BY ID;. When I edit the database it doesnt reorder when I run the method, it just pushes the edited ID to the bottom and orders them there. I am also confused if I should use an array sort in order to reorganize the entire table? Any help is appreciated. This runs whenever I attempt to edit the table in the GUI.
Source code google drive
public void reorder()
{
for(int i = 0 ; i < size - 1;i++)
{
for(int j = i+1 ; j< size;j++)
{
if(launch[i].getID() > launch[j].getID())
{
Launch temp = launch[i];
launch[i] = launch[j];
launch[j] = temp;
System.out.println(launch[i]);
}
}
}
}
public void orderByID()
{
String sql = "SELECT * FROM LaunchPriceList ORDER BY ID DESC";
try
{
dbman.updateQuery(sql);
//reorder();
}
catch(SQLException e)
{
System.out.println("Error Order by: " + e);
}
}
I am unable to access your code (for whatever the n/w restrictions). Having said that...
You can start off by creating a custom implementation of TableModel by extending AbstractTableModel
Coming to populating the TableModel, you start with iterating through the result set and creating a TreeSet with a custom Comparator that compares the ID attribute.
once done, you can create the table with the previously populated table model. E.g.
JTable t = new JTable(model);
Updating the TableModel with refreshed data will automatically refresh the table.
I'm working on a simple GUI where I drag combobox and edit the values here I i have a class categories and then 3 methods of rice,sweets and meal. I would like to be to call these three methods on my frame and then from there I want to fill the values into the combo box. An important thing that these 3 methods of categories class are connected with access so they fetch data from there. My question is: What will be the return type of these particular methods?
public String rice()
{
String query ="select * from categories";
String end=null;
String a ;
try{
ps=conn.prepareStatement(query);
rs=ps.executeQuery();
while(rs.next())
{
end=end+rs.getString("Rice")+"\t";
}
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
return end;
}`
now in another class
Combo_boxes obj = new Combo_boxes();
comboBox.addItem(obj.rice());
When I call this method it will to return a value of 1 row of database and then I want to place it into the combo box and then next row so from this,i will place every item from database. When I update my database it should automatically update the combo box.
I have a project set up with with an embedded derby jdbc and a jtable, however when I try to append data from my database to my jtable through resultset and adding the results from the resultset to a string[] and adding it to my tablemodel the result display is blank.
This is my database resultset:
ResultSet res = statement.executeQuery("SELECT * FROM VAULT");
while (res.next()) {
String [] row = {res.getString("Expenses"), res.getString("ExpensesType"), res.getString("PaymentType"), res.getString("Amount"), res.getString("Date")};
System.out.print(res.getString("Expenses"));
System.out.print(res.getString("ExpensesType"));
System.out.print(res.getString("PaymentType"));
System.out.print(res.getString("Amount"));
System.out.print(res.getString("Date"));
GUI.tableModel.addRow(row);
GUI.tableModel.fireTableDataChanged();
}
res.close();
This is my table code:
table = new JTable(tableModel);
table.setBackground(Color.GRAY);
table.setFillsViewportHeight(true);
JTableHeader header = table.getTableHeader();
header.setBackground(Color.DARK_GRAY);
header.setForeground(Color.LIGHT_GRAY);
scrollPane.setViewportView(table);
tableModel.addColumn("Expenses");
tableModel.addColumn("Expense Type");
tableModel.addColumn("Payment Type");
tableModel.addColumn("Amount");
tableModel.addColumn("Date");
Since the code, basically, works, I have to assume the problem is with some other part of the application which I cannot replicate, like the database management for example...
However...
Your resource management is non-existent...A database Statement has context and has a direct relationship to the query that made it, once you have completed working with it you should make sure you close it, for example...
public static Connection createDatabaseConnection() throws SQLException, ClassNotFoundException {
//...
System.out.println("Database Connected...");
try (Statement statement = c.createStatement()) {
count = statement.executeUpdate("CREATE TABLE VAULT (Expenses VARCHAR(5000), ExpensesType VARCHAR(5000), PaymentType VARCHAR(5000), Amount VARCHAR(10), Date VARCHAR(5000))");
System.out.println("Table Created...");
}
try (Statement statement = c.createStatement()) {
ResultSet res = statement.executeQuery("SELECT * FROM VAULT");
while (res.next()) {
String[] row = {res.getString("Expenses"), res.getString("ExpensesType"), res.getString("PaymentType"), res.getString("Amount"), res.getString("Date")};
System.out.print(res.getString("Expenses"));
System.out.print(res.getString("ExpensesType"));
System.out.print(res.getString("PaymentType"));
System.out.print(res.getString("Amount"));
System.out.print(res.getString("Date"));
GUI.tableModel.addRow(row);
}
}
and...
String updateStatement = "INSERT INTO VAULT"
+ " (Expenses, ExpensesType, PaymentType, Amount, Date)"
+ " VALUES (\'" + expenses + "\',\'" + expensesType + "\',\'" + paymentType + "\',\'" + amount + "\',\'" + date + "\')";
try (Statement statement = c.createStatement()) {
System.out.print(updateStatement);
int c = statement.executeUpdate(updateStatement);
count = count + c;
System.out.println("Data Inserted in to Database...");
} catch (Exception ex) {
ex.printStackTrace();
}
This will ensure that once you leave the try section, the resource will automatically be closed.
You should also consider making use of PreparedStatements, see Using Prepared Statements for more details.
In your actionPerformed method, this...
table.setModel(tableModel);
is worrying. The model has already been set when you setup the UI, you shouldn't need to set it again unless you've create a new model or table, which you've done neither of...
And...
tableModel.fireTableDataChanged();
table.updateUI();
Should never be done. You should never call any of the notification methods of a model externally, these should all be taken care of by the model it self (and in the case of the DefaultTableModel are).
updateUI has nothing to do with "updating the state of the UI" and has is probably the most efficient method you could use. The simple fact that you've fireTableDataChanged should have already triggered an update (although fireTableDataChanged is also one of the most efficient methods you could use as well).
Simply call tableModel.addRow and let the model and table do the rest.
Your work flow is a little off. You shouldn't add the row to the table until AFTER you've made sure it's been added to the database, what happens if the insert fails for some reason?
You really, really, REALLY should learn to make use of dialogs, see How to Make Dialogs for more details, instead of throwing, yet, another frame at the user...
static is not your friend, sure it might "seem" to make life easier and "it's just a quick {what ever}", but bad is bad any of the time...
You should never make UI components static it is way to easy to lose context and not know if you're updating what's actually on the screen or not.
"But how does class X reference component Y?" - in most cases, it shouldn't. I should either return a value/values that container class can deal with or should communicate through the use of some kind of model or observer pattern...
If you're going to strip away the window frame, you had better implement functionality that allows me to drag it and, because it's a personal grip of mine, resize it, otherwise your users will not like you
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
See Why is it frowned upon to use a null layout in Swing? and Laying Out Components Within a Container for more details...
EDIT(NEW):
Still haven't figured out how to populate the cboxCustomers. I've been at it for the past day or two, but without luck.
In case anyone can help: http://pastebin.com/e5wibRYw
I went from cats to customers, btw.
I tried Mr. Xymon's approach, but didn't implement it correctly since it didn't work.
Whatever event I used to handle the population I always got NullPointerException for whatever control/event I was trying to use.
OLD:
There's a JForm. On it, there's a single combo box. Also have a single table with cats - cats. Each cat has id, and catName.
What I wanted to do was when I click on the combo box, thus expanding it, populate it with all id of cats that are found in cats table.
SLOVED. Asnwer below.
Unfortunately I receive numerous unreported exception java.sql.SQLException from the lines I've indicated with >:
private void cboxCatsMouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
// create an array list to be filled with cat's ids
ArrayList<String> cats = new ArrayList<String>();
String query = "SELECT id FROM cats ORDER BY id";
>java.sql.PreparedStatement stm = connection.prepareStatement(query);
>ResultSet rs = stm.executeQuery(query);
>while(rs.next()){
>String cat = rs.getString("id");
// add cat's ids tp the array list
cats.add(cat);
}
>rs.close();
// populate the combo box
DefaultComboBoxModel model = new DefaultComboBoxModel(cats.toArray());
cboxCats.setModel(model);
}
OLD ANSWER:
I think I fixed it. I just had to wrap all of the highlighted lines of code together into one big try-catch statement that would catch SQLException. Problem is - the combo box doesn't get populated with id values when I expand it. Why is that? Am I using the wrong event?
Isn't better to populate your combo box with cat's name instead of the id? I came up with a different solution by directly adding field value into model instead of using ArrayList. You have to perform it within the constructor to populate the combo box upon loading the form.
DefaultComboBoxModel list = new DefaultComboBoxModel();
JComboBox cbo_cats = new JComboBox(list);
// at constructor or a user-defined method that's called from constructor
try{
// assume that all objects were all properly defined
s = con.createStatement();
s.executeQuery("SELECT * FROM cats ORDER BY catName");
rs = s.getResultSet();
while(rs.next()){
//int id = rs.getInt("id");
//list.addElement(id);
String c = rs.getString("catName");
list.addElement(c);
}
}catch(Exception err){
System.out.println(err);
}
As you can see I didn't use prepared statements but you can easily change that.
I'm struggling with a homework assignment and am getting hung up on some SQL queries.
My query is interrogating an inventory database for the quantity of some item. The query requests the column with the name quantity_in_stock from the table, given the primary key.
I have initialized some prepared statements. This is the one I'm using here:
stmtFindColumn = Database.getConnection().prepareStatement(String.format("select ? from %s where %s = ?",
INVENTORY_TABLE_NAME, SKU) );
Now a separate method is called. I pass it a static const QTY_IN_STOCK, which is defined as "quantity_in_stock" and the item's SKU number, which is the primary key in the table.
private int getIntegerFromTable(String column, String key) {
int toReturn = 0;
try {
// Complete the prepared statement
stmtFindColumn.setString(1, column);
stmtFindColumn.setString(2, key);
ResultSet result = stmtFindColumn.executeQuery();
toReturn = result.getInt(column);
} catch (SQLException e) {
LOG.error(e.getMessage());
e.printStackTrace();
}
return toReturn;
}
When I run the query I get an sql exception that tells me: Invalid column name quantity_in_stock.
I have tried using a while loop processing result.next() and get the same error. I can't find any examples of how to properly get the results when you know only a single record is being returned.
Help!
EDIT: OK, I've found that part of my problem is I'm not getting a result set, where I should expect one. Any ideas?
UPDATE: I've tested my code, using a garden variety statement and a plain string query instead and it works just fine. So the problem is in my use of the prepared statement. Can someone check if I'm using the ? wildcards correctly? Thanks!
as far as i know, the column name may not be a parameter ...
DarkSquirrel42 is right -- you can't replace the column list of the select using a ? parameter marker. Instead, you can String.format that into place too, for example.
bad:
*select ? from INVENTORY_TABLE_NAME where SKU = ?
good:
select QUANTITY_IN_STOCK from INVENTORY_TABLE_NAME where SKU = ?