Good evening,
I've got a JTable with data from a SQL table. I have a column in the SQL table with decimal values (for example, 44.44) but in the JTable it shows as 44.00. So somehow the JTable (or the input field) is rounding off the value to the nearest whole number (which is what i do not want).
I tried using Table Renderer, but it's not giving me the desired results (or i'm overlooking something)
Code for the table renderer:
static class DecimalFormatRenderer extends DefaultTableCellRenderer {
private static final DecimalFormat formatter = new DecimalFormat( "#,###.00" );
public Component getTableCellRendererComponent(
JTable pickTable, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
Number number = (Number) value;
value = formatter.format((Number)value);
return super.getTableCellRendererComponent(
pickTable, value, isSelected, hasFocus, row, column );
}
}
this code loads the date from the SQL Table into the JTable:
private void LoadPickTable() {
ArrayList<Pick> pick = ListPick(pickFilterTxt1.getText());
DefaultTableModel model = new DefaultTableModel();
model.setColumnIdentifiers(new Object[]{"ID", "ARTIKELCODE", "LOCATIE", "OMSCHRIJVING", "EENHEID", "CODE","HAL","AANTAL","INITIAAL"});
Object[] rij = new Object[9];
pickTable.setFont(new Font("Barlow", Font.PLAIN, 22));
for (int i = 0; i < pick.size(); i++) {
rij[0] = pick.get(i).getId();
rij[1] = pick.get(i).getArtiekelcode();
rij[2] = pick.get(i).getLocatie();
rij[3] = pick.get(i).getOmschrijving();
rij[4] = pick.get(i).getEenheid();
rij[5] = pick.get(i).getCode();
rij[6] = pick.get(i).getHal();
rij[7] = pick.get(i).getAantal();
rij[8] = pick.get(i).getInitiaal();
model.addRow(rij);
}
pickTable.setModel(model);
pickTable.getColumnModel().getColumn(7).setCellRenderer(new DecimalFormatRenderer());
}
The Input field i'm using to test is a JComboBox (pickAantalCombo), the code:
private void ModifyPick() {
int row = pickTable.getSelectedRow();
String cell = pickTable.getModel().getValueAt(row, 0).toString();
String sql = "UPDATE PICKLOCATIES SET artikelcode=?,locatie=?,omschrijving=?, eenheid=?, hal=?, aantal=?, initiaal=? WHERE ID=" + cell;
try {
conn = getConnection();
pst = conn.prepareStatement(sql);
String code = (String) pickArticleCombo.getSelectedItem();
pst.setString(1, code);
String loc = (String) pickLocationCombo.getSelectedItem();
String hal = (String) halCombo.getSelectedItem();
String decimal = (String) pickAantalCombo.getSelectedItem();
pst.setString(1, code);
pst.setString(2, loc);
pst.setString(3, pickDescriptionTxt.getText());
pst.setString(4, eenheidTxt.getText());
pst.setString(5, hal);
pst.setString(6,decimal);
pst.setString(7, pickInitiaalTxt.getText());
pst.executeUpdate();
LoadPickTable();
ClearPickFields();
JOptionPane.showMessageDialog(null, "Artikel Aangepast!");
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
Screenshot of the JTable:
JTable Screenshot
Screenshot of the SQL Table:
SQL Table Screenshot
The input value in the input field is, of course, 44.44.
Any help will be highly appreciated. Thanks!
First an other error: ever table now needs its own row object, otherwise you are overwriting every row's fields with the last rows' fields.
for (int i = 0; i < pick.size(); i++) {
Object[] rij = new Object[9];
You should ensure, that the read Number is not integral.
rij[7] = (BigDecimal) pick.get(i).getAantal();
I suspect getAantal to deliver an int.
At the moment the table fields seem to always be string:
pst.setBigDecimal(6, new BigDecimal(decimal));
Then there is still the problem of decimal point versus comma, but I leave it at this.
Try debugging.
Related
I designed a jTable that will display data from a table in MySql DB.
The table name is studentrolls with STRollID (int) as primary key and StudentID (Varchar), BachID (year) as foreign keys.
So after typing the StudentID in a jTextField and clicking a jButton only data concerning the student should be displayed in the jTable.
It's working actually but am having two problems, instead of displaying the Year on the year column it's displaying a date for example it should display 2020 but it displaying 2020-01-01.
The main problem is that when I enter another StudentID, it is adding the new results to the old one, so when I enter for the first time a StudentID I get good results and then when I enter another StudentID and click the button I get in the table the new results mixed with the first student's one, etc...
Is there any way to solve this and clear the table before inserting new results?
Here is my code :
private void rSButtonIconDsearchstidActionPerformed(java.awt.event.ActionEvent evt) {
try{
String sqlqueryPastYHi = "SELECT * FROM studentrolls WHERE StudentID = ? ORDER BY BachID";
PreparedStatement preparedStatement = con.prepareStatement(sqlqueryPastYHi);
PreparedStatement pst=con.prepareStatement(sqlqueryPastYHi);
if(!jTextFieldsearchstid.getText().isEmpty() ) {
preparedStatement.setString(1, jTextFieldsearchstid.getText());
ResultSet resultSet = preparedStatement.executeQuery();
while(resultSet.next()){
String scolaryear = resultSet.getString("BachID");
String stclass = resultSet.getString("ClassID");
String totpercent = String.valueOf(resultSet.getInt("PourcentTotal"));
String finalplace = String.valueOf(resultSet.getInt("PlaceFinale"));
String appication = resultSet.getString("Aplication");
String behavior = resultSet.getString("Conduite");
String finalaction = resultSet.getString("ActionFinale");
String pastHistTableData [] = {scolaryear, stclass, totpercent, finalplace, appication, behavior, finalaction};
DefaultTableModel tblModel = (DefaultTableModel)jTablehipastyears.getModel();
tblModel.addRow(pastHistTableData);
}
}
else{
JOptionPane.showMessageDialog(this, "Veillez taper le matricule d'un eleve svp.");
}
}catch (Exception exception){
JOptionPane.showMessageDialog(this, "erreur des donnees: " + exception.getMessage());
}
}
is there any way to solve this and clear the table before inserting new results?
DefaultTableModel tblModel = (DefaultTableModel)jTablehipastyears.getModel();
tblModel.setRowCount(0);
while (...)
{
....
tblModel.addRow(...);
}
thanks #camickr i did changed the code as follow using your methode and it worked.
if(!jTextFieldsearchstid.getText().isEmpty() ) {
preparedStatement.setString(1,
jTextFieldsearchstid.getText());
ResultSet resultSet = preparedStatement.executeQuery();
DefaultTableModel tblModel =
(DefaultTableModel)jTablehipastyears.getModel();
tblModel.setRowCount(0);
while(resultSet.next()){
String scolaryear = resultSet.getString("BachID");
String stclass = resultSet.getString("ClassID");
String totpercent =
String.valueOf(resultSet.getInt("PourcentTotal"));
String finalplace =
String.valueOf(resultSet.getInt("PlaceFinale"));
String appication =
resultSet.getString("Aplication");
String behavior = resultSet.getString("Conduite");
String finalaction =
resultSet.getString("ActionFinale");
String pastHistTableData [] = {scolaryear, stclass,
totpercent, finalplace, appication, behavior,
finalaction};
tblModel.addRow(pastHistTableData);
}
I have spent a few days trying to get my JTable sorting correctly. I know the code I have to use, but cannot seem to get it for 'fit' and work into my code. I am getting the TableModel data from a database so if i call the getColumnClass() when initalising the model, I get a NullPointerException (of course), but I can't seem to get the getColumnClass(int) to work anywhere else such as model.getColumnClass(columnIndex). I only need to sort the first column in numerical order as the rest are strings. Here is my code. (ps: this is the first time using JBDC so I most likely have errors in the order I am calling - or maybe doing it in 'longhand' haha)
public JTable memberList()
{
JTable jTable1;
DefaultTableModel model;
model = new DefaultTableModel();
jTable1 = new JTable(model);
TableRowSorter sorter = new TableRowSorter(model);
try
{
Statement stmt = conn.createStatement();
String sql = "select rm.race_no,cm.firstname,cm.lastname,cm.phone,cm.dob,cm.email,cm.TwinTown_ID,rm.disqualified,cm.notes\n" +
"from competitor_master cm join competitor_season cs on cm.competitor_id = cs.competitor_id\n" +
"inner join race_master rm on cs.race_no= rm.race_no where cm.twintown_id is not null and cs.season_start_year in (year(sysdate()))\n" +
"group by (race_no);";
ResultSet rs = stmt.executeQuery(sql);
String b = "", c = "", d = "", e = "", f = "", g = "", h = "", i = "";
int a;
model.addColumn("Member Number");
model.addColumn("First Name");
model.addColumn("Last Name");
model.addColumn("Phone");
model.addColumn("Date of Birth");
model.addColumn("Email");
model.addColumn("TT Member Number");
model.addColumn("Disqualified");
model.addColumn("Notes");
while(rs.next())
{
a = rs.getInt(1);
b = rs.getString("FirstName");
c = rs.getString("LastName");
d = rs.getString("phone");
e = rs.getString("dob");
f = rs.getString("email");
g = rs.getString("TwinTown_ID");
h = rs.getString("disqualified");
i = rs.getString("notes");
model.addRow(new Object[] {a,b,c,d,e,f,g,h,i});
model.getColumnClass(1);
}
stmt.close();
rs.close();
}
catch (SQLException ex)
{
}
jTable1.getTableHeader().setFont(new Font("Microsoft Tai Le", Font.BOLD, 14));
jTable1.getTableHeader().setBackground(Color.WHITE);
jTable1.getTableHeader().setForeground(new Color(234, 168, 82));
jTable1.getTableHeader().setBorder(null);
jTable1.setRowSorter(sorter);
return jTable1;
}
public Class getColumnClass (int column){
if (column==1) {
return(Integer.class);
}
return(String.class);
}
it is sorting but by the first number only. so is sorting like this: 123 17 22 28 45 5 56 66
Because it is treating all data as String data.
model = new DefaultTableModel();
jTable1 = new JTable(model);
You are using the default implementation of the DefaultTableModel and the JTable. The default implementation of the getColumnClass(...) method just returns Object.class so the toString() value of each object is sorted.
You don't invoke the getColumnClass() method manually, you need to override the getColumnClass(...) method of your TableModel:
model = new DefaultTableModel()
{
#Override
public Class getColumnClass (int column)
{
return (column == 0) ? Integer.class : String.class;
}
};
I have done enough searches to solve my problem which i have done partly but there's this one bug that keeps disturbing me.I am trying to fetch data from a database based on a condition.I have a table 'user_branch' with a foreign key column branchID which is supposed to fetch the coresponding branchNames in another table 'branches' and I am supposed to display the results into a JTable.When i do System.out.println i get all my results but it returns only the last row when i display in a JTable(branchJTable).This is the code i am using
int row = user2BAssignedJTable.getSelectedRow();
assignUserID.setText(user2BAssignedJTable.getModel().getValueAt(row, 0).toString());
user2BAssignedField.setText(user2BAssignedJTable.getModel().getValueAt(row, 1).toString());
try {
String userBrQry = "SELECT branchID FROM user_branch WHERE userID IN(?) ";
String brQ = "SELECT branchName FROM branches WHERE branchID IN(%s) ";
pstmt = con.prepareStatement(userBrQry);
pstmt.setString(1, assignUserID.getText());
results = pstmt.executeQuery();
results.last();
int nRows = results.getRow();
results.beforeFirst();
while (results.next()) {
String branchIDS = results.getString("branchID");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < nRows; i++) {
builder.append("?");
if (i + 1 < nRows) {
builder.append(",");
}
}
brQ = String.format(brQ, builder.toString());
PreparedStatement ps = con.prepareStatement(brQ);
for (int i = 0; i < nRows; i++) {
ps.setString(i + 1, branchIDS);
}
ResultSet rs = ps.executeQuery();
//branchJTable.setModel(DbUtils.resultSetToTableModel(rs));
javax.swing.table.DefaultTableModel model = new javax.swing.table.DefaultTableModel();
model.setColumnIdentifiers(new String[]{"Branch Name"});
branchJTable.setModel(model);
while (rs.next()) {
String branchname = rs.getString("branchName");
model.addRow(new Object[]{branchname});
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
Forget about the first 3 rows as it is a another JTable event i use to get the userID to use as a condition for getting a particular user's branches assigned to him.
The branches assigned to a user is dynamic hence using StringBuilder.
I am supposed to display the results into another JTable called branchJTable which only displays the last row.Any HELP would be appreciated!
From your question, I think you should declare the JTable
javax.swing.table.DefaultTableModel model = new javax.swing.table.DefaultTableModel();
model.setColumnIdentifiers(new String[]{"Branch Name"});
branchJTable.setModel(model);
before your first loop -
i.e. before while (results.next()) { in your code.
Otherwise in loop, for each loop execution,
the JTable Model is initialising and you are getting the last inserted row in Jtable.
I try to select certain row from jTable and perform a deletion then the jTable will be updated with the latest data in database. This is how I set up jTable :
private JTable getJTableManageReplies() {
jTableManageReplies.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jTableManageReplies.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
int viewRow = jTableManageReplies.getSelectedRow();
// Get the first column data of the selectedrow
int replyID = Integer.parseInt(jTableManageReplies.getValueAt(
viewRow, 0).toString());
eForumRepliesAdmin reply = new eForumRepliesAdmin(replyID);
replyID = JOptionPane.showConfirmDialog(null, "Are you sure that you want to delete the selected reply? " , "Delete replies", JOptionPane.YES_NO_OPTION);
if(replyID == JOptionPane.YES_OPTION){
reply.deleteReply();
SetUpJTableManageReplies();}
}
}
});
return jTableManageReplies;
}
public void SetUpJTableManageReplies() {
DefaultTableModel tableModel = (DefaultTableModel) jTableManageReplies
.getModel();
String[] data = new String[5];
db.setUp("IT Innovation Project");
String sql = "Select forumReplies.reply_ID,forumReplies.reply_topic,forumTopics.topic_title,forumReplies.reply_content,forumReplies.reply_by from forumReplies,forumTopics WHERE forumReplies.reply_topic = forumTopics.topic_id ";
ResultSet resultSet = null;
resultSet = db.readRequest(sql);
tableModel.getDataVector().removeAllElements();
try {
while (resultSet.next()) {
data[0] = resultSet.getString("reply_ID");
data[1] = resultSet.getString("reply_topic");
data[2] = resultSet.getString("topic_title");
data[3] = resultSet.getString("reply_content");
data[4] = resultSet.getString("reply_by");
// Add data to table model
tableModel.addRow(data);
}
resultSet.close();
} catch (Exception e) {
System.out.println(e);
}
}
And this is my codes to perform deletion from database :
public boolean deleteReply() {
boolean success = false;
DBController db = new DBController();
db.setUp("IT Innovation Project");
String sql = "DELETE FROM forumReplies where reply_ID = " + replyID
+ "";
if (db.updateRequest(sql) == 1)
success = true;
db.terminate();
return success;
}
However, there is an error message which is ArrayIndexOutOfBound right after I add the SetUpJTableManageReplies methos in the jDialog box. I try to do like when user select certain row, there will be a pop out to ask for confirmation of deletion. Then right after they click on yes, the jTable data will be refreshed. Can somebody give me some guides? Thanks in advance.
Your Problem is here:
tableModel.getDataVector().removeAllElements();
Better:
tableModel.setRowCount(0);
Much better: write your own table model and implement all methods which are defined in TableModel interface - so you can learn how to deal with the JTable component
Use TableModel to manage table data. DefaultTableModel will be useful, you should first create tableModel, then create JTable and set table's model to previously created table model.
You should perform insert/delete/update to table cells using model, which will update JTable automatically. Use DefaultTableModel to manage your data.
I have a Jtable (tableSummary).
I need to format 2 columns of the table so it's content is in DECIMAL form (e.g. 1,400.00)
How can i do it?
here's my code for the table:
private void tableMarketMouseClicked(java.awt.event.MouseEvent evt) {
String sql = "SELECT tblClientInfo.ClientID, tblrefmarket.MarketDesc, tblclientinfo.LastName, tblledger.LoanAmount, "
+ "tblledger.DateStarted, tblledger.DailyPay, tblledger.Expiry FROM tblclientinfo Inner Join tblbusinessinfo ON tblbusinessinfo.ClientID = tblclientinfo.ClientID "
+ "Inner Join tblrefmarket ON tblbusinessinfo.MarketID = tblrefmarket.MarketID "
+ "Inner Join tblledger ON tblledger.ClientID = tblclientinfo.ClientID where MarketDesc = ?";
try {
//add column to the table model
model.setColumnCount(0); //sets the column to 0 para ig utro click, dili mapun-an ang columns
model.setRowCount(0); //sets the row to 0 para ig utro click, dili mapun-an ang rows
model.addColumn("C NO");
model.addColumn("MARKET");
model.addColumn("BORROWER");
model.addColumn("LOAN");
model.addColumn("START");
model.addColumn("DAILY");
model.addColumn("EXPIRY");
//model.addColumn("BALANCE");
int row = tableMarket.getSelectedRow();
pst = conn.prepareStatement(sql);
pst.setString(1, tableMarket.getModel().getValueAt(row, 0).toString());
rs = pst.executeQuery();
while(rs.next()){
String id = rs.getString(1);
String market = rs.getString(2);
String name = rs.getString(3);
String amt = rs.getString(4);
String start = rs.getString(5);
String daily = rs.getString(6);
String expiry = rs.getString(7);
//String area = rs.getString(3);
model.addRow(new Object[]{ id, market, name, amt, start, daily, expiry});
}
tableSummary.setModel(model);
renderer.setHorizontalAlignment( JLabel.RIGHT );
renderer2.setHorizontalAlignment( JLabel.CENTER );
tableSummary.getColumnModel().getColumn(0).setCellRenderer( renderer2 );
tableSummary.getColumnModel().getColumn(4).setCellRenderer( renderer2 );
tableSummary.getColumnModel().getColumn(6).setCellRenderer( renderer2 );
tableSummary.getColumnModel().getColumn(3).setCellRenderer( renderer );
tableSummary.getColumnModel().getColumn(5).setCellRenderer( renderer );
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e);
}
}
the columns, amt and daily are the columns i need to be formatted.
Thanks in Advance!
As kleopatra already suggested in her comments
The conversion from Object to a String representation (or any other representation) is the task of the renderer. Your TableModel should just contain the objects
Create and set the appropriate renderer on your JTable (for example by calling JTable#setDefaultRenderer or overriding JTable#getCellRenderer)
As renderer for your Number instances you can use one which uses the NumberFormat for formatting as shown in the answer of Samir
NumberFormat formatter = new DecimalFormat("#,###.00");
String str = formatter.format(1400);
System.out.println(str);