i have a table in the database of 4rows and 4columns. each column holds a different data.
now i want to retrieve all the data in the database and put them on JLabel on another form. i.e
in my Database i have.
packageName.....monthlyFee..... YearlyFee....... TotalFee
Regular......................150..................300....................450
Gold.........................300...................400..................700
..... ..... .... ....
now i have a form that i have put 4 empty JLabels in four rows but how do i retrieve the values from the database and place each value in the appropriate Label?.
This is what i've done but i still cant get around it. im stuck.
Thank you anyone.
public void getPrices()
{
String srt ="SELECT * FROM program_tbl";
try
{
con.connect();
ps = con.con.prepareStatement(srt);
rs = ps.executeQuery();
ResultSetMetaData data = rs.getMetaData();
int colums = data.getColumnCount();
while(rs.next())
{
Vector rows = new Vector();
for (int i = 1; i < colums; i++)
{
rows.addElement(rs.getObject(i));
}
.....................................................................
If you want to get this data as a string then you could probably try something like:
Vector<String> rows = new Vector<String>();
while(rs.next()) {
String rowEntry = rs.getString("packageName") +
rs.getString("monthlyFee") +
rs.getString("yearlyFee") +
rs.getString("totalFee") +
rows.add(rowEntry);
}
If not String, but an object to use later, then you can create a class:
public class MyObject {
private String packageName;
private int monthlyFee;
private int yearlyFee;
private int totalFee;
public MyObject (String name, int monthlyFee, int yearlyFee, int totalFee) {
this.packageName = name;
this.monthlyFee = monthlyFee;
this.yearlyFee = yearlyFee;
this.totalFee = totalFee;
}
/*Setters
*And
*Getters*/
}
And then use it as:
Vector<MyObject> rows = new Vector<MyObject>();
while (rs.next()) {
MyObject obj = new MyObject(rs.getString("packageName")
, rs.getInt("montlyFee")
, rs.getInt("yearlyFee")
, rs.getInt("totalFee")
);
rows.add(obj)
}
So say we now have a vector with String values - Vector<String> rows;
now i would like to create those JLabels.
JLabel[] myLabels = new JLabel[v.size()];
for(int i=0; i<rows.size(); i++) {
as[i] = new JLabel(rows.get(i));
}
And now we have an array of JLabels ready to be put to applet.
Don't use a JLabel. There is no way you can easily format the data so that you get tabular data.
Instead you should be using a JTable. Read the section from the Swing tutorial on How to Use Tables for more information. You can also search the forum for examples of using a JTable with a ResultSet.
Related
I want to get table label of column .like string display in mysql. Like this
However, when I use getColumnName, It turn out there is some difference between returned string and below string. Like this:
But It is right in Variables explorer in eclipse when I debug, Like this:
I can't find other way to get column. It seem returned string is originalColumnName, but how to get ColumnName? Anyone know how to fix it?
There is my code, I know there is other problem in code. Please just assume the type of all column is String.
public ResultSet DisplayShowTables() throws SQLException
{
ResultSet Res = Sta.executeQuery("DESC Code2Name");
ResultSetMetaData ResMeta = Res.getMetaData();
String [] ColumnName = new String [ResMeta.getColumnCount()];
int MetaCount = ResMeta.getColumnCount();
for (int i = 0; i < MetaCount; i++) {
ColumnName [i] = ResMeta.getColumnName(i+1);
}
String LeftAlignFormat = "|";
String Separator = "+";
for (int i = 0; i < MetaCount; i++) {
LeftAlignFormat = LeftAlignFormat.concat(" %-20s |");
Separator =Separator.concat("----------------------+");
}
LeftAlignFormat = LeftAlignFormat.concat("%n");
Separator = Separator.concat("%n");
if(Res.isBeforeFirst()){
System.out.format(Separator);
System.out.format(LeftAlignFormat, ColumnName);
System.out.format(Separator);
}
while (Res.next()) {
Vector<String> RowData = new Vector<String>();
for (int i = 0; i < MetaCount; i++) {
RowData.add(Res.getString(i+1).toString());
}
System.out.format(LeftAlignFormat, RowData);
}
if(Res.isAfterLast())
System.out.format(Separator);
return Res;
}
It looks like DESC is just a shortcut for a query of the information schema with aliases for the columns.
Column aliases can be retrieved with ResultSetMetadata.getColumnLabel(int).
JDBC defines column label as:
Gets the designated column's suggested title for use in printouts and displays. The suggested title is usually specified by the SQL AS clause. If a SQL AS is not specified, the value returned from getColumnLabel will be the same as the value returned by the getColumnName method.
This also means that in almost all situation you should be using getColumnLabel instead of getColumnName.
This is actually a re-do of an older question of mine that I have completely redone because my old question seemed to confuse people.
I have written a Java program that Queries a database and is intended to retrieve several rows of data. I have previously written the program in Informix-4GL and I am using a sql cursor to loop through the database and store each row into a "dynamic row of record". I understand there are no row of records in Java so I have ended up with the following code.
public class Main {
// DB CONNECT VARIABLE ===========================
static Connection gv_conn = null;
// PREPARED STATEMENT VARIABLES ==================
static PreparedStatement users_sel = null;
static ResultSet users_curs = null;
static PreparedStatement uinfo_sel = null;
static ResultSet uinfo_curs = null;
// MAIN PROGRAM START ============================
public static void main(String[] args) {
try {
// CONNECT TO DATABASE CODE
} catch(Exception log) {
// YOU FAILED CODE
}
f_prepare(); // PREPARE THE STATEMENTS
ArrayList<Integer> list_id = new ArrayList<Integer>();
ArrayList<String> list_name = new ArrayList<String>();
ArrayList<Integer> list_info = new ArrayList<String>();
ArrayList<String> list_extra = new ArrayList<String>();
try {
users_sel.setInt(1, 1);
users_curs = users_sel.executeQuery();
// RETRIEVE ROWS FROM USERS
while (users_curs.next()) {
int lv_u_id = users_curs.getInt("u_id");
String lv_u_name = users_curs.getString("u_name");
uinfo_sel.setInt(1, lv_u_id);
uinfo_curs = uinfo_sel.executeQuery();
// RETRIEVE DATA FROM UINFO RELATIVE TO USER
String lv_ui_info = uinfo_curs.getString("ui_info");
String lv_ui_extra = uinfo_curs.getString("ui_extra");
// STORE DATA I WANT IN THESE ARRAYS
list_id.add(lv_u_id);
list_name.add(lv_u_name);
list_info.add(lv_ui_info);
list_extra.add(lv_ui_extra);
}
} catch(SQLException log) {
// EVERYTHING BROKE
}
// MAKING SURE IT WORKED
System.out.println(
list_id.get(0) +
list_name.get(0) +
list_info.get(0) +
list_extra.get(0)
);
// TESTING WITH ARBITRARY ROWS
System.out.println(
list_id.get(2) +
list_name.get(5) +
list_info.get(9) +
list_extra.get(14)
);
}
// PREPARE STATEMENTS SEPARATELY =================
public static void f_prepare() {
String lv_sql = null;
try {
lv_sql = "select * from users where u_id >= ?"
users_sel = gv_conn.prepareStatement(lv_sql);
lv_sql = "select * from uinfo where ui_u_id = ?"
uinfo_sel = gv_conn.prepareStatement(lv_sql)
} catch(SQLException log) {
// IT WON'T FAIL COZ I BELIEEEVE
}
}
}
class DBConn {
// connect to SQLite3 code
}
All in all this code works, I can hit the database once, get all the data I need, store it in variables and work with them as I please however this does not feel right and I think it's far from the most suited way to do this in Java considering I can do it with only 15 lines of code in Informix-4GL.
Can anyone give me advice on a better way to achieve a similar result?
In order to use Java effectively you need to use custom objects. What you have here is a lot of static methods inside a class. It seems that you are coming from a procedural background and if you try to use Java as a procedural language, you will not much value from using it. So first off create a type, you can plop it right inside your class or create it as a separate file:
class User
{
final int id;
final String name;
final String info;
final String extra;
User(int id, String name, String info, String extra)
{
this.id = id;
this.name = name;
this.info = info;
this.name = name;
}
void print()
{
System.out.println(id + name + info + extra);
}
}
Then the loop becomes:
List<User> list = new ArrayList<User>();
try {
users_sel.setInt(1, 1);
users_curs = users_sel.executeQuery();
// RETRIEVE ROWS FROM USERS
while (users_curs.next()) {
int lv_u_id = users_curs.getInt("u_id");
String lv_u_name = users_curs.getString("u_name");
uinfo_sel.setInt(1, lv_u_id);
uinfo_curs = uinfo_sel.executeQuery();
// RETRIEVE DATA FROM UINFO RELATIVE TO USER
String lv_ui_info = uinfo_curs.getString("ui_info");
String lv_ui_extra = uinfo_curs.getString("ui_extra");
User user = new User(lv_u_id, lv_u_name, lv_ui_info, lv_ui_extra);
// STORE DATA
list.add(user);
}
} catch(SQLException log) {
// EVERYTHING BROKE
}
// MAKING SURE IT WORKED
list.get(0).print();
This doesn't necessarily address the number of lines. Most people who use Java don't interact with databases with this low-level API but in general, if you are looking to get down to the fewest number of lines (a questionable goal) Java isn't going to be your best choice.
Your code is actually quite close to box stock JDBC.
The distinction is that in Java, rather than having a discrete collection of arrays per field, we'd have a simple Java Bean, and a collection of that.
Some examples:
public class ListItem {
Integer id;
String name;
Integer info;
String extra;
… constructors and setters/getters ellided …
}
List<ListItems> items = new ArrayList<>();
…
while(curs.next()) {
ListItem item = new ListItem();
item.setId(curs.getInt(1));
item.setName(curs.getString(2));
item.setInfo(curs.getInfo(3));
item.setExtra(curs.getString(4));
items.add(item);
}
This is more idiomatic, and of course does not touch on the several frameworks and libraries available to make DB access a bit easier.
Adding the colums works, but i am stuck when i want to add the data of the columns stored in a mysql database to the jtable. it ask for a object vector[][] but i have no clue what to give
Connection con;
DefaultTableModel model = new DefaultTableModel();
public Hoofdscherm() {
initComponents();
uitvoerSpelers.setModel(model);
try {
con = DriverManager.getConnection("jdbc:mysql://localhost/fullhouse", "root", "hamchi50985");
// selecteer gegevens uit fullhouse.speler tabel
PreparedStatement stat = con.prepareStatement("SELECT * FROM fullhouse.speler");
// sla deze GEGEVENS op in een resultset
ResultSet resultaat = stat.executeQuery();
// haal alle kolomnamen op PUUR VOOR DE MODEL VAN JTABLE
ResultSetMetaData data = resultaat.getMetaData();
String[] colum = new String[15];
for (int i = 1; i < data.getColumnCount(); i++) {
colum[i] = data.getColumnName(i);
model.addColumn(colum[i]);
while (resultaat.next()) {
Object[] gegevens = new String[] {resultaat.getString(1)};
model.addRow(gegevens[0]);
}
}
} catch (SQLException ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
I think you need something like this.
Note
1. Also add your columns separate to resultset data. Like I showed in my code below.
Vector<String> rowOne = new Vector<String>();
rowOne.addElement("R1C1");
rowOne.addElement("R1C2");
Vector<String> rowTwo = new Vector<String>();
rowTwo.addElement("R2C1");
rowTwo.addElement("R2C2");
Vector<String> cols = new Vector<String>();
Vector<Vector> vecRow = new Vector<Vector>();
vecRow.addElement(rowOne);
vecRow.addElement(rowTwo);
cols.addElement("Col1");
cols.addElement("Col2");
JTable table = new JTable(vecRow, cols);
Edit
For you convenience and requirement You can follow code structure below.
Vector<String> rows = new Vector<String>();
Vector<Vector> dBdata = new Vector<Vector>();
// Add Columns to table
for (int i = 1; i < data.getColumnCount(); i++) {
colum[i] = data.getColumnName(i);
model.addColumn(colum[i]);
}
while (resultaat.next()) {
// add column data to rows vector
// Make sure that all data type is in string because of generics
rows.add(resultaat.getString("columnName1"));
rows.add(resultaat.getString("columnName2"));
rows.add(resultaat.getString("columnName3"));
// add whole row vector to dBdata vector
dBdata.addElement(rows);
}
model.addRow(dBdata);
Vector implements a dynamic array. It is similar to ArrayList, but with two differences:
Vector is synchronized.
Vector contains many legacy methods that are not part of the collections framework.
Class Vector Javadoc
I hope this will help you.
The line model.addRow(gegevens[0]);is incorrect.
You should do something like this:
String[] colum = new String[15];
for (int i = 1; i < data.getColumnCount(); i++) {
colum[i] = data.getColumnName(i);
model.addColumn(colum[i]);
while (resultaat.next()) {
Object[] gegevens = new String[] {resultaat.getString(1)};
model.addRow(gegevens);
}
}
Also you need to check DefaultTableModel
According to the documentation of DefaultTableModel:
This is an implementation of TableModel that uses a Vector of Vectors
to store the cell value objects.
I'm trying to populate a table with data from a database however i am having some issues with it. Could someone provide me with an example? (so the table takes in an Object[][] parameter for the data). I have the following basic code to display a table ;
class table extends JFrame
{
JTable table;
public table()
{
setLayout(new FlowLayout());
String[] columnNames = {"test","test","test"};
Object[][] data= {{"test","test","test"},{"test","test","test"}};
table = new JTable(data,columnNames);
table.setPreferredScrollableViewportSize(new Dimension(500,100));
table.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
}
}
Two years ago, during my time in technical school, I wrote a little library help solve some of the problems proposed by the exercises, which included a a DatabaseTableModel.
The class extends from AbstractTableModel, which means you can set it as the your JTable's data source.
Here's the algorithm that constructs a model from a ResultSet:
public final void constructModel(ResultSet rs) throws SQLException {
ResultSetMetaData rsmd = rs.getMetaData();
rs.last();
rowCount = rs.getRow();
int columnCount = rsmd.getColumnCount();
// DatabaseColumn simply holds a name and a Class<?>.
columns = new DatabaseColumn[columnCount];
// This is the Object[][] array that you were talking about.
// It holds all the data from the ResultSet.
data = new Object[columnCount][rowCount];
for (int i = 0; i < columnCount; ++i) {
// Figure out the column name and type.
int j = i + 1;
String colName = rsmd.getColumnLabel(j);
Class<?> colClass = String.class;
try {
colClass = Class.forName(rsmd.getColumnClassName(j));
} catch (ClassNotFoundException ex) {
colClass = String.class;
}
columns[i] = new DatabaseColumn(colName, colClass);
// Get the data in the current column as an Object.
rs.beforeFirst();
for (int k = 0; rs.next(); ++k) {
data[i][k] = rs.getObject(j);
}
}
// Notify listeners about the changes so they can update themselves.
fireTableStructureChanged();
}
The class worked when I used it in school, but it isn't exactly production code. When I look at it today, I start to see problems.
One problem is that it is loading the entire contents of the ResultSet into memory. Could get ugly pretty quickly.
Also, the algorithm isn't exactly optimal. It loops around with the database cursor as if it was nothing; I suppose that it would be less costly for the database if it had retrieved all the objects in the current row first and assigned them to their appropriate columns before moving on to the next row.
Nevertheless, I think it is a good enough starting point.
Here is my code, it does get data and paste it in the Text Area as I want it to do, I was just wondering if I could change it so that I could edit how it gets outputted, and add line breaks etc?
btnLeaderBoardUpdate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String sql3 ="Select * from honscores group by Name order by Kills";
ResultSet rsz;
try {
PreparedStatement stz = conn.prepareStatement(sql3);
rsz = stz.executeQuery();
LeaderBoard = rsz.toString();
while(rsz.next()){
ArrayList<String> record = new ArrayList<String>();
ResultSetMetaData metaData = rsz.getMetaData();
int columns = metaData.getColumnCount();
for (int i = 1; i <= columns; i++) {
String value = rsz.getString(i);
record.add(value);
}
for (int i=1;i<columns;i++) {
txtLeaderBoard_1.append(record.toString());
}
}
} catch(Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
});
It sounds like maybe a Java Swing "Listbox" might be a better choice for you than a "TextArea".
You have to add the separators and any decorators to the "rendering" loop. It's independent from the query. (Eg dummy example:)
for (int i=1;i<columns;i++) {
txtLeaderBoard_1.append(record.toString());
txtLeaderBoard_1.append("\n");
}
An other approach is what the others suggested, use a different widget.