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.
Related
Good afternoon guys, i'm trying to learn java programming and then i'm encountering some problem that i don't know why with my code when I'm learning about JTable.
So, what I'm trying to do is when i double clicked the row in JTable named TableGejala, the row that i double clicked will transfered into the other JTable named TableAturan and after that the row that i double clicked in TableGejala will be removed. For the part of transferring row from TableGejala to TableAturan successfully transferred when i double clicked the row, but it doesn't delete the correct row in TableGejala. Instead of deleting the row that i clicked, it delete the row below it.
For more details, this is my code to create TableGejala :
private void getTableGejala() {
while(tabel2.getRowCount() > 0){
for(int i=0;i < tabel2.getRowCount();i++){
tabel2.removeRow(i);
}
}
tabel2.addColumn("ID Gejala");
tabel2.addColumn("Nama Gejala");
TabelGejala.setModel(tabel2);
TabelGejala.setAutoResizeMode(TabelGejala.AUTO_RESIZE_ALL_COLUMNS);
}
And then this is my code to get data for my table from MySQL :
private void loadDataGejala(Boolean baru){
tabel2.getDataVector().removeAllElements();
try {
java.sql.Connection konek = (Connection) Koneksi.KoneksiDB.getConnection();
java.sql.Statement konek_statement = konek.createStatement();
String query_bukaTabel = "";
if(baru){
query_bukaTabel = "select id_gejala,nama_gejala from gejala";
}
else{
String idPkt = FieldID.getText();
query_bukaTabel = "select gejala.id_gejala,gejala.nama_gejala from gejala where gejala.id_gejala not in(select id_gejala from aturan2 where id_penyakit='"+idPkt+"')";
}
java.sql.ResultSet line_result = konek_statement.executeQuery(query_bukaTabel);
while (line_result.next()) {
Object[] getO = new Object[2];
getO[0] = line_result.getString("id_gejala");
getO[1] = line_result.getString("nama_gejala");
tabel2.addRow(getO);
}
line_result.close();
konek_statement.close();
}catch (Exception e) {}
}
This is my code to transfer the row and delete the row :
private void TabelGejalaMousePressed(java.awt.event.MouseEvent evt) {
if (evt.getClickCount()>=2){
int col = 0;
int row = 0;
row = TabelGejala.rowAtPoint(evt.getPoint());
col = TabelGejala.columnAtPoint(evt.getPoint());
String col1 = (String)TabelGejala.getValueAt(row, 0);
String col2 = (String)TabelGejala.getValueAt(row, 1);
DefaultTableModel model = (DefaultTableModel) TabelAturan.getModel();
DefaultTableModel old = (DefaultTableModel) TabelGejala.getModel();
old.removeRow(row);
model.addRow(new Object[]{col1, col2, 0});
TabelAturan.requestFocus();
TabelAturan.setRowSelectionInterval(TabelAturan.getRowCount()-1,TabelAturan.getRowCount()-1);
TabelAturan.editCellAt(TabelAturan.getRowCount()-1,2);
}
}
And this is the screenshot of my problem :
Before Double Clicked
After Double Clicked
Which part that makes my output get the wrong row to be deleted? please help me, and thank you in advance for any helps, even for reading my question :)
Firstly disable cell editable property in your first table(TabelGejala) to ensure proper deleting of row. I achieved this using the following code :-
//instance table model
DefaultTableModel tableModel = new DefaultTableModel(new Object[][]{},
new String[]{
"ID Gejala", "Nama Gejala"
}) {
#Override
public boolean isCellEditable(int row, int column) {
//all cells false
return false;
}
};
TabelGejala.setModel(tableModel);
then use jtable.getselectedrow() and jtable.getselectedcolumn() to get values from table. after addition of desired values to second table, simply delete the selected row. here is the code, derived from your code :-
private void TabelGejalaMousePressed(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
if (evt.getClickCount() >= 2) {
DefaultTableModel model = (DefaultTableModel) TabelAturan.getModel();
DefaultTableModel old = (DefaultTableModel) TabelGejala.getModel();
model.addRow(new Object[]{TabelGejala.getValueAt(TabelGejala.getSelectedRow(), 0), TabelGejala.getValueAt(TabelGejala.getSelectedRow(), 1), 0});
old.removeRow(TabelGejala.getSelectedRow());
TabelAturan.requestFocus();
TabelAturan.setRowSelectionInterval(TabelAturan.getRowCount() - 1, TabelAturan.getRowCount() - 1);
TabelAturan.editCellAt(TabelAturan.getRowCount() - 1, 2);
}
}
I am trying to get a table to populate from my database. I followed a tutorial and my code is displayed below, however I am getting this error and cannot figure out why. In my database I have 'first name, last name, address, city, state, zip' not sure if this info is needed to help me with my question
Could someone please help
thank you in advanced for your help.
package medicalrecords;
import java.awt.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
public class TableFromDatabase extends JPanel {
private Connection conexao = null;
public TableFromDatabase() {
Vector columnNames = new Vector();
Vector data = new Vector();
try {
// Connect to an Access Database
conexao = DriverManager.getConnection("jdbc:derby://" + "localhost"
+ ":1527/Medical Records", "root", "password");
// Read data from a table
String sql = "select * from SD2799.PATIENTRECORDS";
try (Statement stmt = conexao.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
// Get column names
for (int i = 1; i <= columns; i++) {
columnNames.addElement(md.getColumnName(i));
}
// Get row data
while (rs.next()) {
Vector row = new Vector(columns);
for (int i = 1; i <= columns; i++) {
row.addElement(rs.getObject(i));
}
data.addElement(row);
}
}
conexao.close();
} catch (Exception e) {
System.out.println(e);
}
// Create table with database data
JTable table = new JTable(data, columnNames) {
#Override
public Class getColumnClass(int column) {
for (int row = 0; row < getRowCount(); row++) {
Object o = getValueAt(row, column);
if (o != null) {
return o.getClass();
}
}
return Object.class;
}
};
JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
JPanel buttonPanel = new JPanel();
add(buttonPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Patient Records");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
TableFromDatabase newContentPane = new TableFromDatabase();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
});
}
}
Your message "uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details" is not an error, but it is a warning. The Vector class is generic (Generics were added to Java in 1.5), which means that it takes a type parameter. Here, it means the type of objects it can hold.
If you were to re-compile with the command line option "-Xlint:unchecked" as the warning suggests, the compiler will give you more details about the warning, including the offending lines.
You didn't supply a type parameter for any of your Vectors, so they are raw, meaning no type parameter was supplied. The compiler is warning you that you are using raw types, and that your type safety is at risk.
You can supply the appropriate type parameters to eliminate the warnings. In the TableFromDatabase constructor, towards the top:
Vector<String> columnNames = new Vector<String>();
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
and later on in the same constructor:
Vector<Object> row = new Vector<Object>(columns);
However, Vector was superseded by ArrayList (and its List interface) in Java 1.2. In fact Vector was retrofitted then to implement the new-then List interface. It doesn't look like you need Vector's thread safety, so it's recommended to use ArrayList instead.
List<String> columnNames = new ArrayList<String>();
List<Vector<Object>> data = new ArrayList<List<Object>>();
and
List<Object> row = new ArrayList<Object>(columns);
As of Java 1.7, you can use the "diamond operator", and remove the type parameter on the right side of the assignment operator, letting Java infer the proper type, e.g.:
List<String> columnNames = new ArrayList<>();
List<Vector<Object>> data = new ArrayList<>();
and
List<Object> row = new ArrayList<>(columns);
Currently, this is my main screen:
()
I have 2 files: “patient.txt” and “treatment.txt” which hold records of multiple patients and treatments.
What I’m trying to do is to display all of those records in a nice JTable whenever I click “Display Treatments” or “Display Patients”, in a screen like so:
I am using an MVC model for this Hospital Management System (with HMSGUIModel.java, HMSGUIView.java, HMSGUIController.java, HMSGUIInterface.java files), and add records using the following code:
FileWriter tfw = new FileWriter(file.getAbsoluteFile(), true);
BufferedWriter tbw = new BufferedWriter(tfw);
tbw.write(this.view.gettNumber() + "," + this.view.gettName() + "," + this.view.gettDoctor() + "," + this.view.gettRoom());
tbw.newLine();
tbw.flush();
JOptionPane.showMessageDialog(null, "Successfully added treatment!"); }
Please help on how I can add a reader as well, to display all the records from the text file to a table?
Many thanks in advance!!
Keeping in line with your MVC, you could create a TableModel which knew how to read a give patient record.
Personally though, I'd prefer to separate the management of the patient data from the view, so the view didn't care about where the data came from.
To this end, I would start by creating a Patient object and a Treatment object, these would hold the data in a self contained entity, making the management simpler...
You would need to read this data in and parse the results...
List<Treatment> treatments = new ArrayList<Treatment>(25);
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String text = null;
while ((text = br.readline()) != null) {
String parts[] = text.split(",");
Treatmeant treament = new Treatment(parts[0],
parts[1],
parts[2],
parts[3]);
treatments.add(treament);
}
} // Handle exception as required...
I'd wrap this into a readTreatments method in some utility class to make it easier to use...
Around about here, I'd be considering using a stand alone database or even an XML document, but that's just me.
Once you have this, you can design a TableModel to support it...
public class TreatmentTableModel extends AbstractTableModel {
protected static final String[] COUMN_NAMES = {
"Treatment-Number",
"Treatment-Name",
"Doctor-in-charge",
"Room-No",
};
protected static final Class[] COLUMN_CLASSES = new Class[]{
Integer.class,
String.class,
Doctor.class,
Integer.class,
};
private List<Treatment> treatments;
public TreatmentTableModel() {
this.treatments = new ArrayList<>();
}
public TreatmentTableModel(List<Treatment> treatments) {
this.treatments = new ArrayList<>(treatments);
}
#Override
public int getRowCount() {
return treatments.size();
}
#Override
public int getColumnCount() {
return 4;
}
#Override
public String getColumnName(int column) {
return COUMN_NAMES[column];
}
#Override
public Class<?> getColumnClass(int columnIndex) {
return COLUMN_CLASSES[columnIndex];
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
Treatment treatment = treatments.get(rowIndex);
Object value = null;
switch (columnIndex) {
case 0:
value = treatment.getNumber();
break;
case 1:
value = treatment.getName();
break;
case 2:
value = treatment.getDoctor();
break;
case 3:
value = treatment.getRoomNumber();
break;
}
return value;
}
}
Then you simply apply it to what ever JTable you need...
private JTable treatments;
//...
treatments = new JTable(new TreatmentTableModel());
add(new JScrollPane(treatments));
Then, we you need to, you would load the List of Treatments and apply it to the table...
File file = new File("...");
treatments.setModel(new TreatmentTableModel(TreatmentUtilities.readTreatments(file)));
Depending on your needs for the table, you can look at using the DefaultTableModel and populating your data using that model. The downside to that is, you may want special capability from your table, like not being able to edit cells, store more than strings, etc... in which case you might look in to extending AbstractTableModel and defining your own behavior for the model.
A simple thing to do would be to start with the default model and expand on that.
String[] myColumns = {"Treatment-Number","Treatment-Name", "Doctor-in-charge", "Room-No"};
// init a model with no data and the specified column names
DefaultTableModel myModel = new DefaultTableModel(new Object[myList.size()][4](), myColumns);
// assuming you have a list of lists...
int i = 0;
int j = 0;
for (ArrayList<Object> list : myList) {
for ( Object o : list ) {
myModel.setValueAt(o, i, j); // set the value at cell i,j to o
j++;
}
i++;
}
JTable myTable = new JTable(myModel); // make a new table with the specified data model
// ... do other stuff with the table
If you want to access the table data, you use myTable.getModel() and update the data. This will automatically update the view of the table (completing the MVC connection)
Look here for more info on using tables.
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.
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.