I'm making a GUI and it includes a JPanel, inside that JPanel there's a JTable, and what I want to do is: when I click a button, both of them appear (since I'm using CardLayout). Code:
private void teGjithaButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
parentPanel.setVisible(true);
parentPanel.removeAll();
parentPanel.add(tgjPanel);
parentPanel.repaint();
parentPanel.revalidate();
listAllCurtains();
} catch (SQLException ex) {
Logger.getLogger(MainBrillant.class.getName()).log(Level.SEVERE, null, ex);
}
}
And the code for listAllCurtains():
DefaultTableModel deftm = (DefaultTableModel) allTable.getModel();
if (deftm.getRowCount() != 0) {
deftm.setRowCount(0);
}
stm = (Statement) conn.createStatement();
ResultSet rs = stm.executeQuery("select * from customerregister.curtain inner join curtainrel on curtain.code = curtainrel.curtainCode;");
while (rs.next()) {
String shifra = rs.getString("code");
String ngjyra = rs.getString("color");
String emri = rs.getString("name");
double cmimi = rs.getDouble("price");
double sasia = rs.getDouble("amount");
allCurtains.add(new Curtain(shifra, ngjyra, emri, cmimi, sasia));
}
Object[] row = new Object[5];
for (int i = 0; i < allCurtains.size(); i++) {
row[0] = allCurtains.get(i).getShifra();
row[1] = allCurtains.get(i).getEmri();
row[2] = allCurtains.get(i).getNgjyra();
row[3] = allCurtains.get(i).getCmimi();
row[4] = allCurtains.get(i).getSasia();
deftm.addRow(row);
}
}
The problem is that when i re-click the button, eventhough there's this part of the code to ensure the data is not duplicated:
if (deftm.getRowCount() != 0) {
deftm.setRowCount(0);
}
It still continues to insert the same data into table each time the button is clicked. I can't figure out why this is happening, and I'd really appreciate your help.
Perhaps you should Clear your JTable model of its rows before you decide to reissue the data again. Instead of your:
if (deftm.getRowCount() != 0) {
deftm.setRowCount(0);
}
code, perhaps use a simple clearTable() method like:
private void clearJTable(DefaultTableModel yourTableModel) {
while (yourTableModel.getRowCount() > 0) {
for (int i = 0; i < yourTableModel.getRowCount(); i++) {
yourTableModel.removeRow(i);
}
}
}
and then in your code:
DefaultTableModel deftm = (DefaultTableModel) allTable.getModel();
clearJTable(deftm);
stm = (Statement) conn.createStatement();
ResultSet rs = stm.executeQuery("select * from customerregister.curtain inner join curtainrel on curtain.code = curtainrel.curtainCode;");
while (rs.next()) {
String shifra = rs.getString("code");
String ngjyra = rs.getString("color");
String emri = rs.getString("name");
double cmimi = rs.getDouble("price");
....................................
....................................
....................................
Related
How to not duplicate when adding data in JTable because when I am adding in JTable it always duplicate the same data.
public void buyproduct() {
String name = code_cart1.getText();
try {
con = Connector.getConnection();
PreparedStatement pst = con.prepareStatement("SELECT `Code`, `Category`, `ProductName`, `Size`, `Quantity`, `Price`, `Sub-Total` FROM `product_table` WHERE Code = ?");
pst.setString(1, name);
rs = pst.executeQuery();
while (rs.next()) {
int currentqty = rs.getInt("Quantity");
int pricenew = Integer.parseInt(price_cart1.getText());
int qtynew = Integer.parseInt(quantity_cart1.getText());
int tot = pricenew * qtynew;
if (qtynew > currentqty || qtynew == 0) {
JOptionPane.showMessageDialog(this, "Out of Stock!");
} else {
DefaultTableModel model = (DefaultTableModel) cart_Display.getModel();
model.addRow(new Object[]{code_cart1.getText(),
category_cart1.getText(),
productname_cart1.getText(),
size_cart1.getText(),
quantity_cart1.getText(),
price_cart1.getText(),
tot});
int sum = 0;
for (int i = 0; i < cart_Display.getRowCount(); i++) {
sum = sum + Integer.parseInt(cart_Display.getValueAt(i, 6).toString());
}
SubTotal_Cart_text.setText(Integer.toString(sum));
SubTotal_Cart_text1.setText(Integer.toString(sum));
code_cart1.setText("");
category_cart1.setText("");
productname_cart1.setText("");
size_cart1.setText("");
quantity_cart1.setText("");
price_cart1.setText("");
}
}
} catch(Exception ex) {
}
}
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";
currently I have data in MySQL server and I am calling the datas onto the JTable through JDBC. However there are 1369 rows and it seems that it has too much data for it to load. It usually takes 5 minutes to load. Are there anyways to optimize the process? This is my code(I apologize in advance for a messy code):
public class DataTable {
private String databaseName = "*****";
private String tableName = "******";
public void showDatabase(){
Connection conn = null;
DatabaseMetaData meta = null;
Statement stmt = null;
ResultSet rs = null;
int k = 0;
try{
Class.forName("com.mysql.jdbc.Driver").newInstance();
String connectionUrl = "jdbc:mysql://localhost:3306/" + databaseName;
String connectionUser = "*****";
String connectionPassword = "*****";
conn = DriverManager.getConnection(connectionUrl, connectionUser, connectionPassword);
stmt = conn.createStatement();
meta = conn.getMetaData();
dataSets(stmt, meta);
}catch(Exception e){
e.printStackTrace();
} finally{
try { if (rs != null) rs.close(); } catch (SQLException e) { e.printStackTrace(); }
try { if (stmt != null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); }
try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}
}
//return the column size of the table
public int getColumnNumber(DatabaseMetaData meta, Statement stmt) throws SQLException
{
//ResultSet rs = meta.getColumns(null, null, "practiceexample", null);
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
ResultSetMetaData rsmd = rs.getMetaData();
int columnsNumber = rsmd.getColumnCount();
return columnsNumber;
}
//return the rowNumber of the tables
public int getRowNumber(Statement stmt) throws SQLException
{
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
int rowCount = 0;
while(rs.next()){
rowCount = rs.getInt(1);
}
return rowCount;
}
public void dataSets(Statement stmt, DatabaseMetaData meta) throws SQLException
{
String[] columnNames = new String[getColumnNumber(meta, stmt)];
String[][] dataSets = new String[getRowNumber(stmt)][columnNames.length];
ResultSet column = meta.getColumns(null, null, tableName, null);
int i = 0;
while(column.next())
{
columnNames[i] = column.getString("COLUMN_NAME");
//columnNames.add(i, column.getString("COLUMN_NAME"));
i++;
}
for(int j = 0; j < dataSets.length; j++)
{
String[] singleRowData = new String[columnNames.length];
ResultSet data = null;
for(int k = 0; k < columnNames.length; k++)
{
String columnName = columnNames[k];
data = stmt.executeQuery("SELECT " + columnName +
" FROM " + tableName + " LIMIT " + j + ", " + 1);
while(data.next())
{
singleRowData[k] = data.getString(columnName);
}
}
dataSets[j] = singleRowData;
}
SimpleTable table = new SimpleTable(columnNames, dataSets);
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
table.createAndShowGUI();
}
});
}
class SimpleTable{
String[] columns;
String[][] dataSets;
public SimpleTable(String[] columns, String[][] dataSets){
this.columns = columns;
this.dataSets = dataSets;
}
public void createAndShowGUI(){
JPanel gui = new JPanel(new BorderLayout(3, 3));
final JTable table = new JTable(new DefaultTableModel(dataSets, columns));
final JScrollPane scrollPane = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
Dimension dimension = table.getPreferredSize();
scrollPane.setPreferredSize(new Dimension(dimension.width, table.getRowHeight() * 30));
JPanel navigation = new JPanel(new FlowLayout(FlowLayout.CENTER));
JButton next = new JButton(">");
next.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
int height = table.getRowHeight() * (20-1);
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue(bar.getValue() + height);
}
});
JButton previous = new JButton("<");
previous.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent ae) {
int height = table.getRowHeight()*(20-1);
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue( bar.getValue()-height );
}
} );
navigation.add(previous);
navigation.add(next);
gui.add(scrollPane, BorderLayout.CENTER);
gui.add(navigation, BorderLayout.SOUTH);
JOptionPane.showMessageDialog(null, gui);
}
}
}
IMHO the root of the bad permormance is you unnecessarily query the database mutliple times to get the data (columns, rows, rows number, columns number, etc) you need:
To get columns number:
ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);
To get rows number:
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + tableName);
To get rows (this is the worst beacuse it's inside a loop):
data = stmt.executeQuery("SELECT " + columnName + " FROM " + tableName + " LIMIT " + j + ", " + 1);
How to solve it
Just query the database once. A single ResultSet and its associated ResultSetMetaData should be enough to accomplish your goal. Additionaly, and as already suggested, use a SwingWorker to do database calls in a separate thread. For example:
final JTable table = new JTable();
SwingWorker<Void, TableModel> worker = new SwingWorker<Void, TableModel> () {
#Override
protected Void doInBackground() throws Exception {
ResultSet resultSet = stmt.executeQuery("SELECT * FROM " + tableName);
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount(); // columns number
String[] columnNames = new String[columnCount];
for (int i = 1; i <= columnCount; i++) {
columnNames[i] = metaData.getColumnName(i); // fill columns names
}
resultSet.last();
int rowCount = resultSet.getRow(); // get rows number
resultSet.beforeFirst();
Object[][] data = new Object[rowCount][columnCount];
int currentRow = 0;
while (resultSet.next()) {
for (int currentColumn = 1; currentColumn <= columnCount; currentColumn++) {
data[currentRow][currentColumn - 1] = resultSet.getObject(currentColumn); // fill data set
}
currentRow++;
}
TableModel model = new DefaultTableModel(data, columnNames);
publish(model);
return null;
}
#Override
protected void process(List<TableModel> chunks) {
TableModel model = chunks.get(0);
table.setModel(model);
}
}
worker.execute();
Hello I would like to print data from mysql query to my Jtable, I knw how to print the conventional data(String), but do not know how to do it with pictures. What I need is print the picture in the first cell of the table.
public void SearchMovie() throws SQLException {
try {
Connection con = null;
ResultSet rs = null;
Statement st = null;
String Genre = ComboGenero.getSelectedItem().toString();
String Era = ComboEra.getSelectedItem().toString();
String Clsssification = ComboClasification.getSelectedItem().toString();
String sql = "select Foto,Title,Year,Country ,Rating from movie where Genre ='" + Genre + "'";
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost/whichmovie", "Asis", "dekrayat24");
st = con.createStatement();
rs = st.executeQuery(sql);
DefaultTableModel model = new DefaultTableModel();
this.jTable1.setModel(model);
jTable1.setDefaultRenderer(Object.class,new IconCellRenderer());
jTable1.setRowHeight(40);
ResultSetMetaData rsMD = rs.getMetaData();
int numcolumnas = rsMD.getColumnCount();
for (int x = 1; x <= numcolumnas; x++) {
model.addColumn(rsMD.getColumnLabel(x));
}
while (rs.next()) {
Object[] fila = new Object[numcolumnas];
for (int i = 0; i < numcolumnas; i++) {
fila[i] = rs.getObject(i + 1);
ResultadosLabel.setText(numcolumnas + "Movies found");
}
model.addRow(fila);
}
rs.close();
st.close();
con.close();
} catch (ClassNotFoundException ex) {
System.out.println(ex.getMessage());
}
}
Thanks .
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..