I am new to Java and I am practicing some new stuff.. I've started working with the database. therefore I made a to do list application with the MVC pattern.
In my Model I get all the results. In My view I try to output this data as a nice table. The problem is that I don't get any output except for a hardcoded piece of code..
here is the code of my view
JTable table = null;
public ToDoListView(ToDoListModel model) {
this.model = model;
setBackground(Color.WHITE);
JTable table = new JTable();
DefaultTableModel tableModel = new DefaultTableModel(new Object[][]{},new String[]{"To do","Date added"});
table.setModel(tableModel);
// this one below is outputted
tableModel.addRow(new Object[]{"something","1-1-2012"});
// this should give me all the results..
for(int i = 0; i < model.getRows().size(); i++) {
tableModel.addRow(model.getRows());
System.out.println("added");
}
add(table);
}
in my Model I have this
private Vector<String> rijen = new Vector<String>();
public void getValue() {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = db.connectToAndQueryDatabase("test", "root", "root");
System.out.println("connection established");
st = con.createStatement();
String query = "SELECT id, item, datum FROM toDoList";
rs = st.executeQuery(query);
while(rs.next()) {
System.out.println(rs.getInt("id") + "\n" + rs.getString("item") + "\n" + rs.getDate("datum"));
rijen.add(rs.getInt("id") + "");
rijen.add(rs.getString("item"));
rijen.add(rs.getDate("datum") + "");
}
public Vector<String> getRows() {
return rijen;
}
This is all the relevant code.. I don't know what I miss or what I do wrong. Could someone show me how I could solve it :)?
// This JTable attribut ...
JTable table = null;
public ToDoListView (ToDoListModel model) {
this.model = model;
setBackground (Color.WHITE);
// is hidden by this local variable:
JTable table = new JTable();
In your ToDoModel class you add all data in one large Vector
while(rs.next()) {
System.out.println(rs.getInt("id") + "\n" + rs.getString("item") + "\n" + rs.getDate("datum"));
rijen.add(rs.getInt("id") + "");
rijen.add(rs.getString("item"));
rijen.add(rs.getDate("datum") + "");
}
Then you loop over that Vector to add all those items to the TableModel, but that loop is incorrect
for(int i = 0; i < model.getRows().size(); i++) {
tableModel.addRow(model.getRows());
System.out.println("added");
}
You always add the whole vector instead of just the data for that row.
Combine that with the answer of #user unknown and you might be able to fix your problem
Related
I'am trying to access data from database and showing it in jTable on clicking a button. but my table shows nothing on pressing button. i have gone through all adding row into table questions in stackOverflow but nothing helped me. here i'am pasting my button's actionListener-
private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
java.util.Date utildate = jDateChooser1.getDate();
java.sql.Date date = new java.sql.Date(utildate.getTime());
//System.out.println(date);
String dbURL = "jdbc:derby://localhost:1527/contact;user=nbuser;password=nbuser";
Connection conn = null;
Statement stmt = null;
try
{
Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();;
//Get a connection
conn = DriverManager.getConnection(dbURL);
stmt = conn.createStatement();
//System.out.println(id);
ResultSet result = stmt.executeQuery("select ID, NAME from EMPLOYEE ORDER BY ID ");
ArrayList<String> id = new ArrayList<String>();
ArrayList<String> name = new ArrayList<String>();
Map<String, String> present = new HashMap<String, String>();
while(result.next()){
id.add(result.getString("id"));
name.add(result.getString("name"));
present.put(result.getString("id"), "A");
}
result = stmt.executeQuery("select ID from ATTENDANCE where DATE = '" + date +"'");
while(result.next()){
present.replace(result.getString("id"), "P");
}
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
model.setColumnIdentifiers(new String[] { "Id", "Name","Attendance"});
for(int i = 0; i < id.size(); i++){
System.out.println(id.get(i)+" "+ name.get(i)+ " "+ present.get(id.get(i)));
model.addRow(new String[]{id.get(i), name.get(i), present.get(id.get(i))});
model.fireTableRowsInserted(1, i+1);
}
jTable1.setModel(model);
}
catch (Exception except)
{
except.printStackTrace();
}
}
please tell me where i'am doing wrong?
I coded Auto Suggesting Combo boxes. Functionality is,
*when a user type the first letter in either combo box , data retrieves from the MySQL database and show in a popup list, when a user click on a suggested item ,then press Add button that item added to the J Table and clears the combo boxes
But when I select another item from the combo box and click Add button before added one disappears
*How can I keep Both or many items in the J Table according to above situation *
I'll post my code:
private void NamecomboActionPerformed(java.awt.event.ActionEvent evt) {
String drugname = (String) Namecombo.getSelectedItem();
try{
String name = "SELECT * FROM druginfo WHERE ItemName LIKE '"+drugname+"%'";
PreparedStatement pstmt = conn.prepareStatement(name);
ResultSet rs = pstmt.executeQuery();
while (rs.next()){
IDcombo.setSelectedItem(rs.getString("ItemID"));
}
}catch(Exception e){
JOptionPane.showMessageDialog(null,"error "+ e);
}
}
private void IDcomboActionPerformed(java.awt.event.ActionEvent evt) {
String drugid = (String) IDcombo.getSelectedItem();
try{
String name = "SELECT * FROM druginfo WHERE ItemID LIKE '"+drugid+"%'";
PreparedStatement pstmt = conn.prepareStatement(name);
ResultSet rs = pstmt.executeQuery();
while (rs.next()){
Namecombo.setSelectedItem(rs.getString("ItemName"));
}
}catch(Exception e){
JOptionPane.showMessageDialog(null,"error "+ e);
}
try{
String exp = "SELECT ExpDate FROM druginfo WHERE ItemID LIKE '"+drugid+"%'";
PreparedStatement pstmt = conn.prepareStatement(exp);
ResultSet rs2 = pstmt.executeQuery();
while (rs2.next()){
String date = rs2.getString("ExpDate");
exptxt.setText(date);
}
}catch(Exception e){
JOptionPane.showMessageDialog(null,"error "+ e);
}
}
add button action performed for adding item to JTable;
private void add_btnActionPerformed(java.awt.event.ActionEvent evt) {
String temp = (String) IDcombo.getSelectedItem();
String sql = "select ItemID,ItemName,CostPrice,InStock from druginfo where ItemID=?";
try {
pst=conn.prepareStatement(sql);
pst.setString(1, temp);
rs=pst.executeQuery();
tableSale.setModel(DbUtils.resultSetToTableModel(rs));
IDcombo.setSelectedItem(null);
Namecombo.setSelectedItem(null);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex);
}
Add the current selection(resultset data) to JTable object without replacing the old data.
rs=pst.executeQuery();
addDataToTable(tableSale,DbUtils.resultSetToTableModel(rs));
IDcombo.setSelectedItem(null);
Namecombo.setSelectedItem(null);
//ADD this method
public void addDataToTable(JTable table,TableModel model) {
DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
DefaultTableModel resultSetModel = (DefaultTableModel) model;
for (int i = 0; i < resultSetModel.getRowCount(); i++) {
Vector row=new Vector();
for (int j = 0; j < resultSetModel.getColumnCount(); j++) {
row.addElement(resultSetModel.getValueAt(i, j));
}
tableModel.addRow(row);
}
tableModel.fireTableDataChanged();
}
This tableSale.setModel(DbUtils.resultSetToTableModel(rs)); will replace the old model with new model.So obviously datas will be lost.You have to add values to the existing model.I have added a snippet which will help you.
Replace tableSale.setModel(DbUtils.resultSetToTableModel(rs)); with addValuesToModel(DbUtils.resultSetToTableModel(rs));
addValuesToModel(DbUtils.resultSetToTableModel(rs));
public void addValuesToModel(TableModel resultModel) {
DefaultTableModel tmodel = (DefaultTableModel) tableSale.getModel();
DefaultTableModel rmodel = (DefaultTableModel) resultModel;
for (int i = 0; i < rmodel.getRowCount(); i++) {
Object[] row = new Object[rmodel.getColumnCount()];
for (int j = 0; j < rmodel.getColumnCount(); j++) {
row[j] = rmodel.getValueAt(i, j);
}
tmodel.addRow(row);
}
}
I want to display the data out of my result set into a JTable.
When I run the following code the table doesn't update.
public void getHouses(int price) {
Connection conn;
ArrayList<Integer> ID = new ArrayList<Integer>();
ArrayList<String> Price = new ArrayList<String>();
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
conn = DriverManager.getConnection("jdbc:odbc:Houses");
Statement statement = conn.createStatement();
ResultSet rec = statement.executeQuery("SELECT * FROM Houses WHERE Price <= " + price + "");
while (rec.next()) {
ID.add(rec.getInt("ID"));
Price.add(rec.getString("Price"));
}
String[] columnNames = {"House ID", "House Price"};
Object[][] rows = new Object[ID.size()][2];
for (int i = 0; i < ID.size(); i++) {
rows[i][0] = ID.get(i);
rows[i][1] = Price.get(i);
}
jTable1 = new JTable(rows, columnNames);
statement.close();
} catch (SQLException se) {
} catch (ClassNotFoundException cnf) {}
}
NOTE!
I added the JTable to the gui by drag and drop.
I also tested that my resultset has the data in it.
You need to learn about OP Swing MVC pattern, you need to declare a TableModel which your data store then set it to your table, like:
TableModel myData = new DefaultTableModel(columnVector, dataVector);
jTable1.setModel(myData);
Read more about DefaultTableModel
public void search() throws Exception{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:******";
String user = "*****";
String pass = "*****";
Connection con = DriverManager.getConnection(url, user, pass);
Statement state = con.createStatement();
ResultSet rs = state.executeQuery("");
ResultSetMetaData rsmetadata = rs.getMetaData();
int columns = rsmetadata.getColumnCount();
DefaultTableModel dtm = new DefaultTableModel();
Vector column_name = new Vector();
Vector data_rows = new Vector();
for (int i=1; i<columns;i++){
column_name.addElement(rsmetadata.getColumnName(i));
}
dtm.setColumnIdentifiers(column_name);
while(rs.next()){
data_rows = new Vector();
for (int j=1; j<columns; j++){
data_rows.addElement(rs.getString(j));
}
dtm.addRow(data_rows);
}
tblPatient.setModel(dtm);
}
On my ResultSet rs = state.executeQuery() I used this SQL
"SELECT "
+ "pIDNo AS 'Patient ID',"
+ "pLName AS 'Last Name',"
+ "pFName AS 'First Name',"
+ "pMI AS 'M.I.',"
+ "pSex AS 'Sex',"
+ "pStatus AS 'Status',"
+ "pTelNo AS 'Contact No.',"
+ "pDocID AS 'Doctor ID',"
+ "pAddr AS 'St. No.',"
+ "pStreet AS 'St. Name',"
+ "pBarangay AS 'Barangay',"
+ "pCity AS 'City',"
+ " pProvince AS 'Province',"
+ " pLNameKIN AS 'Last Name',"
+ "pFNameKIN AS 'First Name',"
+ "pMIKIN AS 'M.I.',"
+ "pRelationKIN AS 'Relation',"
+ "pTotalDue AS 'Total Due'"
+ " FROM dbo.Patients");
First I run this line (pTotalDue didn't come up to jTable.)
And on my second attempt to display it I do this:
"SELECT pTotalDue AS 'Total Due' FROM dbo.Patients"
Now I tried this one, and I think something's really wrong about my codes. BTW this column has MONEY DATA TYPE
why does it didn't show to my JTable? could anyone tell me what is the problem with my codes?
(Problem in the answer that has given to me)
public class QueryOnWorkerThread extends SwingWorker{
private final JTable tableToUpdate;
public QueryOnWorkerThread( JTable aTableToUpdate ) {
tableToUpdate = aTableToUpdate;
}
#Override
protected TableModel doInBackground() throws Exception {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:OJT_dsn";
String user = "sa";
String pass = "";
Connection con = DriverManager.getConnection( url, user, pass );
Statement state = con.createStatement();
ResultSet rs = state.executeQuery("");
ResultSetMetaData rsmetadata = rs.getMetaData();
int columns = rsmetadata.getColumnCount();
DefaultTableModel dtm = new DefaultTableModel();
Vector column_name = new Vector();
Vector data_rows;
//note the <= check iso the < check (as the count starts at index 1)
for (int i=1; i<=columns;i++){
column_name.addElement(rsmetadata.getColumnName(i));
}
dtm.setColumnIdentifiers(column_name);
while(rs.next()){
data_rows = new Vector();
//note the <= check iso the < check (as the count starts at index 1)
for (int j=1; j<=columns; j++){
data_rows.addElement(rs.getString(j));
}
dtm.addRow(data_rows);
}
return dtm;
}
`#Override <<<<<<<<<<<<<<<<<<<<< I have a problem here it says : done() in javaapplication25.SearchPatient.QueryWorkerThread cannot override done() in javax.swing.SwingWorker overriden method does not throw java.lang.Exception , what does it mean sir?`
protected void done() throws Exception{
//this method runs on the EDT, so it is safe to update our table here
try {
tableToUpdate.setModel( get() );
} catch ( InterruptedException e ) {
throw new RuntimeException( e );
} catch ( ExecutionException e ) {
throw new RuntimeException( e );
}
}
try this
DefaultTableModel dtm=(DefaultTableModel)table.getModel();
for (int i = dtm.getRowCount() - 1; i > -1; i--) {
dtm.removeRow(i);
}
Connection con = DriverManager.getConnection(url, user, pass);
Statement state = con.createStatement();
ResultSet rs = state.executeQuery("Your SQL Query");
while(rs.next())
{
String str1=rs.getString(1);
String str2=rs.getString(2);
String str3=rs.getString(3);
String str4=rs.getString(4);
String str5=rs.getString(5);
:
:
:
dtm.addRow(new Object[]{str1,str2,str3,str4,str5});
}
In you loops, your exit condition is
j<columns
this means thant the last column will never be recovered. try this insted:
for (int j=1; j<=columns; j++)
The fact that your last column does not appear is probably related to your loop statements, as already indicated by #Joan.
There are however more issues with this code. You should only update Swing components on the Event Dispatch Thread, and on that Thread you should not perform long running operations. In short, mixing SQL queries and updates of the JTable should not happen on the same thread. Consult the Concurrency in Swing guide for more info.
Using a SwingWorker could solve this issue:
public class QueryOnWorkerThread extends SwingWorker<TableModel, Void>{
private final JTable tableToUpdate;
public QueryOnWorkerThread( JTable aTableToUpdate ) {
tableToUpdate = aTableToUpdate;
}
#Override
protected TableModel doInBackground() throws Exception {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url = "jdbc:odbc:******";
String user = "*****";
String pass = "*****";
Connection con = DriverManager.getConnection( url, user, pass );
Statement state = con.createStatement();
ResultSet rs = state.executeQuery("");
ResultSetMetaData rsmetadata = rs.getMetaData();
int columns = rsmetadata.getColumnCount();
DefaultTableModel dtm = new DefaultTableModel();
Vector column_name = new Vector();
Vector data_rows;
//note the <= check iso the < check (as the count starts at index 1)
for (int i=1; i<=columns;i++){
column_name.addElement(rsmetadata.getColumnName(i));
}
dtm.setColumnIdentifiers(column_name);
while(rs.next()){
data_rows = new Vector();
//note the <= check iso the < check (as the count starts at index 1)
for (int j=1; j<=columns; j++){
data_rows.addElement(rs.getString(j));
}
dtm.addRow(data_rows);
}
return dtm;
}
#Override
protected void done() {
//this method runs on the EDT, so it is safe to update our table here
try {
tableToUpdate.setModel( get() );
} catch ( InterruptedException e ) {
throw new RuntimeException( e );
} catch ( ExecutionException e ) {
throw new RuntimeException( e );
}
}
}
The SwingWorker can be started by calling
QueryOnWorkerThread worker = new QueryOnWorkerThread( tblPatient );
worker.execute();
Note how I changed the loops in your code
Try getting that column via ResultSet.getBigDecimal() rather than via ResultSet.getString(). Then put your retrieved BigDecimal.toPlainString() into your table cell.
Example:
data_rows.addElement(rs.getBigDecimal("pTotalDue").toPlainString());//Assuming your select returns a pTotalDue Column (e.g. SELECT pTotalDue,... FROM ...)
Try to Use an TableCellRenderer.
Implement the Renderer and render the Column with the Money Type in the form you wish.
Regards,
HL
Here's my code:
private void show(java.awt.event.ActionEvent evt) {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/";
String dbName = "phone";
String driver = "com.mysql.jdbc.Driver";
String userName = "root";
String password = "school";
try {
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url + dbName, userName, password);
PreparedStatement pStmt = conn.prepareStatement("SELECT * FROM contacts");
ResultSet rs = pStmt.executeQuery();
JFrame frame1 = new JFrame();
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setSize(300, 150);
frame1.setVisible(true);
while (rs.next() == true) {
Object rowData[][] = {{"Name"},
{"Phone"}};
Object columnNames[] = {"Column One", "Column Two"};
JTable table = new JTable(rowData, columnNames);
JScrollPane scrollPane = new JScrollPane(table);
frame1.add(scrollPane, BorderLayout.CENTER);
}
rs.close();
pStmt.close();
conn.close();
} catch (Exception ex) {
System.out.println(ex);
}
}
I want to display the record in a separate window but its showing a blank screen. Any corrections suggested?
Vector columnNames = new Vector();
Vector data = new Vector();
try{
Connection conn = null;
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
conn = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:XE","yedal ","yedal121288");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("");
ResultSetMetaData meta=rs.getMetaData();
int columns = meta.getColumnCount();
for (int i = 1; i <= columns; i++)
{
columnNames.addElement( meta.getColumnName(i) );
}
while (rs.next())
{
Vector row = new Vector(columns);
for (int i = 1; i <= columns; i++)
{
row.addElement( rs.getObject(i) );
}
data.addElement( row );
}
rs.close();
stmt.close();
}
catch (SQLException ex) {
ex.printStackTrace();
}
t= new JTable(data, columnNames); t.setVisible(true);
TableColumn col;
for (int i = 0; i < t.getColumnCount(); i++)
{
col = t.getColumnModel().getColumn(i);
col.setMaxWidth(200);
}
JScrollPane scrollPane = new JScrollPane(t);
You're creating multiple JTables in your while loop, I assume that's not what you're intending to do, and also you don't give them size. you must set the size of JTable with setPreferredSize or setSize method:
tblObj.setPreferredSize(new Dimension(300,400));
also you pass true to setFillsViewportHeight method for your table content to fill the view port.
Here's a link on how to use JTable:
How To Use JTable
I suppose you see an exception java.lang.ArrayIndexOutOfBoundsException if you look into your console. The JTable is populated with a table model which has two columns but you construct it with an array with data of only one.
Please note since you set the frame to visible before this exception occurs, the frame is shown, the component is added to it but when swing tries to paint it it will fail.
If you replace your test data with e.g.
Object rowData[][] = { { "Name", "Phone" }, { "Name2", "Phone2" } };
it'll work (unless rs.next() is never true).
it is better to use a library file rs2xml.jar .
include it into ur library
first create a connection with the database using jdbc.
import this --> import net.proteanit.sql.DbUtils;
String query ="select * from employee"; //let
pst = conn.prepareStatement(query);
rs = pst.executeQuery();
s.append (QueryArea.getText()).append("\n");
jTable.setModel(DbUtils.resultSetToTableModel(rs));
There will be an exception thrown in this ,so handle it by a try catch statement.
if any problem with this u can ask.