I'm modeling a prototype that will use JavaFX.
The application will be similar with a kiosk, for self service. however before the client interact with it, the administrator should unlock it. The administrator will be able to send some remote commands, via a dedicated channel (HTTP or IPC or USB device). Examples of command would be: start, stop and reset
How should I do it?
a) Can I have a Task, running in another thread pooling actively an IPC and if there is message there, switch the Scene?
b) to have a reactor running in a thread and as soon receives a command, it pass it to the JavaFX thread.
are both options valid? does exist a third one?
Both your options (a) thread with Task and (b) thread without task are valid.
Recommended Solution
I'd choose option b (thread without a task).
The key part of the solution is the line:
Platform.runLater(() -> MyApplication.changeScene(newData));
Task is good, but probably not best for your situation
Task is good if you have something which is initiated by the UI or JavaFX thread. For example, the user clicks a button and you want to retrieve data from a server based upon that action, feeding back progress reports via messages and progress bar updates as the data is retrieved. So Task is very good for that kind of operation because it has explicit support for things such as the message feedback and progress updates as well as a well defined state model for when the task starts and completes. See invariants code example to understand how Task improves such situations: Platform.runLater and Task in JavaFX.
However, when the initiator of the event is off the JavaFX application thread, there isn't much advantage in using a Task versus just using traditional concurrency utilities. This is because you typically don't need the extra services that the Task is providing such as the progress and message update APIs and its state machine. Also, libraries that are initiating such events typically already have their own thread model setup, so you don't need the extra threading framework provided by a Task.
Using Platform.runLater()
All you really want is a notification that something happened. Now that notification needs to occur on the JavaFX application thread as you can't manipulate items in an active scene using another thread. To get an event passed to the JavaFX application thread, you use the Platform.runLater(runnable) construct.
Sample Code
I won't write Ruby, because I really can't, but here is some code in Java to give you the gist - it's actually really simple.
class DataReader implements Runnable {
private final DataSource dataSource;
public DataReader(String location) {
dataSource = new DataSource(location);
Thread thread = new Thread(this);
thread.setDaemon(false);
thread.start();
}
public void run() {
while (dataSource.hasData()) {
MyImmutableObject newData = dataSource.getSomeData();
Platform.runLater(() -> MyApplication.changeScene(newData));
}
}
}
class MyApplication extends Application {
public void changeScene(MyImmutableObject newData) {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"layout.fxml"
)
);
UIController controller =
loader.<UIController>getController();
controller.initData(newData);
Scene scene = new Scene((Pane) loader.load());
stage.setScene(newScene);
}
}
The above sample makes use of fictional DataSource, MyImmutableObject and UIController classes and a fictional FXML template to demonstrate the concept (so the snippet is not a standalone runnable thing). The FXML loading concepts come from: Passing Parameters JavaFX FXML. The sample code creates its own thread, but if whatever you library you are using already creates threads itself (which is likely), you don't need to create another one, you can just add appropriate hooks into the existing library with Platform.runLater calls to get the event notification and passing of data between the library threads and your JavaFX application.
Related Questions
There are numerous other questions on Platform.runLater versus Task on StackOverflow:
Javafx: Difference between javafx.concurent and Platform.runLater?
JavaFX 2: background and Platform.runLater vs Task/Service
Additional Questions
in my case, the administrator will be able, in some cases, to send an initial information to the kiosk, almost like an (initialization vector), for example the passport number. With this information, still the Platform.runLater the best solution?
Yes, Platform.runLater is still the best solution. You will have some thread which is alerted when the administrator sends the information to the kiosk (e.g. a servlet on an embedded http server or a jax-rs service) and it can invoke Platform.runLater to update the JavaFX based kiosk UI based on that info.
Related
I must say that I'm new to Java and JavaFX (less than 2 months), and also my UML skills are not perfect, so I might have used wrong blocks or/and connectors on the diagram :) But I hope you get an idea.
I have an order management app with a following (simplified to essentials) design:
OMS app design
Put very simply, the JavaFX GUI displays in a table view what is happening (i.e. the current state of the orders) between the client (that sends orders) and the broker (on the other end of the network connection). Order Manager is the only entity that has access to modify the model (i.e., the list of orders and their fields), and all methods modifying the model are synchronised (so it's safe to call them from any thread).
The orders are JavaFX beans, with different fields implemented as JavaFX Properties. These properties are bound to table columns in the GUI, so whenever the Order Manager updates a field, the change is propagated to the GUI via the binding mechanism.
Now, because the property binding mechanism is not thread-safe (see the following rule:
An application must attach nodes to a Scene, and modify nodes that are already attached to a Scene, on the JavaFX Application Thread.
), I have to wrap all the code modifying those fields, in Platform.runLater() calls, for example:
public void onOrderCanceled(int id, String reason) {
Order order = orderbook.get(id);
if(order == null) {
throw new IllegalArgumentException("Order "+id+ " not found");
}
Platform.runLater(() -> {
order.setReason(reason);
order.setStated(CANCELED);
subscribers.foreach(sub -> sub.notifyUpdated(order));
});
}
This approach has the following unpleasant implications:
The client notification is delayed by an arbitrary time (till the GUI thread finishes processing its message queue). Reason: I cannot notify the client before the order fields are updated (or it will have incorrect data), and I can only update the fields in the GUI thread.
Because the state of the order is not modified right away but at some future point, there exists for some time an incoherence between the order object and the actual order state.
If the GUI thread gets blocked or becomes very slow (because of bugs or design flaws), the client code is blocked or slowed down (while waiting for the notification that is stuck in the GUI thread's message queue).
Is there a better way of doing that? Ideally, I would like a solution that:
Allows the client code to communicate with the networking layer (via the order manager) as fast as possible, i.e. without waiting for the GUI to catch-up
The GUI is allowed to lag behind a little bit, but must not "skip" field updates, or at least never drop the most recent update (which is the most relevant)
Rely on the FX property binding architecture to update the GUI (which I find very convenient)
I feel that I need to create another "model" for the GUI that will be updated in the FX thread only, while the "real" model will be used by the order manager and the client code, and I need to ensure to maintain the two models in sync (which is creepy).
Was FX designed without multithreading in mind? I had a look on the Task and Service interfaces, but is doesn't look like something appropriate (in my case, GUI doesn't initiates a task - it comes from an external source, the client code or the network).
Thanks in advance!
If I understand this implementation correctly, you are performing the notification to remote clients on the FX Application Thread. You're doing this because you need to send the clients the updated version of the Order object, and since this object is bound to the table, changes to its state can only happen on that thread.
This is somewhat perilous, as those remote notifications may take time, and so you may block the UI thread, causing a lack of responsiveness. Additionally, you are forcing the logic of the application to wait for the (potentially blocked) UI thread. This is the opposite way around to the way you should be doing things: your application logic should flow in a thread of execution in a natural way, and you should arrange for the FX Application Thread to show the latest version of the data in as lightweight a way as possible on each frame rendering.
I think what you need here is a separate, immutable class to represent the updates. You'll send those to your clients, and then on successful notification update the UI, instead of driving the application from the UI. So something like
public abstract class Update {
private final int orderId ;
public Update(int orderId) {
this.orderId = orderId ;
}
public abstract void performUpdate(Order order) ;
public int getOrderId() {
return orderId ;
}
}
and
public class Cancelation extends Update {
private final String reason ;
public Cancelation(int orderId, String reason) {
super(orderId);
this.reason = reason ;
}
public String getReason() {
return reason ;
}
#Override
public void performUpdate(Order order) {
if (order.getId() != getOrderId()) {
throw new IllegalArgumentException("Wrong order");
}
order.setReason(reason);
order.setState(CANCELED);
}
}
Now in your application code you can do something like
public void onOrderCanceled(int id, String reason) {
Order order = orderbook.get(id);
if(order == null) {
throw new IllegalArgumentException("Order "+id+ " not found");
}
Task<Update> updateTask = new Task<Update>() {
#Override
public Update call() throws Exception {
Update update = new Cancelation(id, reason);
subscribers.forEach(sub -> sub.notifyUpdate(update));
return update ;
}
};
updateTask.setOnSucceeded(e -> updateTask.getValue().performUpdate(order));
updateTask.setOnFailed(e -> {
Exception exc = updateTask.getException();
// handle exception
});
subscriberNotification.execute(updateTask);
}
Now you schedule updates in an executor dedicated to that particular functionality, and then update the UI when you know the notification has happened. In other words, the UI responds to the application logic, instead of the other way around. Your clients now receive the details of the update, and presumably they have their own representation of the Order (perhaps instances of the same class), and can update their own representations using the information in the Update. Note this will likely save you network traffic too (probably the biggest bottleneck in your application), because you only communicate the changes, instead of the entire object. Of course, this might entail some major refactoring of your code (sorry about that...).
It's going to be important that the updates are all transmitted in the correct order, so you should use a single thread of execution for managing them. In other words, you need something like
private final Executor subscriberNotification = Executors.newSingleThreadedExecutor();
All,
I have appreciated many helpful answers on this site but I have found a need to post my first question (if you notice anything to be improved in my post let me know).
I have a modest sized Java program with GUI that is acting as a "middleman" and controller. On one end of the information flow it sends and receives data via an HTTP server. On the other it is interacting with an API where data is ultimately exchanging with a SmartCard. In the "middle" is the GUI, logging, and some other features.
There is also a feature (initiated via the GUI) to occasionally load an update to the SmartCard. Otherwise exchanges with the SmartCard are initiated over HTTP.
The problem is when switching between these 2 modes (communicating http to smartcard and then switching to loading the update or vice versa).
When I do that I have concluded I run into the problem of
CardException: Exclusive access established by another Thread
as thrown by sun.security.smartcardio
Searching the web shows the code that exception appears to come from is
void checkExclusive() throws CardException {
Thread t = exclusiveThread;
if (t == null) {
return;
}
if (t != Thread.currentThread()) {
throw new CardException("Exclusive access established by another Thread");
}
}
My first thought was I needed to instantiate the SmartCard API each time I need it (and then set it back to null) instead of once for the entire program like I had initially.
This works for the exchanges over http and I figure it is because each request to the handle() method is a new thread.
In the GUI the update is initiated by an ActionEvent which makes an instance of a CardUpdate. Inside that class then gets an instance of the SmartCard API.
I thought maybe I'd have better luck if when actionPerformed triggered I put the actions on a different, temporary, thread. So far, no.
The closest I got was using something like:
SwingWorker worker = new SwingWorker<ImageIcon[], Void>() {
as found at on Sun's website
Using that I could do an update and then go back to http exchanges but I couldn't do another update (per the one time use stipulation of SwingWorker)
I then tried making multiple SwingWorker as needed doing something like
private class GUICardUpdate extends SwingWorker<Integer, Void > {
but then I was back to my original problem. I have also tried to just do a simple additional thread off the GUI class in this fashion:
public class GUI extends javax.swing.JFrame implements ActionListener, Runnable
but this is no different.
Maybe I don't understand threads well enough or maybe I am overlooking something simple. Anyone have any ideas?
Thanks!
As far as I got you are using javax.smartcardio package (directly or indirectly) to work with your card. Some thread (created by you or by the framework you are probably using on top of javax.smartcardio) invoked beginExclusive() method on the Card instance to ensure exclusive access to the card.
The exclusive access is necessary as treatment of the data kept on the IC cards is state-depended, so the proper selection of data files and reading of their records requires the actions of application layer not to be interfered with actions of some other application or thread. For this purpose these three Card interface methods beginExclusive(), endExclusive() and checkExclusive() exist.
So you should check your(framework) code if it calls beginExclusive() and then doesn't call endExclusive().
I have a client/server question that i am trying to figure out the best solution for.
If a client ever gets disconnected from the server, for any reason, i would like a way for the input output thread to alert the gui thread that something went wrong, and thus have the gui thread print an error and gracefully handle it (probably drop back out to the login gui). After the initial gui thread is created, the client could change to any number of guis, depending on what he is doing, so I am thinking i need a way to dynamically see what gui is currently being run.
The way that i was thinking of doing this so far:
1) Create an object that creates and shows every gui. So instead of calling invokeLater...SomeGui.CreateAndShoGui()... we would have this object be responsible for doing that, ie GuiObject.showSomeGui();
2) Have each gui implement an interface, which will insure there is a method that, when called, will gracefully shutdown this gui when we have lost connection to the server.
3) Have a thread that monitors the IO thread and the gui object. If something goes wrong on the IO thread, the IO thread will close down and notify the monitoring thread that we have lost connection the server. The monitoring thread could then alert any open guis (from the gui object) that we have lost connection and that it needs to shut down.
I have just started thinking about this, and so far this is the best solution i have come up with. Does this seem like a reasonable solution that wont add too much complexity to the code? Or can anyone recommend a solution that would be simpler for people reading the code to understand?
Thanks
EDIT:
The other option i am toying with is having an object on the IO thread, that also gets passed to each new gui as it is opened. This object will give the currently opened guis reference back to the io thread, so that the io thread can alert it if something goes wrong. I am leaning against this solution though, because it seems like it would be easier to read if you had one object that was dedicated to get this working (like the above solution), instead of passing some obscure object to each gui.
Let me just go through each of your ideas:
1) Bad idea - you are tying your whole application together through a single object. This makes maintainability difficult and is the antithesis of modularity.
2) This is the way to go IMHO. Since it seems that each gui has unique logic in a failure scenario then it stands to reason that the object that best understands what to do would be the gui object itself.
Another version of this idea would be to create an adapter for each gui to put this failure logic into. The advantage would be you have one less dependency between your application framework and your gui. The disadvantage is that this is an extra layer of complexity. If your gui is already pretty coupled to your application then I would choose the interface method. If you want to reuse your guis in another application then the adapter way could help facilitate that.
3) This complements #2 nicely. So let me get this straight - you would have 3 threads: the IO thread, the monitor thread, and the UI thread. I don't know if you need the monitor thread. From what you were saying the IO thread would be able to detect a connection problem by itself (probably because some form of IOException was caught). When a connection problem is discovered the IO thread is not busy since it is just going to shut itself down soon so it might as well just have the responsibility of notifying the guis that there was a problem. The guis should have their interface method called on the UI thread anyways so the IO thread is just calling a bunch of invokeLater() calls (or asyncExec() calls for SWT) and then the IO thread can just shut itself down.
4) (Your Edit) You are basically describing the Visitor pattern. I do not think this is a good solution because the call is from the IO thread to the gui and not the other way around. I am not sure how passing a visitor object around will help in this case.
One final thought. If you make your interface generic (not gui specific) then you can apply this pattern to other resources. For instance you may want to flush your user credentials when you lose connection (since you talked about going to the login screen again). That isn't really gui logic and should not be done from a gui class.
Edit: I would use an event model. Let's say you create a interface like this:
public interface ConnectionFailureListener {
void handleConnectionFailure(); // Add an event object if you need it
}
You could then have registration methods in some object (maybe the Runnable for the IO thread or somewhere else that is convenient for you). These methods would be pretty standard:
public void addConnectionFailureListener(ConnectionFailureListener l) {}
public void removeConnectionFailureListener(ConnectionFailureListener l) {}
When you show a gui on the screen you would add it to your registration object and when you close the gui you would remove it from the registration object. You can add other types of objects as needed - for example when you log in you can add a listener for your credential system and remove it again when log out is processed.
This way when you have a failure condition you simply loop through the currently registered listeners and the listener does its thing.
Can someone tell me the TRUE difference?
My rule of thumb is that an AsyncTask is for when I want to do something tied to single Activity and a Service is for when I want to do something that will carry on after the Activity which started it is in the background.
So if I want to do a small bit of background processing in the Activity without tying up the UI I'll use an AsyncTask. I'll then use the default Handler from that Activity to pass messages back to ensure updates happen on the main thread. Processing the updates on the main thread has two benefits: UI updates happen correctly and you don't have to worry so much about synchronisation problems.
If for example, I wanted to do a download which might take a while I'd use a Service. So if I went to another Activity in my application or another application entirely my Service could keep running and keep downloading the file so it would be ready when I returned to my application. In this case I'd probably use a Status Bar Notification once the download was complete, so the user could choose to return to my application whenever was convenient for them.
What you'll find if you use an AsyncTask for a long-running process it may continue after you've navigated away from the Activity but:
If the Activity is in the background when your processing is complete you may have problems when you try to update the UI with the results etc.
A background Activity is far more likely to be killed by Android when it needs memory than a Service.
Use Service when you've got something that has to be running in the background for extended periods of time. It's not bound to any activity. The canonical example is a music player.
AsyncTask is great when some stuff has to be done in background while in the current activity. E.g. downloading, searching for text inside a file, etc.
Personally I use Handlers only to post changes to the UI thread. E.g. you do some computations in a background thread and post the result via handler.
The bottom line: in most cases, AsyncTask is what you need.
To complement the other answers here regarding the distinction between service and AsyncTask, it is also worth noting[0]:
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
Services tend to be things that describes a significant part of your application - rather than an AsyncTask which is typically contributes to an Activity and/or improves UI responsiveness. As well as improving code clarity Services can also be shared with other applications, providing clear interfaces between your app and the outside world.
Rather than a book I would say the developer guide has lots of good answers.
[0] Source: http://developer.android.com/reference/android/app/Service.html#WhatIsAService
AsyncTask: When I wish to do something without hanging the UI & reflect the changes in the UI.
E.g.: Downloading something on Button Click, remaining in the same activity & showing progress bar/seekbar to update the percentage downloaded. If the Activity enters the background, there are chances of conflict.
Service: When I wish to do something in the background that doesn’t need to update the UI, use a Service. It doesn’t care whether the Application is in the foreground or background.
E.g.: When any app downloaded from Android Market shows notification in the Status Bar & the UI returns to the previous page & lets you do other things.
Service
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with.
When to use?
Task with no UI, but shouldn’t be too long. Use threads within service for long tasks.
Long task in general.
Trigger: Call to method onStartService()
Triggered from: Any Thread
Runs on: Main thread of its hosting process. The service does not create its own thread and does not run in a separate process (unless you specify otherwise)
Limitations / Drawbacks: May block main thread
AsyncTask
AsyncTask enables the proper and easy use of the UI thread. This class allows performing background operations and publishing results on the UI thread without having to manipulate threads and/or handlers. An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread.
When to use?
Small task having to communicate with main thread
For tasks in parallel use multiple instances OR Executor
Disk-bound tasks that might take more than a few milliseconds
Trigger: Call to method execute()
Triggered from: Main Thread
Runs on: Worker thread. However, Main thread methods may be invoked in between to publish progress.
Limitations / Drawbacks:
One instance can only be executed once (hence cannot run in a loop)
Must be created and executed from the Main thread
Ref Link
I'm developing a java swing application that will have several subsystems. For all intents and purposes, let's assume that I am making an internet chat program with a random additional piece of functionality. That functionality will be... a scheduler where you can set a time and get a reminder at that time, as well as notify everyone on your friend list that you got a reminder.
It makes sense to organize this functionality into three classes: a GUI, a ChatManager, and a Scheduler. These classes would do the following:
GUI - Define all of the swing components and events
ChatManager - Create a chat connection, send and receive messages, manage friend list
Scheduler - Monitor system time, send notifications, store a file to remember events between sessions
For the program to work, each of these classes must be capable of communicating with the other two. The GUI needs to tell the ChatManager when to send a message and tell the Scheduler when to start monitoring. The ChatManager needs to display messages on the GUI when they're received, and finally, the Scheduler needs to both notify the GUI when it's finished, and send a status update or whatever to the ChatManager.
Of course, the classes as described here are all pretty simple, and it might not be a bad idea to just let them communicate with each other directly. However, for the sake of this question, let's assume the interactions are much more complex.
For example, let's say we can register a particular event with the scheduler instead of a particular time. When sending a message, I went to send it to the user, store it in a log file, create an event object and pass it to the scheduler, and handle any exceptions that might be thrown along the way.
When communication becomes this complex, it becomes difficult to maintain your code if communication with these classes can be happening in many different places. If I were to refactor the ChatManager, for example, I might also need to make significant chaneges to both the GUI and Scheduler (and whatever else, if I introduce something new). This makes the code difficult to maintain and makes us sleep-deprived programmers more likely to introduce bugs when making changes.
The solution that initially seemed to make the most sense is to use the mediator design pattern. The idea is that none of these three main classes are directly aware of each other, and instead, each is aware of a mediator class. The mediator class, in turn, defines methods that handle communication between the three classes. So, for example, the GUI would call the sendMessage() method in the mediator class, and the mediator would handle everything that needed to happen. Ultimately, this decouples the three main classes, and any changes to one of them would likely only result in changes to the mediator.
However, this introduces two main problems, which ultimately resulted in me coming here to seek feedback. They are as follows:
Problems
Many tasks will need to update the GUI, but the Mediator isn't aware of the components. - Suppose the user starts the program and enters their username/password and clicks login to login to the chat server. While logging in, you want to report the login process by displaying text on the login screen, such as "Connecting...", "Logging in...", or "Error". If you define the login method in the Mediator class, the only way to display these notifications is to create a public method in the GUI class that updates the correct JLabel. Eventually, the GUI class would need a very large amount of methods for updating its components, such as displaying a message from a particular user, updating your friend list when a user logs on/off, and so on. Also, you'd have to expect that these GUI updates could randomly happen at any time. Is that okay?
The Swing Event Dispatch Thread. You'll mostly be calling mediator methods from component ActionListeners, which execute on the EDT. However, you don't want to send messages or read/write files on the EDT or your GUI will become unresponsive. Thus, would it be a good idea to have a SingleThreadExecutor available in the mediator object, with every method in the mediator object defining a new runnable that it can submit to the executor thread? Also, updating GUI components has to occur on the EDT, but that Executor thread will be calling the methods to update the GUI components. Ergo, every public method in the GUI class would have to submit itself to the EDT for execution. Is that necessary?
To me, it seems like a lot of work to have a method in the GUI class to update every component that somehow communicates with the outside, with each of those methods having the additional overheard of checking if it's on the EDT, and adding itself to the EDT otherwise. In addition, every public method in the Mediator class would have to do something similar, either adding Runnable code to the Mediator thread or launching a worker thread.
Overall, it seems like it is almost as much work to maintain the application with the Mediator pattern than to maintain the application without it. So, in this example, what would you do different, if anything?
Your GUI classes will end up with many methods to keep it up to date and that is fine. If it worries you there is always the option of breaking up the GUI into sub GUIs each with a different functionality or a small set of related functionality. The number of methods will obviously not change, but it will be more organised, coherent and decoupled.
Instead of having every method in your GUI create a Runnable and use SwingUtilities.invokeLater to put that update on the EDT I'd advise you to try out another solution. For my personal projects I use The Swing Application Framework (JSR296) which has some convenient Task classes for launching background jobs and then the succeed method is automatically on the EDT thread. If you cannot use this you should try and create your own similar framework for background jobs.
Here, a partial answer to you design questions...
It looks like you want to have loose coupling between your components.
In your case, I would use the mediator as a message dispatcher to the GUI.
The ChatManager and the Scheduler would generate UpdateUIMessage.
And I would write my GUI that way
public class MyView {
public void handleUpdateMessage(final UpdateUIMessage msg){
Runnable doRun = new Runnable(){
public void run(){
handleMessageOnEventDispatcherThread(msg);
}
};
if(SwingUtilities.isEventDispatcherThread()){
doRun.run();
} else {
SwingUtilities.invokeLater(doRun);
}
}
}
So you have only one public method on your GUI, which handles all the EdT stuff.
If you want to have a loose coupling between the GUI and the other components (meaning : you do not want the GUI to know all the API of the other components), the GuiController could also publish ActionMessage (on a specific Thread?), which would be dispatched by the mediator to the other components.
Hope it helps.
Well, I will change the world you are working with. You have 3 classes and each of them is just observer of the chat-world. The MVC is the way how to deal with your problem. You had to create Model for your world, in this case chat program. This model will store data, chat queue, friend list and keep eye on consistency and notify everybody interested about changes. Also, there will be several observers which are interested in state of world and are reflecting its state to user and server. The GUI is bringing visualization to friends-list and message queue and reacts on their changes. The Scheduler is looking about changes in scheduled tasks and update model with their results. The ChatManager will be better doing its job in several classes like SessionManager, MessageDispatcher, MessageAcceptor etc. You have 3 classes with empty center. Create center and connect them together using this center and Observer Pattern. Then each class will deal only with one class and only with interesting events. One GUI class is bad idea. Divide to more subclasses representing logical group (view of model). This is the way how to conquer your UI.
You might want to look at a project that originally started as a MVC framework for Flex development. PureMVC has been ported to many programming languages meanwhile, including Java. Though it is only in a alpha status as of writing this!