Refreshing Jtable after deleting object with hibernate? - java

populating table with initial data:
additionsTable.setModel(new AdditionalDocsTableModel(addDocuments));
constructor of the model:
public AdditionalDocsTableModel(List<MyDocument> docs) {
this.docs = docs;
}
Here's code in AbstractTableModel for deleting object from table:
public void delObjectAtRow(int row){
MyDocument doc= docs.get(row);
MainFrame.session.beginTransaction();
MainFrame.session.update(doc);
MainFrame.session.delete(doc);
MainFrame.session.beginTransaction().commit();
}
calling method:
private void deletePopupItemActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if (additionsTable.getSelectedRow() > -1) {
AdditionalDocsTableModel t = (AdditionalDocsTableModel) additionsTable.getModel();
t.delObjectAtRow(additionsTable.getSelectedRow());
}
}
How do i populate model with new data ? Right now i cant retrieve new data from session. i tried load and update. but receive same stuff as before deleting. Any help would be appreciated. thanks in advance!

You need to call one of the fire methods of the base class to notify JTable that the data has changed.

Related

How to refresh a JTable without setting a new table model?

I am trying to refresh a JTable using the DefaultTableModel without accessing the table itself again, but only the existing, but then updated table model.
Yet, I tried to update the table model itself and then notify the model about it (see in the code). For some reason, the table will not update. I do not know, if this is an access problem or if it is just not possible.
//in the Gui_Main class
private static void addTables(){
JTable tblMain = new JTable(Util_Tables.dtm);
}
//in the Util_Tables class, if the tables needs to be updated
public static DefaultTableModel dtm;
public static void updateTable(){
dtm = new DefaultTableModel(data, columns);
dtm.fireTableDataChanged();
}
So you're basic structure is all over the place. When you create a new instance of DefaultTableModel and assign it to dtm, this won't be reflected by the JTable, as it is still using the instance it first grabbed when it was created.
Exposing dtm the way you have, opens it up to undesirable modification and voids one of the principles of OO - encapsulation, where the class is responsible for the management of its properties. This is also a reason to reconsider the use of static
A better start would be to create a getter which returns a single instance of DefaultTableModel, so each call to it is guaranteed to return the same instance of DefaultTableModel and stops any one else from changing the underlying reference
private static void addTables(){
JTable tblMain = new JTable(Util_Tables.getModel());
}
//in the Util_Tables class, if the tables needs to be updated
private DefaultTableModel model;
public static DefaultTableModel getModel() {
if (model == null) {
model = new DefaultTableModel();
}
}
Okay, so how about updating the model? Well, you need to start by modifying your updateTable method, so it can be used to actually update the model in some meaningful way
public static void updateTable(Object[][] data, Object[] columnIdentifiers){
model.setDataVector(data, columnIdentifiers);
}
The model will then generate the events it needs itself. If you find yourself calling the fireXxx methods yourself, then it's a good indication that you're doing something wrong.

Cannot seem to write custom object to Firebase database?

I'm working on a project using Firebase, which I've never used before, and I know almost nothing about Firebase itself, as the rest of my team has been responsible for most of the dealings with it. I'm writing a parser for some Excel data where I need to extract some specific data and then upload it to Firebase. The parsing is done, but I'm having trouble writing it to Firebase.
We have a sub-database called "families" in our root database that I need to write this data to. I have a class called RegistrationSheet which contains all the data in this particular spreadsheet broken up into objects to represent the structure of the JSON. I'm aware that you can write custom objects to the Firebase database and it will be converted to a JSON format that represents that data. I found a page detailing the different data types that can be written to the database and converted to JSON, and among them were Map and List. So here are my classes that represent the "families" database.
RegistrationSheet.java:
public class RegistrationSheet {
public List<Object> families;
public void addFamily(Family f) { families.add(f); }
public RegistrationSheet() {
families = new ArrayList<>();
}
public void writeToFirebase() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("families");
ref.removeValue(); // Delete the data currently in the database so we can rewrite it.
ref.setValue(families);
}
public File outputJSON() {
return null;
}
}
Family.java:
public class Family {
public Map<String, Object> fields;
public void addField(String str, Object obj) { fields.put(str, obj); }
public Family() {
fields = new HashMap<>();
}
}
Child.java:
public class Child {
public Map<String, Object> fields;
public void addField(String str, Object obj) { fields.put(str, obj); }
public Child() {
fields = new HashMap<>();
}
}
The families list contains Family objects, and one of the "fields" that can be added to the Map in the Family objects is a List of Child objects. I figured that because these are all objects that are valid to write to Firebase, that simply writing the "families" list in the RegistrationSheet object would be enough:
public void writeToFirebase() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("families");
ref.removeValue(); // Delete the data currently in the database so we can rewrite it.
ref.setValue(families);
}
Is there something wrong with the structure of any of my classes or how I'm writing the data to Firebase? Because after executing this, the "families" sub-database disappears from Firebase and I have to restore it from my backup. It seems I have the correct DatabaseReference since removeValue() seems to be removing it, but why isn't it then writing the data from the families list?
I would appreciate any help that someone could provide.
Try the following code. It gives you the reason as to why it is not writing the value.
public void writeToFirebase() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("families");
ref.removeValue(); // Delete the data currently in the database so we can rewrite it.
ref.setValue(object, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference reference) {
if (databaseError != null) {
Log.e(TAG, "Failed to write message", databaseError.toException());
}
}
});
}
Then you can debug your code based on the Exception generated

Java: Proper way to update TableModel's data?

This is a simplifed version of what I'm trying to do. I have a map which maps an integer id to a list of strings. One of these lists from the map is displayed by a JTable at all times. (Depending on which id needs to be displayed) All information for the map is coming from a database, and is constantly being added to and removed from.
My DataClass which stores the full map and receives the updates from the database:
DataClass {
Map(Integer, List<String>) map;
// TabelModel gets list here
public List<String> getList(int id) {
return map.get(id);
}
// Updates from database come here
public updateList(int id, String info) {
if (map.containsKey(id) {
map.get(id).add(info);
}
else {
map.put(id, new List<String>(info));
}
}
// Remove from list, etc all down here
...
}
My Table model class:
MyTableModel extends DefaultTableModel {
List data;
public void updateData(int id) {
data = getList(id)
fireTableDataChanged();
}
... All the other stuff needed ...
}
Since database updates occur in batches, I know that at the end of a batch I have to update the table. So the DataClass informs the UI class which informs the table to update. This causes the updateData(id) to be called which retrieves a new set of data from the DataClass and calls fireTableDataChanged();
My Question are:
Is this the right way to go about updating/storing the data in the table?
Should getList return a clone of the data? If I just return the reference all updates from the database would be accessing that same reference and since these updates aren't running in the EDT wouldn't that be bad/frowned upon/wrong?
How can I do this using Java Events? PropertyChangeEvent? If so, how?
To the extent that your questions are related,
No; when new data is available, your updateData() method should update the internal data structure of your TableModel and fire an appropriate event; because DefaultTableModel knows nothing of your List, extend AbstractTableModel, as shown here; the JTable will update itself in response.
No; your database access layer should retain no references to queried objects, and no cloning should be necessary; forward queried objects to your display layer from the process() method of SwingWorker, or similar.
Use a TableModelListener to learn when and how the TableModel has changed; update the database accordingly.

SWT problems with saving data in the data base

I am trying to make an editable table by using swt, while I have trouble to save dates which are
modified in the database by using toplink:
if (referenceViewId.equalsIgnoreCase(TISTableViewPart.ID)) {
//TODO YUCHEN : Register and save objects in db
System.out.println("test");
final IViewPart viewPart = workbenchPage.findView(TISTableViewPart.ID);
final TISTableViewPart vdv = (TISTableViewPart) viewPart;
WorkingUnitMasterDataImpl sessionUow = new WorkingUnitMasterDataImpl();
Object test = vdv.getLocalComposite().getTableViewer().getElementAt(1);
sessionUow.registerObject(test);
try {
sessionUow.commitAndResume();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
By using
Object test = vdv.getLocalComposite().getTableViewer().getElementAt(1);
I can only get the object of the first colomne of the table, then I use
sessionUow.registerObject(test);
to save the change. Does someone have idea to get the whole table as an object in order to register and commitResume? Thanks in advance.
If you are using a TableViewer properly set up with a ContentProvider, it is assumed that the ContentProvider holds the all the elements the table contains.
Try to access these elements through the getElements() method in case you content provider implements IStructuredContentProvider.
Object[] elements = tableViever.getContentProvider().getElements();
In case you want to register to object changes, you can do that in the method setInput() ofthe ContentProvider. Indeed the javadoc for the IContentProvider interface suggests this method as the place for registering to changes.
If you need to access the input at a certain moment, the TableViewer object gives you access to your table input through the getInput() method:
Object tableInput = tableViewer.getInput();
Good luck!

In Wicket, why isn't my results refreshing after form submission?

I'm struggling with a very basic Wicket issue. I'm trying to query a backend database, but can't get the results to display. Below is the code I'm using. currentQuery and currentResult is correctly updated after submission, but my SearchResults class is never rerendered with the new data in currentResults. I suppose that the results class just doesn't notice that the model has in fact been updated. I've been experimenting with modelChanged, but can't get it to work. I'm a bit new to Wicket, so I'm probably doing something fundamental completely wrong. Any help is much appreciated!
public class SearchPage extends WebPage {
Query currentQuery = new Query();
Result currentResult = new Result();
public SearchPage() {
add(new SearchForm("searchForm", new CompoundPropertyModel<Query>(currentQuery)));
add(new SearchResults("searchResults", new PropertyModel<List<Hit>>(currentResult, "hits")));
}
public void doSearch(Query Query) {
currentResult = getResults(query);
}
public class SearchForm extends Form<Query> {
public SearchForm(String id, CompoundPropertyModel<Query> model) {
super(id, model);
add(new TextField<String>("query"));
}
protected void onSubmit() {
super.onSubmit();
doSearch(currentQuery);
}
}
public class SearchResults extends WebMarkupContainer {
public SearchResults(String id, PropertyModel<List<Hit>> model) {
super(id, model);
add(new ListView<Hit>("hit", model) {
protected void populateItem(ListItem<Hit> item) {
item.add(new Label("column", item.getModelObject().getColumnValue("column")));
}
});
}
}
}
PropertyModel uses reflection to look up the named property on a given target object instance. When you constructed the PropertyModel, you passed it a specific instance of Result, i.e. the new Result() from SearchPage's constructor. The PropertyModel will continue to hold a reference to that same Result instance from render to render of this page, serializing the Result at the end and then deserializing the Result at the start of each new request cycle (page view). The fact that you later change the page's currentResult variable to reference a different Result instance does not affect which Result instance the PropertyModel uses to look up its model value. Your PropertyModel does not care what currentResult later refers to.
There are two possible solutions that I can think of off the top of my head.
Have the PropertyModel read hits from the actual current value of the Page's currentResult variable:
new PropertyModel<List<Hit>>(SearchPage.this, "currentResult.hits")
Use a LoadableDetachableModel to load hits once per request cycle/page view:
new LoadableDetachableModel<List<Hit>>()
{
protected Object load()
{
return getResults(currentQuery);
}
}
Note that a LoadableDetachableModel has to be detached at the end of the request cycle or it will never again call getObject() to recalculate the List<Hit>. That said, since your code shows you'd be using it as the default model of the SearchResults component, the SearchResults component would detach the model for you at the end of the request cycle automatically.
I got it working. This seems to be the offending row:
add(new SearchResults("searchResults", new PropertyModel<List<Hit>>(currentResult, "hits")));
The type of the PropertyModel, i.e. List<Hit>, must have been making the model static. So the only data SearchResults ever saw was the initial object, which was empty.
I changed the line to the below, and updated SearchResult accordingly.
add(new SearchResults("searchResults", new Model<Result>(currentResult, "hits")));
If anyone can explain this further, or feel that I'm incorrect, please comment! In any case, I'm marking my own answer as correct as this solved the problem.

Categories