SWT windows hierachy and global data - java

After a few time enjoying the help of this site, the time to integrate myself here has come!
Well, I'm starting a personal project using java (under Windows 7), and I'm getting started with SWT. After a search of hours, I'm not satisfied with the short information I reached.
The project is an application where I will have a main window, from where the user can access to different modules (Customers Management, products management...).
What I want is to set properly:
A) I18n languagues
B) User preferences
"Properly" means a good,proper and easy access from all the components of the program to that data to use it, having in mind to do it through the most "standardized" way too.
I already created a package called "LanguagueResources", where I have the MessageBundle_xx_XX.properties, and I defined the following attributes on my MainMenu Class
protected String languague="en";
protected String country="UK";
protected Locale currentLocale=new Locale(languague, country);
protected ResourceBundle
messages=ResourceBundle.getBundle("MessageBundle",currentLocale);
With this, my main menu works fine with the different languagues. But what happens when I open a new window? maybe I can declare it this again (too much repeated code), or maybe I can pass some data when I call the new window instance (this doesn't look stylish). Same with other possible preferences settings.
This also makes me wonder how I must construct the program structre.I mean, is correct to start with a SWT Application window (Main Menu), and from there, call other SWT Application windows which will be the different modules (Customers, products)? Maybe must I establish an independent Main class where I will call MainMenu class, and where I will define the languague resources and preferences resources?
Also, I would like to know if the user preferences must be saved like the languages (.properties file)
I think I can do it trough many ways, but I would like to know which is the recommended,standarized and easiest way to do it.
I hope I explained well.Thanks in advance!

Related

How can I design User Preferences module in my Swing application?

I have dialog for storing user preferences of the application which is developed using Java Swing. There are 20+ preferences and I would like to notify other modules when the particular preference changes. I know that I can hold a list of listeners and notify them whenever the preferences change. However, I would like to know about two issues:
How can I bind my Swing components to a bean object,
How can I fire an event when the preferences change,
Dependending your experience, how would you resolve that architecture? What are the best practices to follow?
Thanks
I developed a Swing application where the user could modify some parameters to change functionality or the graphic of the application.
I approached it this way:
A general Setting abstract class represent a single value that the user can change.
A subclass is created for different types of value, in my case: boolean, integer, floating points, colors, etc.
I use a Map to keep track of the created Setting and a Preferences object to store the values.
For the actual settings, I create a static attribute somewhere (in my case, dedicated classes for different logical groups of settings) and use that attribute to read and change the values fo the settings.
PRO: The Settings keeps track of all the settings instantiated, so I don't need to code the frame for changing them twice, I just did it once in an indipendent way from the number of the settings
CONS: It clearly requires changing the code to add a new setting. While in my case it was not an issue because a new setting was needed only because of other changes in the code, in your case it might be.

need design/pattern/structure help on coding up a java 'world'

I've always wanted to write a simple world in Java, but which I could then run the 'world' and then add new objects (that didn't exist at the time the world started running) at a later date (to simulate/observe different behaviours between future objects).
The problem is that I don't want to ever stop or restart the world once it's started, I want it to run for a week without having to recompile it, but have the ability to drop in objects and redo/rewrite/delete/create/mutate them over time.
The world could be as simple as a 10 x 10 array of x/y 'locations' (think chessboard), but I guess would need some kind of ticktimer process to monitor objects and give each one (if any) a chance to 'act' (if they want to).
Example: I code up World.java on Monday and leave it running. Then on Tuesday I write a new class called Rock.java (that doesn't move). I then drop it (somehow) into this already running world (which just drops it someplace random in the 10x10 array and never moves).
Then on Wednesday I create a new class called Cat.java and drop that into the world, again placed randomly, but this new object can move around the world (over some unit of time), then on Thursday i write a class called Dog.java which also moves around but can 'act' on another object if it's in the neighbour location and vice versa.
Here's the thing. I don't know what kinda of structure/design I would need to code the actual world class to know how to detect/load/track future objects.
So, any ideas on how you would do something like this?
I don't know if there is a pattern/strategy for a problem like this, but this is how I would approach it:
I would have all of these different classes that you are planning to make would have to be objectsof some common class(maybe a WorldObject class) and then put their differentiating features in a separate configuration files.
Creation
When your program is running, it would routinely check that configuration folder for new items. If it sees that a new config file exists (say Cat.config), then it would create a new WorldObject object and give it features that it reads from the Cat.config file and drops that new object into the world.
Mutation
If your program detects that one of these item's configuration file has changed, then it find that object in the World, edit its features and then redisplay it.
Deletion
When the program looks in the folder and sees that the config file does not exist anymore, then it deletes the object from the World and checks how that affects all the other objects.
I wouldn't bet too much on the JVM itself running forever. There are too many ways this could fail (computer trouble, unexepected out-of-memory, permgen problems due to repeated classloading).
Instead I'd design a system that can reliably persist the state of each object involved (simplest approach: make each object serializable, but that would not really solve versioning problems).
So as the first step, I'd simply implement some nice classloader-magic to allow jars to be "dropped" into the world simulation which will be loaded dynamically. But once you reach a point where that no longer works (because you need to modify the World itself, or need to do incompatible changes to some object), then you could persist the state, switch out the libraries for new versions and reload the state.
Being able to persist the state also allows you to easily produce test scenarios or replay scenarios with different parameters.
Have a look at OSGi - this framework allows installing and removing packages at runtime.
The framework is a container for so called bundles, java libraries with some extra configuration data in the jars manifest file.
You could install a "world" bundle and keep it running. Then, after a while, install a bundle that contributes rocks or sand to the world. If you don't like it anymore, disable it. If you need other rocks, install an updated version of the very same bundle and activate it.
And with OSGi, you can keep the world spinning and moving around the sun.
The reference implementation is equinox
BTW: "I don't know what kinda of structure/design" - at least you need to define an interface for a "geolocatable object", otherwise you won't be able to place and display it. But for the "world", it really maybe enough to know, that "there is something at coordinates x/y/z" and for the world viewer, that this "something" has a method to "display itself".
If you only care about adding classes (and not modifying) here is what I'd do:
there is an interface Entity with all business methods you need (insertIntoWorld(), isMovable(), getName(), getIcon() etc)
there is a specific package where entities reside
there is a scheduled job in your application which every 30 seconds lists the class files of the package
keep track of the classes and for any new class attempt to load class and cast to Entity
for any newlly loaded Entity create a new instance and call it's insertIntoWorld().
You could also skip the scheduler and automatic discovery thing and have a UI control in the World where from you could specify the classname to be loaded.
Some problems:
you cannot easily update an Entity. You'll most probably need to do some classloader magic
you cannot extend the Entity interface to add new business bethod, so you are bound to the contract you initially started your application with
Too long explanation for too simple problem.
By other words you just want to perform dynamic class loading.
First if you somehow know the class name you can load it using Class.forName(). This is the way to get class itself. Then you can instantiate it using Class.newInstance(). If you class has public default constructor it is enough. For more details read about reflection API.
But how to pass the name of new class to program that is already running?
I'd suggest 2 ways.
Program may perform polling of predefined file. When you wish to deploy new class you have to register it, i.e. write its name into this file. Additionally this class has to be available in classpath of your application.
application may perform polling of (for example) special directory that contains jar files. Once it detects new jar file it may read its content (see JarInputStream), then call instantiate new class using ClaasLoader.defineClass(), then call newInstane() etc.
What you're basically creating here is called an application container. Fortunately there's no need to reinvent the wheel, there are already great pieces of software out there that are designed to stay running for long periods of time executing code that can change over time. My advice would be to pick your IDE first, and that will lead you someways to what app container you should use (some are better integrated than others).
You will need a persistence layer, the JVM is reliable but eventually someone will trip over the power cord and wipe your world out. Again with JPA et al. there's no need to reinvent the wheel here either. Hibernate is probably the 'standard', but with your requirements I'd try for something a little more fancy with one of the graph based NoSQL solutions.
what you probably want to have a look at, is the "dynamic object model" pattern/approach. I implemented it some time ago. With it you can create/modify objecttypes at runtime that are kind of templates for objects. Here is a paper that describes the idea:
http://hillside.net/plop/plop2k/proceedings/Riehle/Riehle.pdf
There are more papers but I was not able to post them, because this is my first answer and I dont have enough reputation. But Google is your friend :-)

Should I implement File Dialog as Singleton?

I'm developing a swing based application where I'm using many FileDialogs? So I say why not to make just one FileDialog object instead all of these instances and use it in the whole project? Is this a good assumption? does this have any performance improvement?
Thanks
This is a great example of a use case where application performance doesn't really matter and the question actually falls into the premature optimization class of problem solving. Why? Using FileDialog means that you are interacting with the user who, even if skilled beyond skilled with shortcut key Kung Fu, will be many orders of magnitude slower than the application. How many FileDialogs could a speedy user open, use and close in one minute? Say a dozen. You should not need to care about a dozen objects coming and going in one minute. Shouldn't even appear on your radar. Use your energies elsewhere. In fact, you should create a new object every time and avoid any caching headaches.
I would make a static FileDialog class that generates a new instance of the FileDialog each time a new one needs open rather than sharing a Singleton instance across the application.
That'll save you the headache of trying to figure out if you're reading the correct path from the dialog box or if somebody has opened the dialog and picked a new path and now you're referencing that new path rather than the originally selected path, etc...
Why implement is as a Singleton? Can you actually verify that displaying two file dialogs will never occur?
Better to have it as a regular class; you don't want to build in limitations which could become pain points later.
It isn't like your application is going to be critically overloaded by millions of calls to the file dialog, and who knows, perhaps someday it will be the right solution to have two file dialogs. Even if you don't display them both at the same time, perhaps holding the history in a "source" dialog and having a separate history in the "destination" dialog would be a blessing in a file transfer program.
Forget performance/speedyness. It doesn't matter here. Semantics matter. Reusing the same file dialog may give you things for free. Will the dialog start in the same directory every time? It will if it is the same instance. If you are creating new dialogs you will have to set startup dir your self.
Also why make it impossible to create more than one instance? Just make an instance member in your frame and be done with it.

How to create a custom 'new class wizard' for Eclipse?

I would like to create a functionality ( for myself ), wherein on clicking a button ( or say firing any event or anything that can trigger my program ), a popup will be displayed which will ask the name of the Class, objects it have and few more thing. Then on pressing OK, it will create a java file with skeleton of predefined methods, inherit known interface and ...
So, basically how to do that? Do i need to create a plugin for eclipse or there is something else in eclipse for it.
PS Please change the title. I am unable to think of any better one.
As others said, you want to create a wizard, then you want to augment the New Class Wizard, which is doing something similar to what you want (but the default wizard don't allow you to to add fields and custom methods).
To create a wizard, you can use the "New File Wizard" extension template: Create a plug-in, then, go to the extensions tab, select Add..., and select the "Extension Wizards" tab. That will get you started on Eclipse wizards.
Once you've learned the basics of creating Wizards and pages, then, include the org.eclipse.jdt.ui and org.eclipse.jdt.core in your plug-in dependencies. Open the following type (Ctrl-Shift-T): "NewClassWizardPage". This is the page that is displayed when you select New > Class in the Package Explorer.
You can probably either copy this page and the parent pages to help you get started or just extend it (in my experience, internal Eclipse wizards such as this one are difficult to extend because they have lots of fields and methods that are package/private, so I usually end up copying the code as a starting point... don't forget to keep the license though!).
You more or less want to add your own wizzard to the 'new class' dialog .. right?
This was the first site I found when typing "creating your own new wizzard eclipse" in Google: http://www.eclipse.org/articles/article.php?file=Article-JFaceWizards/index.html
I may be mis-understanding the question, but it sounds like you are re-implementing the New Class Wizard that exists already.
It lets you name the class, the containing package. Can assign a superclass and/or interface and can also choose if you want to include the contructors for the superclass.
A new .java file is created with all known methods from declared interfaces and also any abstract methods from the superclass.
Edt: Title was changed whilst I was writing this reply to "How to creat a customer 'new class wizard; for Eclipse". It makes my answer slightly redundant but I'm not seeing any new functionality being added in the question.

What are the best practices for internationalizing a Java Swing desktop application?

I'm sure there are a lot of methods, but what's the recommended way to do this that has the least amount of impact to your code?
The obvious is that you create properties files, but how do you swap the values in the rendering? In J2EE you always just re-render the whole page so it's easy. But in Swing apps, do you just add the code for the .getProperty() in the paintComponent(Graphics g) method?
If that's the case, doesn't it seem heavy since now you'll have to override this method everywhere where before you didn't need to...
Additional: How do you setup a notification system to re-render all currently visible components without forcing some kind of registration pattern?
I guess if I overwrite paintComponent(Graphics g) all I have to do is fire an event that something has changed and the paintComponent(Graphics g) method will be called...
As far as I know, some applications use layout/component builders (advised by Karsten Lentzsch, and part of JGoodies API). These builders include the code to localize components (using ResourceBundle under the hood).
Other people (me included) prefer resource injection; this is normally the least intrusive method. This is the way chosen by the Swing Application Framework (JSR-296) and other GUI frameworks like Guts-GUI.
You may also want to take a look at this question which is quite similar to yours.
Regarding changes of language "on the fly" (Locale change notification), I think it is easier to implement when using resource injection (I have implemented this in Guts-GUI already, Swing Application Framework may also have it but I am not sure about it).
Java offers no way to listen to Locale changes, hence you have to create you own "Locale service" (which any Locale change request should be addressed to). In this service, you would have to enumerate all visible windows (this is possible with Window.getWindows(), no need to register visible components before) and then inject resources again.
If you want an example, take a look at the resource package in Guts-GUI source code:
ResourceInjector shows resource injection and method to change Locale, which sends a notification event (uses an Event Bus for that, but simple listeners would be fine too) about this change
WindowController listens to Locale change events
The interesting code for updating all visible windows is copied hereafter:
for (Window window: Window.getWindows())
{
if (window.isVisible())
{
injectResources(window);
window.repaint();
if (window instanceof RootPaneContainer)
{
((RootPaneContainer) window).getRootPane().revalidate();
}
}
}
Supporting dynamic language changes is a tricky problem. The simplest solution is to organise your UI in such a way that you can recreate any visible panels. That avoids the need to register or update components, when the language changes you simply recreate the view.
Obviously you lose the state of all visible components which may be an issue - but that is usually the same in a web app when the page is refreshed.
Java 6 SE allows you to reload resource bundles on the fly.
Just call the clearCache() static function of the ResourceBundle class.
Then call getBundle () again.
See this article under Cache Controls
The only solution I came up with was to create a massive registry of all components that would need to be re-rendered. Then if a call is made to switch Locale you can just call the registry and it will go through all the registered components and adjust their values. So for example for all the registered JLabels it will do something along the lines of
for(JLabel specificJLabel : REGISTRY.registeredJLabels)
{
String localeKey = specificJLabel.getActionCommand();
specificJLabel.setText(ResourceBundle.getString(localeKey));
}
where the Locale key is stored in the components ActionCommand. Then whatever screen is currently being rendered, the main parent panel is responsible for re-rendering it. Also this way the registry doesn't have to manage the Locale keys, these are completely decoupled from the registry. Each component is responsible to manage it's own Locale Keys to the ResourceBundle.
What you need is a ResourceBundle that allows you to have properties file based on Locale that you just access like a properties file.
Here is a sample on how to do it

Categories