sorting a JTable using getColumnClass() when connected to JDBC - java

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

Related

How to fill jtable with the right data from another table?

I have a JTable with 6 columns, the rows for the first 3 columns comes from table1(subject_records_bsit_first_year) and the last 3 will come from table2(evaluation_permission). The two database table have two joined columns(subject_code and subject_title). I'm trying to fill the last 3 columns of my JTable with data from table2—using the db table connection to display the right data.
My code:
public static void loadFirstYearSubjectList() {
ConnectionManager connectionManager = new ConnectionManager();
//String sqlChooseStudent = "SELECT * FROM student_bsit_"+studentID.toLowerCase() +" WHERE year_level = '"+yearLevel+"'";
try {
Connection con = connectionManager.createConnection();
Statement stmt = con.createStatement();
String sql = "SELECT * FROM `subject_records_bsit_first_year` ORDER BY `subject_records_bsit_first_year`.`trimester_period` ASC";
ResultSet rs = stmt.executeQuery(sql);
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.addColumn("Subject Code");
tableModel.addColumn("Subject Title");
tableModel.addColumn("Trimester");
tableModel.addColumn("Section");
tableModel.addColumn("Professor");
tableModel.addColumn("Evaluation");
table.setModel(tableModel);
TableColumnModel columnModel = table.getColumnModel();
columnModel.getColumn(0).setPreferredWidth(95);
columnModel.getColumn(1).setPreferredWidth(266);
columnModel.getColumn(2).setPreferredWidth(90);
columnModel.getColumn(3).setPreferredWidth(77);
columnModel.getColumn(4).setPreferredWidth(179);
columnModel.getColumn(5).setPreferredWidth(78);
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
renderer.setBackground(new Color(120, 120, 120, 10));
renderer.setOpaque(true);
columnModel.getColumn(0).setCellRenderer(renderer);
columnModel.getColumn(1).setCellRenderer(renderer);
columnModel.getColumn(2).setCellRenderer(renderer);
columnModel.getColumn(3).setCellRenderer(renderer);
columnModel.getColumn(4).setCellRenderer(renderer);
columnModel.getColumn(5).setCellRenderer(renderer);
while (rs.next()) {
String subjectCode = rs.getString("subject_code");
String subjectTitle = rs.getString("subject_title");
String trimesterPeriod = rs.getString("trimester_period");
tableModel.addRow(new Object[] {subjectCode, subjectTitle, trimesterPeriod});
}
} catch (Exception e) {
} finally {
try {
connectionManager.closeConnection();
} catch (Exception e2) {
}
}
}
table 2 data
I'm trying to display the section, subject_teacher and evaluation_permission from this table, this table is joined from another table that already displays the first 3 columns on my jtable. The two db table is joined with the same column names; subject_code and subject_title.
Create your own implementation of TableModel that is able to retrieve the data as you described above. Then use JTable's setModel() to make the JTable actually use your TableModel implementation.
An example how to use it is in the Java tutorials.
SELECT subject_records_bsit_first_year.subject_code,
subject_records_bsit_first_year.subject_title,
subject_records_bsit_first_year.trimester_period,
evaluation_permission.section, evaluation_permission.subject_teacher,
evaluation_permission.permission_status
FROM subject_records_bsit_first_year
INNER JOIN evaluation_permission
ON subject_records_bsit_first_year.subject_code = evaluation_permission.subject_code;
Got what I'm trying to do, thanks for the help! Sometimes people learn from example.

Decimals in Jtable not displaying correctly

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.

JTable only displaying one colum from access database

I'm trying to display the data from a access database; for some reason, whenever I run the program, only one row is displayed. Here's my code
try{
String coursec = jTextField9.getText().trim();
String sql5 = "SELECT * FROM Studentcourse WHERE ccode ='" +coursec+"'";
String url5 ="jdbc:ucanaccess://C:/Users/james_000/Documents/NetBeansProjects/Registration/Campus.accdb ";
Connection conn5 =DriverManager.getConnection(url5);
Statement statem = conn5.createStatement();
ResultSet rs5 = statem.executeQuery(sql5);
while (rs5.next()){
DefaultTableModel dm;
dm = new DefaultTableModel(10, 10);
String coursecode= rs5.getString(2);
String attend =rs5.getString(3);
String date =rs5.getString(4);
Vector <String> vector = new Vector<String>();
vector.add(coursecode);
vector.add(attend);
vector.add(date);
String s[] = new String[]{"ccode", "stnumattend", "Date"};
dm.setColumnIdentifiers(s);
jTable1.setModel(dm);
dm.addRow(vector);
jTable1.setVisible(true);
}
}
catch(Exception d){
System.err.println("Exception:" + d.getMessage());
}
You're creating a new DefaultTableModel each time through your while loop, so only the last such model is applied to jTable1. At a minimum, move the model creation out of the loop.
DefaultTableModel dm = new DefaultTableModel(10, 10);
jTable1.setModel(dm);
while (rs5.next()) {
String coursecode= rs5.getString(2);
…
}

Row_Number() in MySql result value Double, but in IBM Data Studio result Int

I want result value in java is Int like in IBM Data Studio, but in my case is java generate value in double, i don't know why?, Please help to fix it!
This my java code to generate Number in table
private void polDatToTab(ResultSet rs, JTable table) throws SQLException{
String[] colHead = new String[] {"No","NIK","Nama"};
DefaultTableModel tm = new DefaultTableModel();
ResultSetMetaData rsd = rs.getMetaData();
Vector<String> nameCol = new Vector<String>();
int kolCount = rsd.getColumnCount();
for(int i=0;i<colHead.length;i++){
nameCol.add(colHead[i]);
}
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while(rs.next()){
Vector<Object> vec = new Vector<Object>();
for(int j=1;j<=kolCount;j++){
vec.add(rs.getObject(j));
}
data.add(vec);
}
tm.setDataVector(data, nameCol);
table.setModel(tm);
}
This my java code to display Table in Gui
private void srcEmp(){
String srcE = "SELECT (#ROW_NUMBER:=#ROW_NUMBER + 1) AS No_Urut,NIK,NAMA FROM PAYROLL.KARYAWAN,"
+ "(SELECT #ROW_NUMBER:=0) AS T WHERE NAMA LIKE '%"+srcRes+"%'";
DbConnect co = new DbConnect();
co.connectDB();
try {
st = co.connection.createStatement();
ResultSet ul = st.executeQuery(srcE);
polDatToTab(ul, tabResSrc);
} catch (SQLException ex) {
Logger.getLogger(ResSrc.class.getName()).log(Level.SEVERE, null, ex);
}
}
This my sql code in IBM Data Studio generate true value in int
SELECT (#ROW_NUMBER:=#ROW_NUMBER + 1) AS No_Urut,NIK,NAMA
FROM PAYROLL.KARYAWAN,(SELECT #ROW_NUMBER:=0) AS T
WHERE NAMA LIKE '%"+srcRes+"%'
This my Result in Java Gui:
and This my Result in IBM Data Studio
Your polDatToTab method isn't generic, it looks like it's designed to work only with this particular resultset. I am jumping to that conclusion because of this line
String[] colHead = new String[] {"No","NIK","Nama"};
As such, you are aware that the first column is expected to be an int. Therefore,
vec.add(rs.getInt(1));
for(int j=2; j<=kolCount; j++){
vec.add(rs.getObject(j));
}
Does the trick

Using PreparedStatement to sort records in MySQL

Im trying to write a code in which when a user will click an a "Sort by Name" button, my program will sort the records of my Database and put them in a JTable,combining 2 DB Tables with INNER JOIN. I have managed to do this by using a resultSet and selecting for example Ascending Order. But because I dont want to have 2 buttons, one for the ASC and one for the DESC, I thought of using preparedStatement and an showInputDialog in which the user will select if he wants to have an ASC or a DESC ordering and execute the order. Also, I remembered that some programs I've seen used a feature in which the first time you clicked the button it sorted DESC and if you pressed it again would order by ASC(havent managed to find in on the WEB).About my first thought, I tried to do it but I could get past this one
ResultSetMetaData mdsort = rssort.getMetaData();
I should have an ResultSet variable(rssort) to use getMetaData() but if I selected to make the program with my PreparedStatement i would get an error there. Any suggestions??
try{
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/test1?user=me&password=12345");
Statement stmtsort = conn.createStatement();
ResultSet rssort = stmtsort.executeQuery("SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name ASC");
// ERROR HERE!!! needs resultset,not preparedStatement
ResultSetMetaData mdsort = rssort.getMetaData();
columnCount = mdsort.getColumnCount();
String[] colssort = new String[columnCount];
for (i=1;i<= columnCount;i++)
{
colssort[i-1] = mdsort.getColumnName(i);
}
DefaultTableModel model = new DefaultTableModel(colssort,0);
while (rssort.next())
{
Object[] rowsort = new Object[columnCount];
for (i = 1 ; i <= columnCount ; i++)
{
rowsort[i-1] = rssort.getObject(i);
}
model.addRow(rowsort);
}
JTable table = new JTable(model);
model.fireTableDataChanged();
table.setCellSelectionEnabled(true);
table.setColumnSelectionAllowed(true);
table.setFillsViewportHeight(true);
table.setSurrendersFocusOnKeystroke(true);
table.setBounds(218,59,529,360);
frame.getContentPane().add(table);
model.fireTableDataChanged();
conn.close();
stmtsort.close();
rssort.close();
} catch (SQLException case1)
{case1.printStackTrace();
} catch (Exception case2)
{case2.printStackTrace();}
}
});
UPDATE
OK I managed to fix this issue with the getMetaData() but now the thing is that I dont use any ResultSet variables/instances and cant use next() method to create my DB.
String name = "SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name ?";
PreparedStatement psname = conn.prepareStatement(name);
String strin = JOptionPane.showInputDialog(null,"ASC or DESC order ? : ");
psname.setString(1,strin);
psname.executeUpdate();
ResultSetMetaData mdsort = psname.getMetaData();
int columnCount = mdsort.getColumnCount();
.
.
.
// error coming up here,because i deleted the ResultSet
while (psname.next())
.
.
.
Better make a bit more complex TableModel.
That is more optimal.
Keep the data from the ResultSet in an original TableModel.
Use a wrapping TableModel to sort, and maybe filter.
Use the ResultSetMetaData for the column type, if it is Number (Integer, BigDecimal, ...) then use that type instead of Object for the column type: gives a right aligned column.
Maybe first do an internet search for ResultSetTableModel; other peoply must have done it already.
try{
conn = DriverManager.getConnection("jdbc:mysql://localhost/test1?user=me&password=12345");
String strin = JOptionPane.showInputDialog(null,"ASC or DESC order ? : ");
stmtsortname = conn.createStatement();
rssortname = stmtsortname.executeQuery("SELECT * FROM consoles INNER JOIN hardware ON consoles.id=hardware.id ORDER BY consoles.name "+strin);
mdsortname = rssortname.getMetaData();
columnCount = mdsortname.getColumnCount();
String[] colssortname = new String[columnCount];
for (i=1;i<= columnCount;i++)
{
colssortname[i-1] = mdsortname.getColumnName(i);
}
model = new DefaultTableModel(colssortname,0);
while (rssortname.next())
{
Object[] rowsortname = new Object[columnCount];
for (i = 1 ; i <= columnCount ; i++)
{
rowsortname[i-1] = rssortname.getObject(i);
}
model.addRow(rowsortname);
}
table = new JTable(model);
model.fireTableDataChanged();
table.setCellSelectionEnabled(true);
table.setColumnSelectionAllowed(true)
table.setFillsViewportHeight(true);
table.setSurrendersFocusOnKeystroke(true);
table.setBounds(146,59,763,360);
frame.getContentPane().add(table);
model.fireTableDataChanged();
conn.close();
stmtsortname.close();
rssortname.close();
} catch (SQLException case1)
{
case1.printStackTrace();
}
catch (Exception case2)
{
case2.printStackTrace();
}
}
});

Categories