I am new to SWT and I need to use it's table widget. I would like to Right send queries to my database and a table is created. The setText() function only takes a new array of strings or a String, How what should I do in order for my rows to be displayed despite the number of columns. This is my code:
try{
ResultSet getTable=dbconnect.connect.createStatement().executeQuery("select * from Status");
ResultSetMetaData md = getTable.getMetaData();
int columns = md.getColumnCount();
for (int i = 1; i <= columns; i++) {
tblclmnNewColumn = new TableColumn(table, SWT.NONE);
tblclmnNewColumn.setWidth(100);
tblclmnNewColumn.setText(md.getColumnName(i));
columnNames.add( md.getColumnName(i));
}
for(int i=0;i<columnNames.size();i++){
String set;
if(i==columnNames.size()-1){
set="getTable.getString"+"("+'"'+columnNames.get(i)+'"'+")";
}else{
set="getTable.getString"+"("+'"'+columnNames.get(i)+'"'+")"+",";
}
columsresultset.add(set);
element[i]=columsresultset.get(i);
System.out.println(columsresultset.get(i));
}
String elements[]=new String[columsresultset.size()];
while (getTable.next()) {
TableItem tableItem =(TableItem) new TableItem(table, SWT.NONE);
tableItem.setText(elements);
}
How about using setText(yourDatabaseColumnIndex - 1, yourDatabaseColumnValue). Of course you have to create your TableColumns anyway, just as you did in your code. Example:
while(resultSet.next())
{
TableItem tableItem = new TableItem(table, SWT.NONE);
for(int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++)
{
tableItem.setText(i-1, resultSet.getString(i));
}
}
No guarantees that I didn't miss any ; or { or something ;-). Also you could optimize this a little by writing the column count to a variable.
Related
When a user clicks a button initially, a query is run and each row is put into a JPanel and added to the display for the user to view. Which works fine.
My problem is, I want the user to be able to filter these results according to values that they provide ( through a JTextField ) , and I want the displayed records to update as the value of the JTextField changes. My queries are formed and executed each time the JTextField is changed, but I can't find a way to update the records displayed.
Any help would be appreciated.
The code took a while to edit to the satisfaction of stackoverflow, but here it is. Hopefully you can follow the logic. This is the method that deals with formation and execution of the queries, which works(again).
The problem is displaying the new results.
private void processSearch(){
int count = 0;
double width;
remove(allInfo);
allInfo = new JPanel();
allInfo.setLayout(new GridLayout(0, 1, 5, 10));
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
width = screenSize.getWidth();
try {
DatabaseConnetor connect = new DatabaseConnetor();
Connection conn = connect.connect();
String query = "";
String whereClause = "";
int unEmpty = 0;
String [] searches ={searchNameTxt.getText(), searchMailTxt.getText(), searchContactTxt.getText(), (String) searchGender.getSelectedItem()};
String [][] keys = {{"first_name", "middle_name", "family_name", "surname"}, {"email"}, {"contact", "contact2"}, {"gender"}};
for(int i=0; i < searches.length; i++){
if(!searches[i].trim().isEmpty()){
unEmpty++;
}
for(int i=0; i < searches.length; i++){
int counter = 0;
if(!searches[i].trim().isEmpty()){
whereClause += " AND ";
int len = keys[i].length;
if(len == 1){
whereClause += " ("+keys[i][0]+" LIKE '%"+searches[i]+"%') ";
}else if(len > 1){
whereClause += " ( ";
while(counter < len){
if(counter == len-1)
whereClause += keys[i][counter]+" LIKE '%"+searches[i]+"%'";
else
whereClause += keys[i][counter]+" LIKE '%"+searches[i]+"%' OR ";
counter++;
}
whereClause += " ) ";
}
}
}
query = "SELECT photo, first_name, middle_name, family_name, surname, gender, email, contact, contact2 FROM user WHERE rights = 2" + whereClause;
PreparedStatement preparedStatement = conn.prepareStatement(query);
String gen = "", middle = "", family = "", cont = "", phot = "";
ResultSet result = preparedStatement.executeQuery();
while(result.next()){
JPanel data = new JPanel();
data.setPreferredSize(new Dimension((int)(width*0.75), 50));
data.setLayout(new GridLayout(1, 0, 5, 10));
if(result.getString(1) == "NULL")
phot = "";
data.add(new JLabel(phot)); //Photo
data.add(new JLabel(result.getString(2))); //First Name
if(result.getString(3) == "NULL")
middle = "";
data.add(new JLabel(middle)); //Middle Name
if(result.getString(4) == "NULL")
family = "";
data.add(new JLabel(family)); //Family Name
data.add(new JLabel(result.getString(5))); //Surname
if(result.getString(6).equals("M"))
gen = "Male";
else
gen = "Female";
data.add(new JLabel(gen)); //Gender
data.add(new JLabel(result.getString(7))); //E-Mail
data.add(new JLabel(result.getString(8))); //Contact1
if(result.getString(9) == "NULL")
cont = "";
data.add(new JLabel(cont)); //Contact 2
allInfo.add(data);
}
add(allInfo);
connect.disconnect(conn);
connect = null;
conn = null;
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
a query is run and each row is put into a JPanel and added to the display for the user to view
I would suggest you use a JTable to display the data from a database. A JTable is designed to display data in a row/column format.
Read the section from the Swing tutorial on How to Use Tables for more information and examples.
I want the user to be able to filter these results according to values that they provide ( through a JTextField ) , and I want the displayed records to update as the value of the JTextField changes.
A JTable supports dynamic filtering of the data displayed in the table. The above tutorial has a section on Sorting and Filtering that shows how to filter as text is entered into a text field. Filtering the table is more efficient then redoing the SQL query.
Adding data to the table is straight forward. Instead of creating a panel with each column of data you can add a new row of data to the TableModel:
String sql = "Select * from ???";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery( sql );
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<Object>(columns);
for (int i = 1; i <= columns; i++)
{
row.addElement( rs.getObject(i) );
}
data.addElement( row );
}
// Create table with database data
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
#Override
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;
}
};
JTable table = new JTable( model );
JScrollPane scrollPane = new JScrollPane( table );
is there any way to retrieve database rows using component other than jTable where unique jButtons for each row can added and made to perform specific task?
Currently I'm using the following code... jTable appears in a dialog box
public static DefaultTableModel buildTableModel(ResultSet rs)
throws SQLException {
ResultSetMetaData metaData = rs.getMetaData();
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
System.out.println("7");
for (int column = 1; column <= columnCount; column++) {
columnNames.add(metaData.getColumnName(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
}
public void searchb2() throws SQLException {
this.be_cgpa = be_cg.getText();
this.maj_proj = Major.getText();
this.h_percent = hss_percent.getText();
this.s_percent = sss_percent1.getText();
preparedStatement = con.prepareStatement("select name,age,gender,email_id,phone_num,state from resume1 where qualification='be' and be_cgpa>='" + be_cgpa + "'" + "and maj_proj_tech='" + maj_proj + "'" + "and hss_percent>='" + h_percent + "'" + "and sss_percent='" + s_percent + "'");
ResultSet rs;
rs = preparedStatement.executeQuery();
JTable table = new JTable(buildTableModel(rs));
JOptionPane.showMessageDialog(null, new JScrollPane(table));
}
Can this code be modified to add jButton in each row?
There is no reason you can't use JTable and add a column containing buttons to the table.
See Table Button Column for one way to do this. This class expects you to provide an Action that is invoked when the button is clicked. All you need to do is add another String of text to the "vector" after you have finished looping through the column data.
Also, use a PreparedStatement for your SQL. It is easier to code and understand and less error prone than your current code.
table button column is definitely the best way of achieving particular cell's value on clicking the corresponding button but seems to be 1 of the hardest thing in jtable.
another approach for implementing the above is enabling cell selection and using list selection model and list selection listener.
On clicking any cell you can get cell's data in a variable.
you can even fix a column and make an ordinary column with text as "button i" where i=row number. and on clicking this cell, you'll get only particular column's data of corresponding row and can even open a new frame or dialog box depending on your coding, this will make it work like a jbutton! (Actually due to fixed column, clicking any cell in that row will perform that task with column number same as fixed column)
Here is a sample code :
final JTable table;
table = new JTable(data, columnNames)
{
public boolean isCellEditable(int rowIndex, int colIndex) {
return false; //Disallow the editing of any cell
}
};
table.setCellSelectionEnabled(true);
ListSelectionModel cellSelectionModel = table.getSelectionModel();
cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
int[] selectedRow = table.getSelectedRows();
for (int i = 0; i < selectedRow.length; i++) {
selectedData = (String) table.getValueAt(selectedRow[i],2);
}
new NewJFrame().setVisible(true);
System.out.println("Selected: " + selectedData);
}
This is a last resort. I'm studying development of Information Systems and even my teachers can't solve this... this is a nut for you to crack!!
This is the problem: My jTable in GUI gives me this:
This is what Microsoft Management Studio shows me:
As you can tell the jTable (GUI) has got 2 main problems:
The columnname "Name" does not contain any information. And it should? Why isn't it showing?
Since as you can tell, the table contains several columns, too many to even show. I therefore want to "add a restriction" that changes so that the jTable only shows the first 6 columns.
This is the code for the "creation of the table", in the DataAccessLayer:
private TableModel getResultSetAsDefaultTableModel(ResultSet rs) {
try {
String[] columnHeadings = new String[0];
Object[][] dataArray = new Object[0][0];
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
String columnName = md.getColumnName(i);
columnHeadings = Arrays.copyOf(columnHeadings, columnHeadings.length + 1);
columnHeadings[i - 1] = columnName;
}
int r = 0;
while (rs.next()) {
Object[] row = new Object[columnCount];
for (int i = 1; i <= columnCount; i++) {
row[i - 1] = rs.getObject(i);
}
dataArray = Arrays.copyOf(dataArray, dataArray.length + 1);
dataArray[r] = row;
r++;
}
DefaultTableModel dtm = new DefaultTableModel(dataArray, columnHeadings) {
public boolean isCellEditable(int row, int column) {
return false;
}
};
return dtm;
} catch (SQLException ex) {
Logger.getLogger(Dataaccesslayer.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
If you want me to show you the path of the code (frame, controller) just say so and I'll post it.
I would be so thankful if anyone can solve this...
Regards,
Christian
I think it is because in your for loop it should say i = 0; and not i = 1; since the first information (the name) is at index 0 right ?
In your case it could be enough to just leave the for-loop as it is and change this line to:row[i - 1] = rs.getObject(i-1);
To hide or show columns you could call setMin setMax and setPreferredWidth on your TableColumn.
Change your method like next, I think it helps you:
private TableModel getResultSetAsDefaultTableModel(ResultSet rs) {
try {
List<String> columnHeadings = new ArrayList<String>();
Object[][] dataArray = new Object[0][0];
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
columnHeadings.add(md.getColumnName(i));
}
int r = 0;
while (rs.next()) {
Object[] row = new Object[columnCount];
for (int i = 1; i <= columnCount; i++) {
row[i-1] = rs.getObject(i);
}
dataArray = Arrays.copyOf(dataArray, dataArray.length + 1);
dataArray[r] = row;
r++;
}
DefaultTableModel dtm = new DefaultTableModel(dataArray,columnHeadings.toArray(new Object[columnHeadings.size()])) {
public boolean isCellEditable(int row, int column) {
return false;
}
};
return dtm;
} catch (SQLException ex) {
Logger.getLogger(Dataaccesslayer.class.getName()).log(Level.SEVERE,null, ex);
}
return null;
}
For showing not all columns use dtm.setColumnCount(2);. Here 2 is column count to show.
This is the code for the "creation" of the table I have in my DataAccessLayer.
private TableModel getResultSetAsDefaultTableModel(ResultSet rs) {
try {
String[] columnHeadings = new String[0];
Object[][] dataArray = new Object[0][0];
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
String columnName = md.getColumnName(i);
columnHeadings = Arrays.copyOf(columnHeadings, columnHeadings.length + 1);
columnHeadings[i - 1] = columnName;
}
int r = 0;
while (rs.next()) {
Object[] row = new Object[columnCount];
for (int i = 1; i <= columnCount; i++) {
row[i - 1] = rs.getObject(i);
}
dataArray = Arrays.copyOf(dataArray, dataArray.length + 1);
dataArray[r] = row;
r++;
}
DefaultTableModel dtm = new DefaultTableModel(dataArray, columnHeadings) {
public boolean isCellEditable(int row, int column) {
return false;
}
};
return dtm;
} catch (SQLException ex) {
Logger.getLogger(Dataaccesslayer.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
**This results in some complications, since one of my tables has 50 different columns and therefore you can't read the columnnames or what is in the cell.
The problem is that the table's values are determined by the metadata...
I want to limit the columns that are showed to a specific number (5) for all tables.
How do I do it?**
Kind regards,
Chris
you can remove tables if you want to...
int amountColumns = table.getColumnModel().getColumnCount(); //count columns
TableColumn c6 = table.getColumnModel().getColumn(6); //identif a random column
table.getColumnModel().removeColumn(c6); //remove this column
i hope that helped...
I would not remove them but change their size to 0.
int amountColumns = table.getColumnModel().getColumnCount(); //count columns
TableColumn c6 = table.getColumnModel().getColumn(6); //identif a random column
table.getColumnModel().setMin(0);
table.getColumnModel().setMax(0);
table.getColumnModel().setPreferredWidth(0);
Like i answered you in your other thread...
I used this coding to retrieve the Mysql data to the JTable.but it returns only the first data row of the relevant table of the database but then again it count the number of rows correctly and all it returns is same copy of the first row equal to the row count.
I'm new to Java and netbeans environment so if someone can help me to solve this problem i'll be really grateful and thank you in advance :)
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/data", "root", "1122");
Statement stat = (Statement) con.createStatement();
stat.executeQuery("select * from reserve;");
ResultSet rs=stat.getResultSet();
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
Vector data=new Vector();
Vector columnNames= new Vector();
Vector row = new Vector(columnCount);
for(int i=1;i<=columnCount;i++){
columnNames.addElement(md.getColumnName(i));
}
while(rs.next()){
for(int i=1; i<=columnCount; i++){
row.addElement(rs.getObject(i));
}
data.addElement(row);
}
DefaultTableModel model = new DefaultTableModel(data, columnNames);
jTable1.setModel( model );
You keep adding to the same Vector row. Try creating a new instance for each iteration of rs.next().
You have an error with your Vector. Consider using something like :
Vector data = new Vector(columnCount);
Vector row = new Vector(columnCount);
Vector columnNames = new Vector(columnCount);
for (int i = 1; i <= columnCount; i++) {
columnNames.addElement(md.getColumnName(i));
}
while (rs.next()) {
for (int i = 1; i <= columnCount; i++) {
row.addElement(rs.getObject(i));
}
data.addElement(row);
row = new Vector(columnCount); // Create a new row Vector
}
DefaultTableModel model = new DefaultTableModel(data, columnNames);
jTable1.setModel( model );