I am trying to get data from a database and display them into a JTable in Java.
Now I have a working code which does retrieve the data and displays it in the table but somehow it does not display the first column. Anybody an idea?
Here my code:
stmt = con.createStatement();
rs = stmt.executeQuery(Query);
while (table.getRowCount() > 0) {
((DefaultTableModel) table.getModel()).removeRow(0);
}
int columns = rs.getMetaData().getColumnCount();
while (rs.next()) {
Object[] row = new Object[columns];
for (int i = 1; i <= columns; i++) {
row[i-1] = rs.getObject(i);
}
((DefaultTableModel) table.getModel()).insertRow(rs.getRow() - 1, row);
}
rs.close();
stmt.close();
con.close();
UPDATE
Ok I tried using Vector and it happens the same thing. My database has the following columns: ID, Subject, AS1, AS2
Now I do get the data displayed in the JTable, but the order of my row data always starts with the Subject column first, then AS1, then AS2 and last ID.
Why is this happening?
I have found a way around it by creating another Object[] and assigning the last object from the first array to the first of array two.
while (rs.next()) {
Object[] row = new Object[columns];
for (int i = 1; i <= columns; i++) {
row[i-1] = rs.getObject(i);
}
Object sub = row[0];
Object ses = row[1];
Object as1 = row[2];
Object as2 = row[3];
Object as3 = row[4];
Object fe = row[5];
Object id = row[6];
Object[] row2 = new Object[columns];
row2[0] = id;
row2[1] = sub;
row2[2] = ses;
row2[3] = as1;
row2[4] = as2;
row2[5] = as3;
row2[6] = fe;
((DefaultTableModel) table.getModel()).insertRow(rs.getRow() - 1, row2);
}
Not beautiful but it gets the job done.
Related
How would I append an Object[][] to another Object[][]?
I have created Object dhadj[][] = new Object[0][6], which I've initialized to 0 because I don't know the number of rows, but I do know the number of columns.
In a loop I create another Object[][] called dha, and search for some data in the database. My intention is, at the end of every loop I want to add dha to dhadj using an append function. However, I get an error; there is a problem with converting array to object return (Object[][]) with temp.toArray().
What can I do to fix this? Is there another approach?
Here is my code:
Object dhadj[][] = new Object[0][6];
v = vector;
ro = size;
for (int i = 0; i < ro; i++) {
int d;
d = Integer.valueOf(v[i]);
query = "SELECT * FROM hadj WHERE id=?";
try (PreparedStatement preparedStatement = c.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY)) {
preparedStatement.setInt(1, d);
ResultSet rs = preparedStatement.executeQuery();
if (rs != null) {
rs.last();
int siz = rs.getRow();
rs.beforeFirst();
ResultSetMetaData rsMeta = rs.getMetaData();
int a = 0;
Object dha[][] = new String[siz][6]; //the neew object dha
while (rs.next()) {
dha[a][0] = rs.getString("id");
dha[a][1] = rs.getString("idh");
dha[a][2] = rs.getString("ticket");
dha[a][3] = rs.getString("montant");
dha[a][4] = rs.getString("datei");
dha[a][5] = rs.getString("nombrep");
a = a + 1;
}//end while
dhadj = appendValue(dhadj, dha); //here I add it using fuction
} else {
dhadj[0][0] = Integer.toString(d);
for (int ii = 1; ii < 6; ii++) {
dhadj[0][ii] = "";
}
}
}//end try
}//end for v
This is the function I'm using to append the arrays together:
private Object[][] appendValue(Object[][] obj, Object[][] newObj) {
ArrayList<Object> temp = new ArrayList<Object>(Arrays.asList(obj));
temp.add(newObj);
return (Object[][]) temp.toArray();
} //end appendvalue
If you don't know the number of elements, you should be using a List. I'd go with an ArrayList or an ArrayDeque:
List<Object[]> results = new ArrayList<>();
Object[] set = new Object[6];
Once you've finished creating your Object[] with the 6 results, call results.add(set);
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.
I used this code to get values from database but can get only one record but I want to put all records in to the combobox.
My code is:
try {
stm = db.con.createStatement();
rs = stm.executeQuery("select code from accounts");
while (rs.next()) {
for (int i = 1; i <= 5; i++) {
ol = rs.getObject(i);
}
}
} catch (SQLException sqlException) {
}
ObservableList<Object> options = FXCollections.observableArrayList(ol);
final ComboBox code = new ComboBox();
code.getItems().addAll(options);
The problem appears to be that your variable ol simply contains the last object that you extracted from the ResultsSet. It appears what you intended to do was something like the following:
ArrayList<Object> ol = new ArrayList<Object>();
while (rs.next()) {
for (int i = 1; i <= 5; i++) {
ol.add(rs.getObject(i));
}
}
I am not sure if this does exactly what you want, but hopefully this demonstrates why you are only getting one object in your combo box.
How to display ResultSet in JTable. i am using this code
String [] record= new
String[ColCount];
for (i=0; i<ColCount; i++)
{
record[i]=rset1.getString(i+1);
}
cell[i] = rset1.getString("loginname");
cell[i] = rset1.getString( "role");
System.out.println(cell[i][0]);
//ItemGroup = rset1.getString( "Status");
}
System.out.println(ItemCode);
JTable jt = new JTable(
cell[i], headers);
but I get only one row which is lastly inserted to database.
You need to put a while loop around your code to iterate over the result set. eg,
while(rset1.next())
{
//do something
}
The code that you have listed is incomplete/incomprehensible, but the code below shows how to take a ResultSet with an arbitrary number of columns and display its contents in a JTable.
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
private void viewTable(){
//Perform database query here, which will open a Connection to the database
//Assume we use the above query to populate a ResultSet results
//Get information about the ResultSet
ResultSetMetaData metaData = results.getMetaData();
//Gets the number of columns in results
int columnCount = metaData.getColumnCount();
//Gets the name of each column in results
String[] columnNames = new String[columnCount];
for(int i = 0; i < columnNames.length; i++){
columnNames[i] = metaData.getColumnLabel(i+1);
}
//You can use a String[] to keep track of the rows if you know the #
//# of rows in the ResultSet, this implementation assumes that we don't
//This ArrayList will keep track of each row in results (each row is
//represented by a String[]
ArrayList<String[]> rows = new ArrayList<>();
while(results.next()){
//Fetch each row from the ResultSet, and add to ArrayList of rows
String[] currentRow = new String[columnCount];
for(int i = 0; i < columnCount; i++){
//Again, note that ResultSet column indecies start at 1
currentRow[i] = results.getString(i+1);
}
rows.add(currentRow);
}
//Close Connection to the database here
String[][] rowsArray = new String[rows.size()][columnCount];
rowsArray = rows.toArray(rowsArray);
table = new JTable(rowsArray, columnNames);
}