I have java applet with JTable. Due to lots of data and poor network bandwidth it takes lots of time to perform any operation like load the table or change it.
I'm thinking about adding sort of activity indicator to let user know that his request is processing.
Before i use JProgressBar, I'd like to know whether there are other options like ajax activity flower.
The easiest way would be setting a (not animated) WAIT_CURSOR
// Setting cursor for any Component:
component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
doProcessing();
component.setCursor(Cursor.getDefaultCursor());
see http://www.catalysoft.com/articles/busyCursor.html
For an animated cursor see:
http://book.javanb.com/swing-hacks/swinghacks-chp-12-sect-2.html
SwingWorker was designed for this, as suggested in this example. In particular, "Note that it safe to mutate the tableModel from inside the process method because it is invoked on the Event Dispatch Thread."—publish()
You can use JBusyComponent for this. Just wrap your Table or the Scrollpane in the JBusyComponent. But remember to load the data outside the event dispatch thread. For this you can use the SwingWorker as suggested in the other answer. JBusyComponent already provides a BusySwingWorker for this.
Related
I am looking for advice in structure rather than particular coding.
My program has a Main class that initializes a GUI and then, after puting the name of the files that are going to be read, I click one button. I attached a listener with the respective mouseClicked event handler and I do all my routines INSIDE the handler.
This doesn't seem a good approach, is it? Is it usual to do things this way? All my program inside an event handler?
Is it usual to do things this way?
UI programming is event-based in Swing. Twisting it into any other style will not make it easier for you. What you might mean is that you should minimize the code in that UI part.
This means that you shouldn't tie the UI to the logic, therefore creating dense coupling. In this example, the file-reading code should be moved into another method, ideally in another class.
All my program inside an event handler?
To answer this specific question: No, that'd be terrible! It's okay to invoke your program from there, but don't write the code in the event-handler!
This doesn't seem a good approach, is it? Is it usual to do things this way? All my program inside an event handler?
You are right, this isn't a good approach. Instead look into implementing a Model-View-Control (MVC) type structure or one of its variants.
The Model: this is the brains of your program, the one that holds the program state. This should contain no GUI code, no listener code, just the data and the logic that goes with the data. The model should not implement a handler interface
The View: this is the GUI, here your Swing components and related code. The view should not implement a handler interface.
The Control: this is the connecting code between the two above, the code that handles user interactions, asks the model to change state. This may implement a handler interface, or have inner classes that do, or be composed of objects that do. Your control for instance could read in the file (in a background thread), supply the text to the model, and then the model could notify the view (or the control -- there are many variants of this) that its state has changed.
As an aside: don't give a JButton a MouseListener. Use an ActionListener instead.
There is no rules but only good practices.
And from Good Practice ethics, it is always advised to divide your code into small chunks, each one responsible for some stuff.
So you would better move your code outside the event handler and delegate the job to some method called readFiles() and call the later within your handler.
And even if this method can be cut into pieces you can do the same, e.g. it can only iterate over the files to be read and call a readFile() method for each one:
private void readFiles(Files[] files)
{
for(File file : files)
{
readFile(file);
}
}
Just a simple snippet and all should be updated to follow your model.
Firstly instead of providing a path to the file you can use
JFileChooser to do file selection operations. Especially since you
are using Swing.
Secondly one should attempt to modularize the code to an extent it
makes code looks simpler a d understandable. So you can create a
separate method that handles your file operations. The you can call
this function from any event handler. Be it mouse or keyboard. This
will avoid code duplication and will enable module reude.
I'm using Java Swing (Eclipse) to create a GUI and want to be able to display a continuously changing list in a panel. In my code this is a LinkedList of Objects and it will automatically reorder and change without any need for user interaction. What are the options for displaying this kind of list in the GUI? Thanks
One option, which I personally have used, is to have a method on the object containing this list, which, when called, modifies the data in the list, and then calls updateUI() which causes the UI to update without any user interaction. In order to detect whenever this list's data changes (I'm assuming you're looking at something external to the program) I would poll using another thread. The method you'd have on the object containing the list would have to be synchronized of course.
I hope this helps...
A Swing JList can take 3 types of collections as input.
An Object array - public JList(Object[] listData)
A Vector - public JList(Vector listData)
A ListModel - public JList(ListModel model)
You're going to have to convert your LinkedList into one of these 3 collections.
My recommendation is the ListModel. You can use a DefaultListModel, extend the AbstractListModel, or write your own class using the ListModel interface.
It is a very popular task when designing UI. To achieve your goals you need to follow next principles
Update your data in list
Send notification to UI Thread for update UI, here is a link to good tutorial
When to much data updates you need to limit amount of UI updates to acceptable (1 per 100 mills or smth), otherwise UI will suffer
I have a Table viewer with 3 columns and several rows (>4000).
When call tableviewer.setInput(myList) it takes forever and i'm ok with that but i wanted to implement a monitor so that the user can know what's going on but i have no idea how to start or where to call the monitor. Any help will be appreciated.
I assume that you are using SWT/JFace (you are not saying explicitly, but from the code snippet I guess you do).
Did you think about using SWT.VIRTUAL for you table?
Have a look at the TableViewer JavaDoc and the the ILazyContentProvider JavaDoc.
If you can't or don't want to use virtual tables, there's no easy way I know of to display a progress bar while performing setInput(), because setInput() has to be called from the UI thread and will block until finished. So there's not really a way of updating the UI while waiting for setInput to return (not if you don't implement the viewer and the setInput method yourself, at least)...
I'll make this short:
Is there a way / library in Wicket to show an activity indicator? You know, the spinning thing that moves while the user is waiting for something, or is it just a javascript thing?
Thanks for your help.
If this is an ajax operation then you can look at the implementations of IAjaxIndicatorAware. These implementations will show a 'spinner' while the operation is processing.
e.g. IndicatingAjaxButton and IndicatingAjaxLink
You could also look at AjaxIndicatorAppender and alter it your own needs for non ajax things ?
Check here to generate your own 'activity indicator'.
Simply show it when busy & hide it afterwards.
I think this will help
https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=87917
The Javascript and Css must be add in the renderHEad-Method
how can I add a listener to the computer's processor? I want the mouse cursor to change when the processing is hight.
You are going to have to drop to native code to get the CPU info. Here is an article on doing that.
You would have to write a class that then makes use of that native call and provides the API you want for the listener.
Edit:
Hmmm... you might also check out http://support.hyperic.com/display/SIGAR/Home.