I successfully managed to populate jtable from an MS Access database using UcanAccess library.
What I want is to populate jtable from two databases. I have two databases, one contains table with four columns, the other contain three columns.
I want to populate jtable with seven columns from the two databases.
Code used :
public void PopulateJtable(JTable table, String table_name) {
String sql = "SELECT * from " + table_name;
DefaultTableModel dtm = (DefaultTableModel) table.getModel();
dtm.setRowCount(0);
try {
conn = DriverManager.getConnection(myDB);
state = conn.createStatement();
state.execute(sql);
ResultSet rs = state.getResultSet();
int columns = table.getColumnCount();
Vector vector = new Vector();
while (rs.next()) {
Vector row = new Vector();
for (int i = 1; i <= columns; i++) {
row.addElement(rs.getObject(i));
}
dtm.addRow(row);
}
} catch (SQLException e) {
JOptionPane.showMessageDialog(null, e, "ERROR !! ", 0);
} finally {
try {
state.close();
conn.close();
} catch (SQLException ex) {
Logger.getLogger(DBEngine.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
MS Access DB Tables :
table1
table2
i want to join above tables cols in one jtable
Related
I am trying to populate a java database with car brands, models, and if they are available but I have a big issue. When I enter multiple cars to the table, the new car prints to the table, but previous cars I have entered also reprint
[Issue.png][1]. So first I entered Ferrari Enzo, then I entered Tesla S but Ferrari Enzo is repeating.
I know the issue is not with adding the cars to the database because if I look in the database it only shows the two I entered [DatabasePic.png][2]. I know my problem is with how I am entering my cars into the JTable. My methods are below..
ButtonClickEvent:
private void refreshbtnMouseClicked(java.awt.event.MouseEvent evt) {
try {
String Brand = brandlbl.getText();
String Model = modellbl.getText();
Boolean Available = false;
switch (availabilitybox.getSelectedItem().toString()) {
case "True":
Available = true;
break;
case "False":
Available = false;
break;
}
InsertApp nw = new InsertApp();
nw.insert(Brand, Model, Available);
nw.refreshDatabase(jTable1);
} catch (SQLException ex) {
Logger.getLogger(Window.class.getName()).log(Level.SEVERE, null, ex);
}
}
Insert Method:
public void insert(String brand, String model, Boolean available) {
String sql = "INSERT INTO CARDATA(brand,model,available) VALUES(?,?,?)";
try (Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, brand);
pstmt.setString(2, model);
pstmt.setBoolean(3, available);
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
Refreshing my database:
public void refreshDatabase(JTable table) throws SQLException {
Connection con = connect();
String SQL = "SELECT * FROM CARDATA";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(SQL);
int col = rs.getMetaData().getColumnCount();
System.out.println(col);
while (rs.next()) {
Object[] rows = new Object[col];
for (int i = 1; i <= col; i++) {
rows[i - 1] = rs.getObject(i);
}
((DefaultTableModel) table.getModel()).insertRow(rs.getRow() - 1, rows);
}
con.close();
rs.close();
stmt.close();
}
When I enter multiple cars to the table, the new car prints to the table, but previous cars I have entered also reprint
You need to clear the data in the TableModel before you start adding data back into it.
The basic code should be something like:
DefaultTableModel model = (DefaultTableModel)table.getModel();
model.setRowCount(0);
while (rs.next())
{
...
model.addRow(...);
}
Or instead of retrieving all the data from the database every time you do an insert, just add the data to the table at the same time:
pstmt.executeUpdate();
model.addRow(...);
I am running a query on ID column but I don't want it to be visible in my frame/pane. How can I achieve this? Shall I make another table, is there a function in sql/mysql which allows to hide columns? I tried to google it but havent found anything yet.
Here is the code:
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int col = e.getColumn();
model = (MyTableModel) e.getSource();
String stulpPav = model.getColumnName(col);
Object data = model.getValueAt(row, col);
Object studId = model.getValueAt(row, 0);
System.out.println("tableChanded works");
try {
new ImportData(stulpPav, data, studId);
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
public class ImportData {
Connection connection = TableWithBottomLine.getConnection();
public ImportData(String a, Object b, Object c)
throws ClassNotFoundException, SQLException {
Statement stmt = null;
try {
String stulpPav = a;
String duom = b.toString();
String studId = c.toString();
System.out.println(duom);
connection.setAutoCommit(false);
stmt = connection.createStatement();
stmt.addBatch("update finance.fin set " + stulpPav + " = " + duom
+ " where ID = " + studId + ";");
stmt.executeBatch();
connection.commit();
} catch (BatchUpdateException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (stmt != null)
stmt.close();
connection.setAutoCommit(true);
System.out.println("Data was imported to database");
}
}
}
public class MyTableModel extends AbstractTableModel{
int rowCount;
Object data [][];
String columnNames [];
public MyTableModel() throws SQLException{
String query ="SELECT ID, tbl_Date as Date, Flat, Mobile, Food, Alcohol, Transport, Outdoor, Pauls_stuff, Income, Stuff FROM finance.fin";
ResultSet rs ;
Connection connection = TableWithBottomLine.getConnection();
Statement stmt = null;
stmt = connection.createStatement();
rs = stmt.executeQuery(query);
rs.last();
rowCount = rs.getRow();
data = new Object[rowCount][11];
rs = stmt.executeQuery(query);
for (int iEil = 0; iEil < rowCount; iEil++){
rs.next();
data[iEil][0] = rs.getInt("ID");
data[iEil][1] = rs.getDate("Date");
data[iEil][2] = rs.getFloat("Flat");
data[iEil][3] = rs.getFloat("Mobile");
data[iEil][4] = rs.getFloat("Food");
data[iEil][5] = rs.getFloat("Alcohol");
data[iEil][6] = rs.getFloat("Transport");
data[iEil][7] = rs.getFloat("Outdoor");
data[iEil][8] = rs.getFloat("Pauls_stuff");
data[iEil][9] = rs.getFloat("Income");
data[iEil][10] = rs.getFloat("Stuff");
}
String[] columnName = {"ID", "Date","Flat","Mobile"
,"Food","Alcohol","Transport", "Outdoor", "Pauls_stuff", "Income", "Stuff"};
columnNames = columnName;
}
This has solved my problem:
table.removeColumn(table.getColumnModel().getColumn(0));
I placed this in my class contructor. This lets remove the column from the view of the table but column 'ID' is still contained in the TableModel. I found that many people looking for an option to exclude specific column (like autoincrement) from SELECT statement in sql / mysql but the language itself doesn't have that feature. So I hope this solution will help others as well.
Don't put ID in the select part of the query
String query ="SELECT tbl_Date as Date, Flat, Mobile, Food, Alcohol, Transport,
Outdoor, Pauls_stuff, Income, Stuff FROM finance.fin";
How to display MySQL data in JTable without using vector?
I'm doing Java Swing application and I want to show reports from database. I'm using JTable to display data from database. I have tried following code but it is not displaying data from database. My database connection is also correct.
int i;
static Vector<Vector<String>> data = new Vector<Vector<String>>();
String[] columnNames = {"Registration id", "First Name", "Middle Name", "Last Name", "Address", "Dob", "Age", "Date Of Registration", "Register Rfid No."};
public AdmissionReport()
{
initComponents();
//this is the model which contain actual body of JTable
DefaultTableModel model = new DefaultTableModel();
model.setColumnIdentifiers(columnNames);
//jTable1=new JTable(model);
jTable1 = new JTable();
jTable1.setModel(model);
int i1 = jTable1.getRowCount();
if (i1 > 1) {
model.removeRow(0);
i1 = i1 - 1;
}
String str = "select rid,fname,mname,lname,address,dob,age,dor,rfidtagdata from schoolrfid.registration";
Connection cn;
ResultSet rs;
Statement st;
String rid, fname, mname, lname, add, dob, age, dor, rfidtag;
try {
// Change the database name, hosty name,
// port and password as per MySQL installed in your PC.
cn = DriverManager.getConnection("jdbc:mysql://" + "localhost:3306/schoolrfid", "root", "root");
st = cn.createStatement();
rs = st.executeQuery(str);
System.out.println("connected to database.. ");
// int i=0;
while (rs.next()) {
//Vector <String> d=new Vector<String>();
rid = (rs.getString("rid"));
fname = (rs.getString("fname"));
mname = (rs.getString("mname"));
lname = (rs.getString("lname"));
add = (rs.getString("address"));
dob = (rs.getString("dob"));
age = (rs.getString("age"));
dor = (rs.getString("dor"));
rfidtag = (rs.getString("rfidtagdata"));
i = 0;
String[] data = {rid, fname, mname, lname, add, dob, age, dor, rfidtag};
model.addRow(data);
i++;
}
if (i < 1) {
JOptionPane.showMessageDialog(null, "No Record Found", "Error", JOptionPane.ERROR_MESSAGE);
}
if (i == 1) {
System.out.println(i + " Record Found");
} else {
System.out.println(i + " Records Found");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
The TableModel behind the JTable handles all of the data behind the table. In order to add and remove rows from a table, you need to use a DefaultTableModel
To create the table with this model:
JTable table = new JTable(new DefaultTableModel(new Object[]{"Column1", "Column2"}));
To add a row:
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.addRow(new Object[]{"Column 1", "Column 2", "Column 3"});
You can also remove rows by removeRow(int row) which will removes the row at row from the model.
Full details on the DefaultTableModel can be found here
Similarly from the MySQL you can add rows like as show below
DefaultTableModel memberTable = (DefaultTableModel) table.getModel();
while(rs.next())
{
memberTable.addRow(new Object[]{rs.getString('rid'),rs.getString('fname'),rs.getString('lname'),rs.getString('address'),.....});
}
Also Take a look at this answer
https://stackoverflow.com/a/17655017/1575570
As mentioned in the header I cannot get my JTable to update with a new row unless I restart the program. When I restart, the new row is there and everything is as it should be. I have tried revalidating/repainting the panel and frame, I have tried the fire methods. I'm at a loss. Thanks in advance
ActionListener (in adminGUI class) for 'Add' button:
if(source.equals(add2)){
String c = itb.getText();
int a = main.getResults();
boolean matches = Pattern.matches("[A-Z][a-z]+", c);
if(matches == true){
main.addGenre(a, c);
}
String Method(in main class) to add a row to the database table:
public static void addGenre(int a, String b){
int rowsAdded;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection connect =DriverManager.getConnection("jdbc:odbc:MovieDB");
Statement stmt = connect.createStatement();
String query = "INSERT INTO Genres (genre_id, genre_name)" + "VALUES(" + a + ", '" + b + "')";
rowsAdded = stmt.executeUpdate(query);
}catch(Exception exc){}
}
Method(also in main class) to increment the auto-increment-key column:
public static int getResults(){
int a = 0;
ResultSet ints = main.getResults("Select genre_id from Genres");
try {
while(ints.next()){
int d = ints.getInt("genre_id");
if(d>a){
a = d;
}
a++;
}
} catch (SQLException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
return a;
}
JTable details:
ResultSet rs1 = main.getResults("Select * from Genres");
JTable tab1 = new JTable(DbUtils.resultSetToTableModel(rs1));
DbUtils.resultSetToTableModel details :
public class DbUtils {
public static TableModel resultSetToTableModel(ResultSet rs) {
try {
ResultSetMetaData metaData = rs.getMetaData();
int numberOfColumns = metaData.getColumnCount();
Vector columnNames = new Vector();
// Get the column names
for (int column = 0; column < numberOfColumns; column++) {
columnNames.addElement(metaData.getColumnLabel(column + 1));
}
// Get all rows.
Vector rows = new Vector();
while (rs.next()) {
Vector newRow = new Vector();
for (int i = 1; i <= numberOfColumns; i++) {
newRow.addElement(rs.getObject(i));
}
rows.addElement(newRow);
}
return new DefaultTableModel(rows, columnNames);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
"I cannot get my JTable to update with a new row unless I restart the program."
I think what you're expecting is that when the database table update, so should your JTable. It doesn't really work like that. You need to update the TableModel, and the JTable will be automatically updated
Since resultSetToTableModel returns a DefuaultTableModel, you can use either of the two methods from DefaultTableModel:
public void addRow(Object[] rowData) - Adds a row to the end of the model. The new row will contain null values unless rowData is specified. Notification of the row being added will be generated.
public void addRow(Vector rowData) - Adds a row to the end of the model. The new row will contain null values unless rowData is specified. Notification of the row being added will be generated.
So when your are adding the data to the database, you also want to update the DefaultTableModel like this
public static void addGenre(Integer a, String b){
...
rowsAdded = stmt.executeUpdate(query);
if (rowsAdded > 0) {
DefaultTableModel model = (DefaultTableModel)tab1.getModel();
model.addRow( new Object[] { a, b });
}
}
Also noticed I changed the method signature to Integer instead of int so it will fit with the Object[] passed to addRow. The int you pass to it will get autoboxed to Integer
SIDE NOTES
Don't swallow you exception by putting nothing in the catch block. Put something meaningful that will notify you of any exceptions that may occur, like
catch(Exception ex) {
ex.printStackTrace();
}
You should also close your Connections, Statements, and ResultSets
You should use PreparedStatement instead of Statement, to avoid SQL injection.
private void resetListData() throws ClassNotFoundException, SQLException
{
Connection cne = null;
try {
Class.forName("org.sqlite.JDBC");
cne = DriverManager.getConnection("jdbc:sqlite:table.sqlite");
cne.setAutoCommit(false);
PreparedStatement psd = (PreparedStatement) cne.prepareStatement("Select * from Genres");
psd.execute();
ResultSet r = psd.getResultSet();
ResultSetMetaData rsmd = r.getMetaData();
int count = rsmd.getColumnCount();
String[] meta = new String[count];
for (int i = 0; i < count; i++)
{
String name = rsmd.getColumnName(i + 1);
meta[i] = name;
//System.out.println(name);
}
model = new DefaultTableModel(new Object[][]{}, new String[]{"name", "address"});
jTable1.setModel(model);
while (r.next())
{
Object[] row = new Object[count];
for (int i = 1; i <= count; ++i)
{
row[i - 1] = r.getString(i); // Or even rs.getObject()
}
model.addRow(row);
}
cne.close();
} catch (ClassNotFoundException | SQLException e) {
}
}
Use this code. so you can insert one row at the end of Jtable without restarting application.,
Thanks..
I need to fill a Swing table with some data from MySQL DB. The problem is that the table does not display all the columns (i.e. a.aircraftType and b.aircraftCategory). In Debug mode I checked that the query returns correct data. So, why finally some columns are not displayed?
private JTable tbArrivals;
private QueryTableModelFS mdArrivals;
mdArrivals = new QueryTableModelFS();
tbArrivals = new JTable(mdArrivals);
private void fillArrivals() {
mdArrivals.setHost(url); mdArrivals.setDB(db); mdArrivals.setLogin(login); mdArrivals.setPassw(passw);
String query;
query = "SELECT a.id,a.flightNum_arr,a.from_ICAO,a.ETA,a.pkId,a.aircraftType,b.aircraftCategory " +
"FROM flightschedule a, aircrafts b " +
"WHERE a.aircraftType = b.aircraftType;";
mdArrivals.setQuery(query);
}
public void setQuery(String query) {
cache = new Vector();
try {
// Execute the query and store the result set and its metadata
Connection con = getConnection();
Statement statement = con.createStatement();
ResultSet rs = statement.executeQuery(query);
ResultSetMetaData meta = rs.getMetaData();
colCount = meta.getColumnCount();
// Rebuild the headers array with the new column names
headers = new String[colCount];
for (int h = 1; h <= colCount; h++) {
headers[h - 1] = meta.getColumnName(h);
}
while (rs.next()) {
String[] record = new String[colCount];
for (int i = 0; i < colCount; i++) {
record[i] = rs.getString(i + 1);
}
cache.addElement(record);
}
fireTableChanged(null);
rs.close();
if (con.getAutoCommit() != false) {
con.close();
}
} catch (Exception e) {
cache = new Vector();
e.printStackTrace();
}
}
I can't tell what how your TableModel works (it looks like you might be using the DefaultTableModel), but I would suggest using Vectors instead of Arrays to get the data from your ResultSet. Right now your code is very confusing. In one loop you are using (i - 1) to access the data. In the next loop you are using (i + 1). I know the reason is because Arrays are 0 based and the ResultSet is 1 based.
When you use a Vector your loops can just start with 1 and then you just use the addElement() method to add the data to the Vector so your code is not concerned with matching indexes.
See Table From Database Example in Table From Database.