I have some classes with fields and getters/setters and I want to display the fields of the class in a Swing application.
The name of each field should be dosplayed in a Label and the value should be displayed depending on the type of the value, i. e. String uses a TextField, List uses a ComboBox and so on.
One difficulty is that the class can contain fields, which also need to be treated this way itself.
Is there a recommended/standard way of doing that?
I looked a bit into java.beans but I'm not really sure if it isn't primarily used when the class is a Swing component itself.
Another option is to use PropertySheet component from L2FProd. From you description it should do exactly what you wanted.
It wasn't updated for a long time but works well.
I don't think there is an automated way to accomplish this. In fact I think you might even be approaching it incorrectly. What if you List contains objects other than Strings for example, how is a JComboBox going to break this out? I would suggest just using a JTable and putting the name in the first column and the value in a second column.
You could add #Annotations to your fields you want to examine and display in the GUI. In every case you have to use reflections to access and find all the fields you want to display. I think you have to add a custom logic to the databinding which examines a given class for it's fields (maybe filtered with a #Display annotation or stuff like this).
This should be very easy to implement, you can rely on the POJO Bean definition and access all the fields over getter/setter, don't forget to cache the handled classes to avoid circular dependencies of classes.
I hope this helps.
There is ReflectionUI. It can display primitive values objects and lists by just using reflection. It works well with getter/setter properties.
Related
I'm new to JavaFX and what I'm trying to do is I have a DTO object with 15 fields that I fetch from backend which I need to show all the fields in screen
for now what I did for each filed will create textfield in fxml file and inject it in the controller using textfield id then set the text for that from the dto for example
#FXML
TextField firstName;
........
firstName.setText(dto.getFirstName)
so is there is any other way than going through each textfield and using setText to set their value
As you state that you are new to JavaFX, I do not recommend that you try to implement the potential approaches in this answer.
Investigate the controlsfx BeanPropertyUtils, PropertySheet and PropertyEditor.
Different potential implementation strategies:
You could use a collection of TextFields, e.g. a list and assign values sequentially based on, for example, position in an sql row set.
Or perform a lookup on a map of strings to TextFields based on a column name key.
Or use reflection on Java Beans (this is how controlsfx works).
But none of them would be worth implementing unless you have a great many fields and need some generic system to handle values. Otherwise I wouldn’t recommend implementing such abstract functionality.
An example of a generic use case would be if you were introspecting on an unknown large database schema.
If you do need to do this, probably your best place to start would be the controlsfx library.
SceneBuilderKit, which was used to build SceneBuilder, has similar functionality but it is not as easily accesible as ControlsFX.
I advise you review the above comments then decide if you really want to do this.
If you do, then choose one potential strategy and implement it (this won’t be done in a StackOverflow answer).
If stuck, provide a complete minimal reproducible example for a concrete example and implementation attempt in code, only for the art of the problem you are stuck on. This allows you to create a more concrete question that is greatly reduced in scope.
How does language switching work in Java/Vaadin? I have a web application and would like to integrate a combo box, that changes the language of every text in this application. Do i need to mark each text that should get translated manually and define its translation? How complex is it to implement this function into an exting project?
Do i need to mark each text that should get translated manually and define its translation?
You should use ResourceBundles to store/read translations of strings.
How does language switching work in Java/Vaadin?
You need to provide a class that implements I18NProvider. Documentation about that can be found here
Once implemented correctly, you will be able to call getTranslation("HelloWorld") on any Component (and therefore on any view since they must extend a component), to receive the translation of the key "HelloWorld" defined in the ResourceBundle-file of the current UI-Locale.
Views that extend LocaleChangeObserver are notified when the Locale is changed, and then you can call getTranslation("HelloWorld") again to find the translation of the freshly set language.
I would like to integrate a combo box, that changes the language of every text in this application.
See this SO answer of mine where I posted example code of a Select component that acts as a language switcher. It is using both ResourceBundle and I18NProvider. (You can use a ComboBox too, but with the downside that you can only display a String for the selected value)
The important part in that code there is that the Select has a ValueChangeListener that sets the Locale of the VaadinSession, which in turn will trigger the localeChange method of the LocaleChangeObserver that your view now should implement. In the localeChange method, you can re-translate the translatable Strings of every component in the view; set new texts in Labels, set new labels and placeholders for TextFields, etc etc.
How complex is it to implement this function into an exting project?
That depends very much on your definition of complex, and how familiar you already are with ResourceBundles. There certainly are less complex topics than this, but I18N is never easy. In my opinion, Vaadin has done a very great job of providing us devs with a way to use I18N in our applications.
Most people use a sort of translation file system for their localization. Basically you make a text file for each language with a key and value system where you name every translated message with a key and a translated value. You can then use these keys (that should be predefined) to get the correct message for the language you want. These files can be anything really, but if you're looking for a simple java implementation then there are pretty simple ways to do it. For an example look here.
Did you look at this section of the documentation? https://vaadin.com/docs/v14/flow/advanced/tutorial-i18n-localization.html
I have defined a class which acts like a model/pojo. The class has many keys/variable. I have implemented custom solution for storing the POJO on disk for future uses. Now what I want to do is that whenever any value in the class/POJO is changed, I should call a method which sync the fresh changes with file on disk.
I know I can define setter for each variable. But it's quite tedious to do for 100s of direct and sub fields, and even if I define setter for each field, I have to call sync function from all the setters.
What I need is single proxy setter or interceptor for all change pushes to variables in class.
I am using this in an android application, so whenever the user enters new details in his/her account I have to store those details at that specific instance of time for preventing the data loss. I am using GSON for serialising and de-serialising.
Sorry for using vague terminologies, never been to college :|.
The easiest solution is indeed to use a setter. You only have to create one for each field you want to monitor, and most IDEs generate them for you or you can use something like Koloboke, so it being tedious isn't really an argument.
A proxy class or reflection would also be possible, but that is pretty hacky. Another way would be an asynchronous watcher/worker that checks for changes in you POJO instances, but even that seems unnecessarily complicated.
Apart from that you might need to rethink your POJOs structure if it has that many fields.
The problem with persisting(in your case writting to a disk) entity on each property update is that most of the updates are modifying more then one property. So in case you have a code like this:
entity.setA(avalue);
entity.setb(bvalue);
entity.setc(cvalue);
You would write it to the disk 3 times, which is probably not a best way, as it takes more resources, and 2 out of 3 writes are unnecessary.
There are several ways to deal with it. Imagine you have some service for saving this data to a disk, lets name it entityRepository. So one option is manually call this entityRepository each time you want to save/update your entity. It seems to be very uncomfortable, comparing to calling this automatically on setter call, however, this approach clearly shows you when and why your entity is persisted/updated, in your approach it's unclear, and can lead to some problems future problems and mistakes, for example, in future you will decide that you now need to update one of the properties without immideately persisting, then it appears that you will need 2 setter, one with update, and one without...
Another way is to add version property, and when its setter is called inside this setter call entityRepository.save(this).
The other way is to look at AOP, however anyway I don't recommend persist entity on any change, without having control over it.
You are talking about data binding. There is no built-in way for that so you have indeed to sync it yourself. Look into How to Write a Property Change Listener. There are also lots of other approaches to this, but as said no built-in way.
Let's say I have a gui, and the gui is composed of two parts where each part has its own class.
So one class contains a JLabel.
And second class contains a text field with a submit button.
How would I go about making those two components talk to each other?
This is of course a simple example, but if I have two classes where I use one for submitting data, and one for showing the submitted data, then how do I make the two components communicate?
Some thoughts:
Don't add such bindings to the GUI classes, look for a pattern like MVC
Unidirectional change propagation (input -> output as in your example) is usually never problematic, but in many cases, full synchronization of editable component groups is required. So one may keep that in mind during development of the simple case for good reusability of any custom class or interface.
Avoid infinite circular updates with a flag, rather than with a comparison of component values.
Whatever you do, keep things separated and whatever pattern you use, don't add bidirectional references (e.g. among GUI class <-> controller)
Regardless of MVC, there could be a controller class, getting all necessary references to the UI objects (i.E. JPanels with nested JTextFields and JLabels, etc.) via constructor.
On construction, that controller can attach itself to those nested components.
The controller should preferably contain nested, inner or perhaps anonymous classes for implementing the listener interfaces, rather than adding the listener interface to the controller itself. First, to encapsulate these listeners and second, to avoid the event source distinction, if the same interface needs to be implemented for multiple components (sources). These listener implementations (perhaps pretty generic PropertyChangeListener's) could then act as, or use mediator objects (as mentioned), for updating other components.
If you have a submit button, you can add an action listener to it. When clicked you can call a method in your other class that will receive the string and then display it on your JLabel. However having multiple classes for different components isn't usually a good idea, and having a MVC like what Sam said is much better.
Class with JTextArea
//Have this object created
JLabelClass JLC = new JLabelClass();
//When submit button is clicked run this
JLC.displayText(JTextArea.getText());
Inside Class with JLabel
//add this method
public void displayText(String text){
JLabel.setText(text);
//Refresh Gui and display stuff....
}
Hope this helped... Sorry about the formatting I'm still new to StackOverflow
I'm looking for something similar to the Proxy pattern or the Dynamic Proxy Classes, only that I don't want to intercept method calls before they are invoked on the real object, but rather I'd like to intercept properties that are being changed. I'd like the proxy to be able to represent multiple objects with different sets of properties. Something like the Proxy class in Action Script 3 would be fine.
Here's what I want to achieve in general:
I have a thread running with an object that manages a list of values (numbers, strings, objects) which were handed over by other threads in the program, so the class can take care of creating regular persistent snapshots on disk for the purpose of checkpointing the application. This persistor object manages a "dirty" flag that signifies whether the list of values has changed since the last checkpoint and needs to lock the list while it's busy writing it to disk.
The persistor and the other components identify a particular item via a common name, so that when recovering from a crash, the other components can first check if the persistor has their latest copy saved and continue working where they left off.
During normal operation, in order to work with the objects they handed over to the persistor, I want them to receive a reference to a proxy object that looks as if it were the original one, but whenever they change some value on it, the persistor notices and acts accordingly, for example by marking the item or the list as dirty before actually setting the real value.
Edit: Alternatively, are there generic setters (like in PHP 5) in Java, that is, a method that gets called if a property doesn't exist? Or is there a type of object that I can add properties to at runtime?
If with "properties" you mean JavaBean properties, i.e. represented bay a getter and/or a setter method, then you can use a dynamic proxy to intercept the set method.
If you mean instance variables, then no can do - not on the Java level. Perhaps something could be done by manipulations on the byte code level though.
Actually, the easiest way to do it is probably by using AspectJ and defining a set() pointcut (which will intercept the field access on the byte code level).
The design pattern you are looking for is: Differential Execution. I do believe.
How does differential execution work?
Is a question I answered that deals with this.
However, may I suggest that you use a callback instead? You will have to read about this, but the general idea is that you can implement interfaces (often called listeners) that active upon "something interesting" happening. Such as having a data structure be changed.
Obligitory links:
Wiki Differential execution
Wiki Callback
Alright, here is the answer as I see it. Differential Execution is O(N) time. This is really reasonable, but if that doesn't work for ya Callbacks will. Callbacks basically work by passing a method by parameter to your class that is changing the array. This method will take the value changed and the location of the item, pass it back by parameter to the "storage class" and change the value approipriately. So, yes, you have to back each change with a method call.
I realize now this is not what you want. What it appears that you want is a way that you can supply some kind of listener on each variable in an array that would be called when that item is changed. The listener would then change the corresponding array in your "backup" to refect this change.
Natively I can't think of a way to do this. You can, of course, create your own listeners and events, using an interface. This is basically the same idea as the callbacks, though nicer to look at.
Then there is reflection... Java has reflection, and I am positive you can write something using it to do this. However, reflection is notoriously slow. Not to mention a pain to code (in my opinion).
Hope that helps...
I don't want to intercept method calls before they are invoked on the real object, but
rather I'd like to intercept properties that are being changed
So in fact, the objects you want to monitor are no convenient beans but a resurgence of C structs. The only way that comes to my mind to do that is with the Field Access call in JVMTI.
I wanted to do the same thing myself. My solution was to use dynamic proxy wrappers using Javassist. I would generate a class that implements the same interface as the class of my target object, wrap my proxy class around original class, and delegate all method calls on proxy to the original, except setters which would also fire the PropertyChangeEvent.
Anyway I posted the full explanation and the code on my blog here:
http://clockwork-fig.blogspot.com/2010/11/javabean-property-change-listener-with.html