I am trying to show the data of a Table from MySQL server, into a JFrame I am creating. Although everything else works great i cant seem to get correct the TIME data from the corresponding columns.
My code, as well as an example of the output, follows!
package pkginterface;
import java.awt.*;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import java.time.*;
public class Staff_Info extends JFrame
{
public Staff_Info()
{
ArrayList columnNames = new ArrayList();
ArrayList data = new ArrayList();
String url = "jdbc:mysql://localhost:3306/cinema";
String userid = "root";
String password = "password";
String sql = "SELECT * FROM TimeTable";
try (Connection connection = DriverManager.getConnection( url, userid, password );
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery( sql ))
{
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
for (int i = 1; i <= columns; i++)
{
columnNames.add( md.getColumnName(i) );
}
while (rs.next())
{
ArrayList row = new ArrayList(columns);
for (int i = 1; i <= columns; i++)
{
row.add( rs.getObject(i) );
}
data.add( row );
}
}
catch (SQLException e)
{
System.out.println( e.getMessage() );
}
Vector columnNamesVector = new Vector();
Vector dataVector = new Vector();
for (int i = 0; i < data.size(); i++)
{
ArrayList subArray = (ArrayList)data.get(i);
Vector subVector = new Vector();
for (int j = 0; j < subArray.size(); j++)
{
subVector.add(subArray.get(j));
}
dataVector.add(subVector);
}
for (int i = 0; i < columnNames.size(); i++ )
columnNamesVector.add(columnNames.get(i));
// Create table with database data
JTable table = new JTable(dataVector, columnNamesVector)
{
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 );
getContentPane().add( scrollPane );
JPanel buttonPanel = new JPanel();
getContentPane().add( buttonPanel, BorderLayout.SOUTH );
pack();
}
public static void main(String[] args)
{
Staff_Info frame = new Staff_Info();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
}
}
And here you can see the above output!
I am working on Ubuntu 14.04 with MySQL Workbench and NetBeans.
Both of the timetable_starttime and timetalbe_endtime fields, have the TIME datatype in their table creation as long as a valid insert field.
Here you can see the MySQL Select * statement for that table.
I figured out that there has something to do with Epoch time but I wasn't able to find an actual solution to the problem!
Any help would be greatly appreciated!
Thanks for your time!
As to this documentation, the call to rs.getObject(i) will return an instance of java.sql.Time for your TIME columns.
java.sql.Time is a subclass of java.util.Date
Unfortunately, JTable does not have a default Renderer in place for java.sql.Time. But is does have one for java.util.Date - which uses a short date format for display - defaulting to showing only the date part, which is all zero for a Time - so it's always Januar 1st 1970
So how to fix this?
Add a custom renderer to your JTable with a specific Renderer for Time:
TableCellRenderer tableCellRenderer = new DefaultTableCellRenderer() {
SimpleDateFormat f = new SimpleDateFormat("HH:mm:ss");
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
if( value instanceof Time) {
value = f.format(value);
}
return super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
}
};
table.setDefaultRenderer(Time.class, tableCellRenderer);
Good Luck.
Related
How i refresh the JTable ?
Here is my Code.
public void itemStateChanged(ItemEvent evt)
{
String text=(String)to_Cmb2.getSelectedItem();
try
{
// Connect to an Access Database
Connection con=DriverManager.getConnection("jdbc:odbc:flightdsn");
Statement s=con.createStatement();
// Read data from a table
ResultSet rs = s.executeQuery("SELECT FlightNo,City,To,Arrives,Departs FROM I_Flights_Routes WHERE To ='"+text+"' ");
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<Object> row = new Vector<>(columns);
for (int i = 1; i <= columns; i++)
{
row.addElement(rs.getObject(i));
}
data.addElement(row);
}
rs.close();
s.close();
con.close();
}
catch (Exception e)
{
System.out.println(e);
}
// Create table with database data
JTable table = new JTable(data, columnNames)
{
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);
scrollPane.setBounds(50,10,400,200);
td.add(scrollPane);
// td is Jpanel object
td.setVisible(true);
}
You're creating an entirely new JTable -- don't do that. Use the same JTable but
modify the JTable's model if you want to add new data to existing data
or if you want to totally replace the data in the table, create a new DefaultTableModel (or other TableModel) and set your JTable's model with it via `setModel(...).
Also, as an aside you will want to avoid using null layouts and setBounds(...) as this creates very inflexible GUI's that look terrible on other platforms or other resolutions and are very difficult to upgrade and manage.
I seem to hit a java error in the following java code when i try to clean and build the project:
public class DisplayPerson extends javax.swing.JFrame{
String driverName = "net.sourceforge.jtds.jdbc.Driver";
String serverName = "xx";
String serverPort = "xx";
String database = serverName + ":" + serverPort;
String url = "jdbc:jtds:sqlserver:/" + database;
String username = "xx";
String password = "xx";
public DisplayPerson() throws SQLException {
ArrayList columnNames = new ArrayList();
ArrayList data = new ArrayList();
try {
Class.forName(driverName);
Connection connection = DriverManager.getConnection(url, username, password);
// Create and execute an SQL statement that returns some data.
String SQL = "";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(SQL);
ResultSetMetaData rsmetadata = rs.getMetaData();
int columns = rsmetadata.getColumnCount();
// Get column names
for (int i = 1; i <= columns; i++)
{
boolean add;
add = columnNames.add( rsmetadata.getColumnName(i) );
}
// Get row data
while (rs.next())
{
ArrayList row;
row = new ArrayList(columns);
for (int i = 1; i <= columns; i++)
{
boolean add;
add = row.add( rs.getObject(i) );
}
boolean add;
add = data.add( row );
}
}
catch (SQLException e)
{
System.out.println( e.getMessage() );
} catch (ClassNotFoundException ex) {
Logger.getLogger(DisplayPerson.class.getName()).log(Level.SEVERE, null, ex);
}
// Create Vectors and copy over elements from ArrayLists to them
// Vector is deprecated but I am using them in this example to keep
// things simple - the best practice would be to create a custom defined
// class which inherits from the AbstractTableModel class
Vector columnNamesVector = new Vector();
Vector dataVector = new Vector();
for (int i = 0; i < data.size(); i++)
{
ArrayList subArray = (ArrayList)data.get(i);
Vector subVector = new Vector();
for (int j = 0; j < subArray.size(); j++)
{
boolean add;
add = subVector.add(subArray.get(j));
}
boolean add;
add = dataVector.add(subVector);
}
for (int i = 0; i < columnNames.size(); i++ )
boolean add
add = columnNamesVector.add(columnNames.get(i));
// Create table with database data
JTable table;
table = new JTable(dataVector, columnNamesVector)
{
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 );
getContentPane().add( scrollPane );
JPanel buttonPanel = new JPanel();
getContentPane().add( buttonPanel, BorderLayout.SOUTH );
}
you can avoid this error by changing this code
for (int i = 1; i <columnNames.size(); i++)
boolean add //here is a missing semicolon
add = columnNamesVector.add(columnNames.get(i));//variable declaration not allowed here
as follow
for (int i = 0; i < columnNames.size(); i++ ){
boolean add ;
add = columnNamesVector.add(columnNames.get(i));
}
Leaving off the brackets isn't good idea.
I create Jtable that store data from the database that I can delete/add contents' the Jtable with Jbutton. When I t try to run the code, I got this result:
When I add data into Jtable twice,there is data in it with an extra blank row
When I delete data into Jtable twice,data in a specific row is deleted but it add a transparent blank row too.
Why does this happen?
Here the code that I think there is a problem:
//add,delete button
final JToggleButton tglbtnAdd = new JToggleButton("Add");
final JToggleButton tglbtnDelete = new JToggleButton("Delete");
JButton button = new JButton("1");
button.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent arg0) {
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection dbconbt1 = DriverManager.getConnection("" +"jdbc:sqlserver://localhost;databaseName=Store;user=sa;password=");
Statement sqlstatement = dbconbt1.createStatement();
ResultSet dbresultset1 = sqlstatement.executeQuery("select * from Store.dbo.Product where ProductID = 'P-1'");
ResultSetMetaData rsmetadata = dbresultset1.getMetaData(); // Get metadata on them
int numcols = rsmetadata.getColumnCount(); // How many columns?
// Get column names
for (int i = 1; i <= numcols; i++) {
defaultmodel2.addColumn( rsmetadata.getColumnName(i));
}
if(tglbtnAdd.isSelected() == true) {
while (dbresultset1.next()) {
Vector<Object> row = new Vector<Object>(numcols);
for (int i = 1; i <= numcols; i++) {
row.addElement( dbresultset1.getObject(i) );
}
defaultmodel2.addRow(row );
}
}
if(tglbtnDelete.isSelected() == true) {
/**while (dbresultset1.next())
{
Vector<Object> row = new Vector<Object>(numcols);
row.removeElement( dbresultset1.getObject(0) );
}
*/
defaultmodel2.removeRow(0);
}
// Get row
dbresultset1.close();
sqlstatement.close();
dbconbt1.close();
Make your table structure on form load only, and just take your data from JTextField's (or from whatever you use) into Object array. Finally, add the object array to your model. For delete, just call model.removeRow() method.
I want to put an action whenever someone clicks a cell. open another gui for example. But how do i make a cell clickable BUT not editable? These are results for an sql query. I can't manage to make the table uneditable though. Do I need a listener or something? and if yes where should I put it?
Here is my code:
public class AllResultsFromDB extends JFrame
{
GUI ins = new GUI();
public AllResultsFromDB(GUI x)
{
Vector columnNames = new Vector();
Vector data = new Vector();
this.ins = x;
try
{
// Initializing GUI class in order to call getSelectedTable() method.
// GUI ins = new GUI();
//System.out.println(ins.getSelectedTable());
Login sgui = new Login();
String dburl = "jdbc:oracle:thin:#localhost:1521:ORCL";
Connection connection = DriverManager.getConnection( dburl, sgui.getUsername(), sgui.getPassword() );
// Fetch data from table specified by user
String query = "SELECT * FROM " + ins.getSelectedTable() + " ORDER BY id";
System.out.println(query);
Statement stmt = connection.createStatement();
ResultSet rset = stmt.executeQuery(query);
ResultSetMetaData metad = rset.getMetaData();
int columns = metad.getColumnCount();
// This loop gets the names of the columns
for (int i = 1; i <= columns; i++)
{
columnNames.addElement( metad.getColumnName(i) );
//columnNames.addElement("PROFILES");
}
// This loop gets the data inside the rows
while (rset.next())
{
Vector row = new Vector(columns);
//Vector b = new Vector((Collection)button);
for (int i = 1; i <= columns; i++)
{
row.addElement( rset.getObject(i) );
}
data.addElement( row );
//data.addElement(b);
}
rset.close();
stmt.close();
connection.close();
// Create table with results
JTable table = new JTable(data, columnNames)
{
public Class getColumnClass(int column)
{
for (int row = 0; row < getRowCount(); row++)
{
Object obj = getValueAt(row, column);
if (obj != null)
{
return obj.getClass();
}
}
return Object.class;
}
};
JScrollPane scroll = new JScrollPane( table );
getContentPane().add( scroll );
//table.addMouseListener(l);
//table.setEnabled(false);
//table.setDragEnabled(true);
JPanel panel = new JPanel();
getContentPane().add( panel, BorderLayout.SOUTH );
} catch (SQLException e) {
}
}
}
Start by taking a look at How to use tables
The isCellEditable method the TableModel determines of a cell is editable or not. This method should return false
When you supply column/data information to the JTable directly, the JTable creates a DefaultTableModel internally. This class's isCellEditiable method will return true by default.
By using something like DefaultTableModel, you can override this method without with to much trouble and set the model to the table directly.
Next, you need to attach a MouseListener to the table
Take a look at How to write a Mouse Listener
You can then use getSelectedColumn, getSelectedRow to get the selected cell.
You'll also need to use convertRowIndexToModel and convertColumnIndexToModel to convert between the view and model indices
These are my codes for my jTable in java swing.
private JTable getJTable() {
if (jTable == null) {
Vector columnNames = new Vector(); //Vector class allows dynamic array of objects
Vector data = new Vector();
JPanel panel = new JPanel();
panel.setSize(new Dimension(198, 106));
try {
DBController db = new DBController();
db.setUp("IT Innovation Project");
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
String dsn = "IT Innovation Project";
String s = "jdbc:odbc:" + dsn;
Connection con = DriverManager.getConnection(s, "", "");
String sql = "Select * from forumTopics";
java.sql.Statement statement = con.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
ResultSetMetaData metaData = resultSet.getMetaData();
int columns = metaData.getColumnCount();
for (int i = 1; i <= columns; i++) {
columnNames.addElement(metaData.getColumnName(i));
}
while (resultSet.next()) {
Vector row = new Vector(columns);
for (int i = 1; i <= columns; i++) {
row.addElement(resultSet.getObject(i));
}
data.addElement(row);
}
resultSet.close();
((Connection) statement).close();
} catch (Exception e) {
System.out.println(e);
}
jTable = new JTable(data, columnNames);
TableColumn column;
for (int i = 0; i < jTable.getColumnCount(); i++) {
column = jTable.getColumnModel().getColumn(i);
column.setMaxWidth(250);
}
String header[] = {"description", "title", "category", "posted by"};
for(int i=0;i<jTable.getColumnCount();i++) {
TableColumn column1 = jTable.getTableHeader().getColumnModel().getColumn(i);
column1.setHeaderValue(header[i]);
}
jTable.setBounds(new Rectangle(82, 218, 736, 292));
jTable.setEnabled(false);
jTable.setRowHeight(50);
jTable.getRowHeight();
}
return jTable;
}
I set an array for the header of my table. However, the program only shows the data inside my database without any header. Can somebody please enlighten me? Thanks in advance.
Put your JTable in JScrollPane like
add(new JScrollPane( getJTable() ) );