Remove JTable row without convert RowIndex To Model - java

I know that for remove a row i should do this:
if (table.getSelectedRow() > -1) {
int rowToTable = table.getSelectedRow();
int rowToModel = table.convertRowIndexToModel(rowToTable);
model.removeBook(rowToModel);
} else {
JOptionPane.showMessageDialog(null, "Select A Row");
}
But, Now i try this method without rowToModel variable and still remove correctly:
if (table.getSelectedRow() > -1) {
int rowToTable = table.getSelectedRow();
model.removeBook(rowToTable);
} else {
JOptionPane.showMessageDialog(null, "Select A Row");
}
My removeBook() method:
public void removeBook(int row) {
Connection connection;
PreparedStatement preparedStatement;
String query = "Delete from BookTable where id=?";
try {
connection = DriverManager.getConnection(...);
Object id = this.getValueAt(row, 0);
preparedStatement = connection.prepareStatement(query);
preparedStatement.setObject(1, id);
if (preparedStatement.executeUpdate() == 1) {
this.removeRow(row);
}
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}
Why both of this works?!
And which is correct?

it works without conversion only if the table is neither sorted nor filtered - as your code can't know whether it is, it must convert the row index always. BTW, same for column index, as the user might have moved the column

Related

java - jTable database repeating values

I am trying to populate a java database with car brands, models, and if they are available but I have a big issue. When I enter multiple cars to the table, the new car prints to the table, but previous cars I have entered also reprint
[Issue.png][1]. So first I entered Ferrari Enzo, then I entered Tesla S but Ferrari Enzo is repeating.
I know the issue is not with adding the cars to the database because if I look in the database it only shows the two I entered [DatabasePic.png][2]. I know my problem is with how I am entering my cars into the JTable. My methods are below..
ButtonClickEvent:
private void refreshbtnMouseClicked(java.awt.event.MouseEvent evt) {
try {
String Brand = brandlbl.getText();
String Model = modellbl.getText();
Boolean Available = false;
switch (availabilitybox.getSelectedItem().toString()) {
case "True":
Available = true;
break;
case "False":
Available = false;
break;
}
InsertApp nw = new InsertApp();
nw.insert(Brand, Model, Available);
nw.refreshDatabase(jTable1);
} catch (SQLException ex) {
Logger.getLogger(Window.class.getName()).log(Level.SEVERE, null, ex);
}
}
Insert Method:
public void insert(String brand, String model, Boolean available) {
String sql = "INSERT INTO CARDATA(brand,model,available) VALUES(?,?,?)";
try (Connection conn = this.connect();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, brand);
pstmt.setString(2, model);
pstmt.setBoolean(3, available);
pstmt.executeUpdate();
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
Refreshing my database:
public void refreshDatabase(JTable table) throws SQLException {
Connection con = connect();
String SQL = "SELECT * FROM CARDATA";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(SQL);
int col = rs.getMetaData().getColumnCount();
System.out.println(col);
while (rs.next()) {
Object[] rows = new Object[col];
for (int i = 1; i <= col; i++) {
rows[i - 1] = rs.getObject(i);
}
((DefaultTableModel) table.getModel()).insertRow(rs.getRow() - 1, rows);
}
con.close();
rs.close();
stmt.close();
}
When I enter multiple cars to the table, the new car prints to the table, but previous cars I have entered also reprint
You need to clear the data in the TableModel before you start adding data back into it.
The basic code should be something like:
DefaultTableModel model = (DefaultTableModel)table.getModel();
model.setRowCount(0);
while (rs.next())
{
...
model.addRow(...);
}
Or instead of retrieving all the data from the database every time you do an insert, just add the data to the table at the same time:
pstmt.executeUpdate();
model.addRow(...);

How to make one mySQL's table column invisible

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";

Showing values in jTable B when selecting a record in jTable A

I am trying to pass in a JTable object which has columns DiscountID and Name. I am basically trying to get a row of the first column which is selected in JTable A (a DiscountID) and upon this set data relating to this selected record in JTable B which is JTable5 in the rs.next() loop.
The problem I have now is that since initially int row = table.getSelectedRow(); I'm having to set it to 0 to avoid an IndexOutOfBoundsException but then when I run the program JTable B will show information correlating to the first record in JTable A without any selection of data by me. I don't want any information to be displayed at all in JTable B until I select a record from JTable A whilst also avoiding the IndexOutOfBoundsException. It will be much appreciated if anyone can help me to fix this I've been trying hard to find a solution.
Here is the code to my method:
public static ArrayList<FlexiBand> getFlexiBands(JTable table, JTable table2) {
ArrayList<FlexiBand> flexiband = new ArrayList<FlexiBand>();
try {
Connection con = null;
PreparedStatement stmt = null;
ResultSet rs = null;
con = DriverManager
.getConnection("jdbc:mysql://localhost:3306/abpp034?user=abpp034&password=120001772");
stmt = con
.prepareStatement("SELECT UpperBound, PercentageRate FROM FlexiBand WHERE DiscountID = ?");
int row = table.getSelectedRow();
if (row == -1) {
row = 0;
for (int x = 0; x < table2.getRowCount(); x++) {
table2.setValueAt("", x, 0);
table2.setValueAt("", x, 1);
}
}
System.out.println(row); // This is printing me 0 meaning that row is still 0
System.out.println(table.getValueAt(row, 0)); // This means that row will be equal to 0
// when it goes to the next line.
stmt.setObject(1, table.getValueAt(row, 0));
try {
rs = stmt.executeQuery();
int i = 0;
while (rs.next()) {
FlexiBand fb = new FlexiBand();
fb.setUpperBound(rs.getInt("UpperBound"));
fb.setPercentageRate(rs.getInt("PercentageRate"));
flexiband.add(fb);
}
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException se) {
System.out.println(se.getErrorCode());
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException se) {
System.out.println(se.getErrorCode());
}
}
if (con != null) {
try {
con.close();
} catch (SQLException se) {
System.out.println(se.getErrorCode());
}
}
}
} catch (SQLException ex) {
Logger.getLogger(Model.class.getName()).log(Level.SEVERE, null, ex);
}
return flexiband;
}
Here is where I call the method:
public static void main(String[] args) {
DiscountGUIView dgv = new DiscountGUIView();
setDiscountNames("Fixed", dgv.getjComboBox2());
getFlexiBands(dgv.getjTable2(), dgv.getjTable5());
}
in the same class as the method.
Just do in this way. Check whether row is selected or not.
public static void main(String[] args) {
DiscountGUIView dgv = new DiscountGUIView();
setDiscountNames("Fixed", dgv.getjComboBox2());
ArrayList<FlexiBand> flexiband = null;
if (dgv.getjTable2().getSelectedRow != -1) {
flexiband = getFlexiBands(dgv.getjTable2(), dgv.getjTable5());
}
if (flexiband !=null) {
// user selected a row, do what ever you want to do
} else {
// nothing is selected
// skip other operations
}
}

INSERT row does not update JTable in GUI

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..

Inserting information from one mysql table to another

I am writing a program that will take in a student ID and verify if that ID exists in a mysql table. If it does exist, I would like to take the entire row that it exists in and copy that row to another table. Currently the program will just copy all rows in a table to the other. Any help appreciated. I have inserted a snippet of code below.
try {
String compareText = IDField.getText().trim();
if(compareText.length() > 0){
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/simlab","root","password");
System.out.println("Connected to database");
Statement stmt1 = conn.createStatement();
ResultSet rs1 = stmt1.executeQuery("select * from students where LUID='"+IDField.getText()+"' ");
boolean isPresent = rs1.next();
if (isPresent)
{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/simlab","root","password");
System.out.println("Connected to database");
int rows = stmt1.executeUpdate("INSERT INTO skills(ID_Student,LUID_Student)SELECT ID, LUID FROM students");
if (rows == 0)
{
System.out.println("Don't add any row!");
}
else
{
System.out.println(rows + " row(s)affected.");
conn.close();
}
//System.out.println("Already exists!!");
}
You could all do that in a single SQL statement:
INSERT INTO <Dest-Table>
(SELECT * FROM <Src-Table> WHERE ID=?);
It will only copy rows that exist.
I suspect it's due to this line:
int rows = stmt1.executeUpdate("INSERT INTO skills(ID_Student,LUID_Student)SELECT ID, LUID FROM students");
As, if that line is parsed, the SELECT statement has no WHERE clause, and will therefore get every row, and therefore insert everything.
With Prepared statements
String sql = "INSERT INTO abc"
+ "(SELECT id1,id2 FROM pqr)";
ps1 = con.prepareStatement(sql);
int rs = ps1.executeUpdate();
if (rs > 0) {
update = true;
} else {
update = false;
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
if (ps1 != null) {
ps1.close();
ps1 = null;
}
if (con != null) {
con.close();
con = null;
}
} catch (Exception e) {
}
}
return update;

Categories

Resources