List of result from searching JTable - java

Having read here and not understood the concept, I had to post my issue here. I am trying take the input value from Keyword JTextField and filter my JTable table_job.
When search button is pressed, it should change the table in Job List panel to only display the set of jobs which includes the keyword in any of the column in its table. Currently, I am having no luck and am getting blank screens.
Here is the Job List Screen
The table on right does not update according to keyword.
Here is what I tried and failed, I am new to table filtering.
try {
jobTableInit();
String value = keyword.getText();
TableRowSorter sorter;
sorter = new TableRowSorter<DefaultTableModel>(new DefaultTableModel());
RowFilter<DefaultTableModel, Object> rowFilter = null;
try {
rowFilter = RowFilter.regexFilter(keyword.getText());
}
catch(java.util.regex.PatternSyntaxException ex) {
return;
}
sorter.setRowFilter(rowFilter);
table_job.setRowSorter(sorter);
}
catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
Can somebody suggest recommendations or show me a simple example code?

by default there are two ways
use custom Comparator and search in the XxxTableModel (or JTables view by using Pattern), more about Comparator is described in JTables tutorial about Sorting and Filtering
use built_in RowFilter in TableRowSorter, then filtered JTables view returns desired List_of_Xxx
another idea is only to hightlighting matches

Related

Java: Refreshing my jTable after data updates in child jDialog

I've investigated lots of different questions and answers around this, but can't find one that seems to work.
I'm new to Java, but have experience in a variety of different languages and, so far (in context to what I'm experimenting with), it's feeling a bit like VBA except with having to build up the actions/functions that you feel should be already there. This is, I expect, just down to my own inexperience though.
I'm using Netbeans IDE 8.2 with Java Runtime 1.80.
I have created jFrame that contains a jTable. The jTable is built with data like so:
public void showTasks(Boolean removeID) {
ArrayList<Tasks> list = tasksList("SELECT * FROM tasks");
JTable table = jTable1;
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
Object[] row = new Object[4];
for(int i=0;i<list.size();i++) {
row[0]=list.get(i).getId();
row[1]=list.get(i).getName();
row[2]=list.get(i).getDesc();
row[3]=list.get(i).getDate();
model.addRow(row);
}
// Remove the 'id' column from the table view
if(removeID) { table.removeColumn(table.getColumnModel().getColumn(0)); }
}
The background behind this is less relevant, but essentially tasksList is a function that applies the query to an SQL statement, returning an ArrayList. I build up my rows with 4 columns, then remove the first column so 'ID' is available but not visible (this final action has been segregated through testing/experimentation).
I have another area of code that opens a jDialog when a row is clicked, in which it is possible to update the MySQL DB.
Problem
I'm trying to throw in a function call so that the table data 'refreshes' when the jDialog is closed. I have temporarily added in a button to the jFrame (where the jTable lives) to test/debug this function.
I can't seem to get this to work, though. The closest I have achieved is to re-call showTasks(false), but this obvious just adds rows with updated data, rather than replacing the dataset. I'm not 100% sure if deleting all the rows, then building them back in is 'best practice'.
As I'm new to Java, and may still be looking at it from a flawed method of thinking, I'm finding it difficult to apply any other examples to that of my own. I also can't seem to find a way to implement fireTableDataChanged().
Surely this is a simple concept I'm over-thinking?
Edit - based on below answer
Is there a reason why something like this would be considered incorrect, if deleting all rows and adding them back in is okay?
public void refreshTasks() {
DefaultTableModel model = (DefaultTableModel) jTable1.getModel();
int row_total = model.getRowCount();
for(int i= row_total -1;i>=0;i--) {
model.removeRow(i);
}
showTasks(false);
}
Edit: Button to invoke data update
Now works correctly (if not improperly) with the following:
private DefaultTableModel parentTable; // To store the parent 'Task' table model
public void setStart(int user,DefaultTableModel table) {
this.txt_taskID.setText(Integer.toString(user)); // Converts the ID to a string
addData(user); // Populates the fields
parentTable = table; // Sets parent TableModel to a variable
}
The above code is called from the Parent jFrame when the Dialog is opened, and passes the Table model and the 'ID' of the row I'm looking to edit. The table model is stored in parentTable.
There's also a 'Save' button, and a 'Cancel' button. I'm yet to separate these, and currently 'Save' does just that (SQL update and so on). My 'Cancel' button closes the dialog and refreshes the jTable, as per the below function:
private void btn_CancelActionPerformed(java.awt.event.ActionEvent evt) {
this.setVisible(false); // Hide the dialog
Menu menu = new Menu(); // for accessing the tasksList function
parentTable.setRowCount(0); // Clears the jTable data
// jTable data is then 'rebuilt' using the new data
ArrayList<Tasks> list = menu.tasksList("SELECT * FROM tasks");
Object[] row = new Object[4];
for(int i=0;i<list.size();i++) {
row[0]=list.get(i).getId();
row[1]=list.get(i).getName();
row[2]=list.get(i).getDesc();
row[3]=list.get(i).getDate();
parentTable.addRow(row);
}
}
I'm not 100% sure if deleting all the rows, then building them back in is 'best practice'.
Yes that is probably the best practice.
The only other approach is to create a completely new TableModel and add it to the table using the setModel() method. The problem with this approach is that it will reset any custom renderers/editors you may have set on the table.
The easiest way to remove all the rows from the DefaultTableModel is to just use:
model.setRowCount(0);
I'm not sure how you want to do it but I'm gonna give you simple example for deleting and refreshing JTable maybe it's help you.
This following btnDelete Jbutton added to JFrame for deleting rows from table:
btnDelete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int rowIndex = table.getSelectedRow();
if(rowIndex > -1) {
int x = (Integer) table.getModel().getValueAt(rowIndex, 0);
if (conn.removeContact(x) == true) { //here add your own code like removeID
model.removeRow(rowIndex);
lblInfo.setText("Contact deleted successfully.");
model.fireTableDataChanged();
} else {
lblInfo.setText("Cannot remove at this time!");
}
}else {
lblInfo.setText("At first you need select a row with single click!");
return;
}
}
});
and these following codes for refreshing table in primitive way :
btnRefresh.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int rowCount = model.getRowCount();
for (int i = rowCount - 1; i >= 0; i--) {//remove all rows
model.removeRow(i);
}
lblInfo.setText("Table datas updated successfully.");
for (Person p : conn.readAllContacts()) {//add all row from scratch
model.addRow(new Object[] { p.getId(), p.getName(), p.getLastName(), p.getPhone(), p.getEmail() });
}
}
});

How to Give Two Forms to JCombobox Items in Java Swing

i am stuck with a new problem, don't know if this works but here i have list of JCombobox as follow.
JCombobox comboBox = new JComboBox();
comboBox.addItem("UserName");
comboBox.addItem("Password");
comboBox.addItem("DLNo 20 b");
comboBox.addItem("DLNo 20 b");
i want to print my database column names which are more than 40!
when i select the Combobox it must internally print my custom item here.
Here i tried with this code but i am not satisfied with this
if(comboBox.getSelectedIndex()==0)
{
System.out.println("U_NAME");
}
if(comboBox.getSelectedIndex()==1)
{
System.out.println("P_NAME");
}
if(comboBox.getSelectedIndex()==2)
{
System.out.println("DL_NO_20_b");
}
if(comboBox.getSelectedIndex()==3)
{
System.out.println("DL_NO_20_b");
}
is there any better way to over come this, like mapping objects
You could create a class ComboBoxItem with a name- and a columnName-attribute.
Use instances of this class for the ComboBox.
In the ComboBoxItem-class, overwrite the toString()-method to return the name, so it gets displayed as wished in the ComboBox. Add a getColumnName()-method to return the columnName, so you could invoke getSelectedItem().getColumnName().

Null error when attempting to add custom row to CellTable in gwt

I have a Cell Table that I am using to output some search results. The cell table uses a list data provider to update info. I want to separate different sections so I am attempting to add a custom row in between different sections that has one cell that spans all of the columns. I am extending AbstractCellTableBuilder to do this, but my issue comes when I use TableRowBuilder and startRow(), calling startRow() returns a null pointer exception, to AbstractCellTableBuilder.java:243, which refers to tbody. So this is leading me to believe that my cell table is not getting passed into AbstractCellTableBuilder properly. My understanding of gwt and java is pretty basic, so I might just not be understanding how exactly this is supposed to work, and the showcase example is pretty complicated for me to understand. If anyone can tell where I'm messing up or has any simpler examples of this that might help me I would appreciate it!
I had found a similar answer and tried to implement it, and that is how I came up with what I have, but it answer wasn't quite detailed enough for me to fully understand how it works. Here is what I referenced:
Building a custom row on demand with GWT CellTableBuilder
EDITED:
Basic format of how I add normal rows to the cell table
searchProvider = new ListDataProvider<SearchColumn>();
cellTable_2 = new CellTable<SearchColumn>();
//Add columns to the cellTable
searchProvider.addDataDisplay(cellTable_2);
//What I call when adding a row to the cellTable using the ListDataProvider
searchProvider.getList().add(new SearchColumn("",label,"","","","","","",""));
Adding the CustomCellTableBuilder to the cell table:
//Passing the CustomCellTableBuilder to the cell table
CustomCellTableBuilder buildRow = new CustomCellTableBuilder();
cellTable_2.setTableBuilder(buildRow);
The CustomCellTableBuilder for adding custom rows:
public class CustomCellTableBuilder extends AbstractCellTableBuilder<SearchColumn>{
public CustomCellTableBuilder() {
super(cellTable_2);
}
#Override
protected void buildRowImpl(SearchColumn rowValue, int absRowIndex){
//building main rows logic
if (labelrow == 1){
System.out.println("Going to build extra row if");
buildExtraRow(absRowIndex, rowValue);
}
else {
System.out.println("Getting into normal buildRow");
buildRow(rowValue,absRowIndex);
}
}
private void buildExtraRow(int absRowIndex, SearchColumn rowValue){
start(true);
TableRowBuilder row = startRow();
TableCellBuilder td = row.startTD().colSpan(getColumns().size());
td.text("Testing this out").endTD();
row.endTR();
}}
I think you should call start(true) before calling startRow() because tbody is initialized to null. Start() call will initialize tbody to HtmlBuilderFactory.get().createTBodyBuilder().
The source doesn't lie.
Just like that:
private void buildExtraRow(int absRowIndex, SearchColumn rowValue) {
start(true); // true makes builder to rebuild all rows
TableRowBuilder row = startRow();
// whatever
}

how to retrieve item ID from JList

I have a JList, where it displays names according to the DB. Associated with these names are IDs. for eg., foodId = 1, foodName = Chinese.
If i click on an item on the JList, i need to capture the foodID associated with the clicked foodName. i know a variable is needed.
when i have that value, I can pass that value into another method to retrieve the relevant food items associated with that foodId. Assume that getters & setters are done.
I have only the following, & am stuck. Please advise thank you.
list_1.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent evt) {
//alter text of Label acc to clicked item # JList
JList list = (JList)evt.getSource();
System.out.println (list.getSelectedValue());
//store int value of item clicked # JList
int temp = 0;
temp = ???????????
//populate JPanel
Food food = new Food();
JPanel panel = new JPanel();
panel.setBounds(153, 74, 281, 269);
panel.add(food.populateWithButtons());
contentPane.add(panel);
}
});
list_1.setBorder(new LineBorder(new Color(0, 0, 0), 0));
//populate JList
list_1.setModel(food.populateJList());
public ListModel populateJList()
{
DefaultListModel model = new DefaultListModel();
ResultSet rs = null;
DataAccessObject db = new DataAccessObject();
db.setUp("customer");
String dbQuery = "SELECT store_Owner_Id, food_Category FROM store_owner";
rs = db.readRequest(dbQuery);
try
{
while (rs.next())
{
food_Category = rs.getString("food_Category");
store_Owner_Id = rs.getInt("store_Owner_Id");
model.addElement(food_Category);
System.out.println (store_Owner_Id); //test DB conn & print retrieved items
System.out.println (food_Category);
}
}
catch (Exception e)
{
e.printStackTrace();
}
db.terminate();
return model;
}
Suggestions:
Don't populate the JList with Strings but rather ...
If you populate your JList with objects that contain both the name and the ID, then you're doing well.
You will likely want to give your JList a cell renderer that helps it to show the information from the object that you want the JList to display.
Then getting the ID is simply a matter of getting the selected item from the JList inside whatever listener you're using, casting it to the object type that in fact is, and then calling the getter method, such as getId(), assuming that objects of this type have this method, and then use your ID.
Note though that this tells us nothing useful:
list_1.setModel(food.populateJList());
If my suggestions don't help you answer your question, then please provide more useful information and code, information that will help us to fully understand your problem.
Edit 2
Your latest code shows that you're doing what I recommended that you not do:
while (rs.next())
{
food_Category = rs.getString("food_Category");
store_Owner_Id = rs.getInt("store_Owner_Id");
model.addElement(food_Category); // ****** here
System.out.println (store_Owner_Id);
System.out.println (food_Category);
}
You're adding Strings to your DefaultListModel, and by doing this you lose all the other information that the database gave you.
Again do not add Strings to this model. Create a class that has two or more fields, one for the category String, and one for the owner ID, that has getters, setters, and a constructor that allows you to pass this information into objects of the class, create objects of this class in your while loop above, and add these to the JList model. Then give your JList a custom renderer which is better than giving the custom object a toString() method for this purpose.
Create a custom class, say called FoodInfo
Declare the DefaultListModel as one that accepts objects of this type, DefaultListModel<FoodInfo>
Then add objects of this type to the model:
e.g.,
DefaultListModel<FoodInfo> model = new DefaultListModel<FoodInfo>();
// ... other code to get database info
while (rs.next()) {
String foodCat = rs.getString("food_Category");
int id = rs.getInt("store_Owner_Id");
FoodInfo foodInfo = new FoodInfo(foodCat, id);
model.addElement(foodInfo);
}
Edit 3
As has been noted in comment by #dic19, don't use a MouseListener on the JList but rather use a ListSelectionListener as described in the JList Tutorial.
See Combo Box With Hidden Data. It will show you how to use a custom object without the need for a custom renderer. I know the title is "Combo Box" but the concept is identical for a JList.
When you use a custom renderer you break the default functionality of JList since you will no longer be able to select items using the keyboard. A properly designed GUI should allow the use to use the mouse or keyboard to select an item.

Synchronize a jCombobox with a MySQL Table

I've created a database application with the NetBeans GUI-Designer.
GUI with Comboboxes (Bound to MySQL databasetables user and team):
on Button new -> jDialog - executes a query to store a new user in database:
Problem: Combobox is updated at the programstart but not while running the program.
Question: Is it possible to update the entries in my combobox directly when a new user or team is saved? And how could I Implement this?
Edit: Here is what I do when clicking on the saveButton in the JDialog:
int k=st.executeUpdate(
"INSERT INTO User (username) " + " VALUES ('"+ name + "')");
//Here I'd like to update the jComboBox1 directly if possible
Outerclass.jComboBox1...;
JOptionPane.showMessageDialog(null, "User is successfully saved");'
Just update your component's ComboBoxModel when you insert a new user in the database. If this is not helpful, please provide an sscce that exhibits the problem.
Addendum: Given a reference to a JComboBox,
private final JComboBox combo = new JComboBox();
you can update its model, as shown below. This example adds name to the beginning of the list, but SortedComboBoxModel is an appealing alternative.
DefaultComboBoxModel model = (DefaultComboBoxModel) combo.getModel();
model.insertElementAt(name, 0);
Addendum: More simply, use the method available to the combo itself,
combo.insertElementAt(name, 0);
I ran into a similar problem: if you enter anything into the database, that is supposed to be reflected in the JComboBox, then you can't change the values of that combo box. It would be great if you could add things to the JComboBox "on the fly" directly, but you have to get that data, create a new ComboBoxModel from it, and then set your JComboBox to that new model.
Here, I use DefaultComboBoxModel, which can either take an array of objects (usually strings) or a vector. If you use vectors to represent your underlying data model, that's a lot easier, since vectors are dynamic data structures.
My code:
Vector<String> s = new Vector<String>();
try {
// I'm using prepared statements, get the ResultSet however you like
ResultSet rs = myPreparedStatement.executeQuery();
while ( rs.next() ) {
// Change "1" to whatever column holds your data
s.add(rs.getString(1));
}
} catch (SQLException ex) {
ex.printStackTrace(); // or whatever
}
DefaultComboBoxModel jcbModel = new DefaultComboBoxModel(s);
jcb.setModel(jcbModel);
EDIT: Remember that ResultSet columns are 1-indexed, not 0-indexed! Gets me every time.

Categories

Resources