My data contained in such as Label and Images is dynamically updated and loaded from the server. How can I refresh or reload them without calling Display.getInstance().callSerially(.)?
If the text in my Label is updated, I'd like to update only that element itself. How can I do that? I can't seem to find any refresh() or reload() method.
Im not so sure, but I think can you add something like this:
yourlabel.repaint();
setText will update the text and repaint. However, if the text size is different layout might change so you will need a revalidate or animateLayout* call to reflow the UI otherwise things might not look as you'd expect in some situations.
If you are on a separate thread (e.g. network callback that isn't on the EDT) you need a callSerially to avoid an EDT violation and hard to detect device bugs.
Related
I want to get my event listener called when the component is repainted (JComponent). I read about different Event Listeners but none seems to be the correct one for Invalidate or Repaints. Any way to do this?
Why I want this: I'm trying to get notified when there is some change in a control, in order to fire the method that tracks the changes (as in the file has changed, "do you want to save changes?").
Another use for this is for manually invoking the custom layout manager of a non-added-to-the-container-but-drawn component (this one is kind of complex, it's for a GUI editor program).
Why I want this: I'm trying to get notified when there is some change in a control, in order to fire the method that tracks the changes (as in the file has changed, "do you want to save changes?").
Normally, you track changes to an edited file in the GUI model class. Every time your model adds or removes a character, you set a dirty flag in the model that you check later.
Another use for this is for manually invoking the custom layout manager of a non-added-to-the-container-but-drawn component (this one is kind of complex, it's for a GUI editor program).
Your understanding of Swing appears to be backwards. The components don't drive the layout. The layout arranges the components.
Here's one example of a Swing character based text editor.
Here's a Stack Overflow question about a GUI builder editor.
I'm using the card layout to create my app,
2 of my cards are shearing the same information (in one you enter data to textarea and in the other the data is printed).
The data is been saved in the Frame.
I have added a refresh function to the second card that get the value and print it, But I don't know how to trigger it.
Is there any event that can be bind to this function?
Or any other way to get to the card functions from the frame (so I can trigger it every time I show the card)?
Thanks'
There are generally two ways of achieving what you are after. Either you update/refresh the output card whenever it is displayed, like you suggested. This can be done by adding a ComponentListener to the Component that you use as your output card. This way you can override the componentShown method so that it calls your custom refresh method. See the accepted answer for this question.
The second alternative is to call refresh whenever any of the data is changed - always keeping it up to date, even when it is not actually visible. Depending on how your application looks this might be done in different ways. If you have a dedicated data model then you could use the Observer / Observable pattern to notify changed from an internal model, or you could hard-code the model to call refresh whenever it is changed. If you just want to get the data directly from the input fields on the first card, then you could just add that code into their respective change listeners etc.
I have a simple program that utilizes Java Swing Timer to display an image for 400 miliseconds, in this period of time I just want to stop all ActionListeners or stop taking ActionEvents. I've got 40+ buttons and want a simple way to do this.
Is there anyway to do that in Java?
Can you determine that you are in this "image displayed" state? The image goes up and you set the state to "image displayed" or whatever. Go through your widgets and decide which ones are supposed to be dead while the image is up. Turn them into Observers of this state value. When the state changes, they either enable or disable, as appropriate. The image code doesn't do anything directly to any widget. It just declares that the state is now "image displayed". It's up to the Observers to decide what to do, if anything, with that information.
Or use the GlassPane. That works too. Of course, the GlassPane shuts down everything. If you need to be more selective, you need a more fine-tuned approach.
You can use a temporary GlassPane instance to consume all events by registering empty listeners to it.
Use an undecorated modal JDialog to display the image. Before you make the dialog visible you would start a Timer. When the Timer fires in 400 ms you close the dialog.
I've had similar issues and typically found that its a design issue that got me in that situation. Being the case, I still had to find away around it. To fix the issue, I kept a list of the elements that I wanted to disable (stop listening) and iterated through them at the beginning and end of the timer. For buttons it should be as simple as:
for(Component c : listOfToggledComponents){
c.setEnabled(shouldItBeEnabled);
}
For buttons, this will grey out the button. Similar things happen to other swing components.
I'm new in Java/SWT. I'm experiencing some troubles using a SWT label.
When I update the text on the label, its size is not correctly updated (the label is cut, respecting the original size). However, if I perform a very small resize in my dialog, the size is updated correctly.
Basically, I create the label with a default text and then, when I load data I update the label with the real text, that is bigger than the original one.
I tried calling label.update() and label.redraw() without luck.
Try to call parent.layout(), where parent is the Composite which contains your label. Also see Understanding Layouts in SWT.
I know this is old, but in order to not lose any LayoutData settings that may be set on the controls. You should call getParent().requestLayout(). The documentation specifically discourages the user of getParent().layout() which loses all the cached Data settings on the controls.
Use of this method is discouraged since it is the least-efficient way to trigger a layout. The use of layout(true) discards all cached layout information, even from controls which have not changed. It is much more efficient to invoke Control.requestLayout() on every control which has changed in the layout than it is to invoke this method on the layout itself.
Based on the documentation of getParent().layout(), you should call requestLayout() on the control itself not its parent as #kingargyle said.
What I always did was label.requestLayout() and it worked flawlessly.
I'm trying to write an own layout manager.
Components must be placed and sized relative to each other.
This means: when the user drags or resizes an component, some other
components (but not the one altered manually by user) have to
be altered.
Swing tells the layout manager to layout the components every time when
some of them is moved/resized. This is a problem hence the layout
manager itself moves/resizes components:
It fails, the method
layoutContainer(Container parent) is called multiple times.
An example of the whole thing (simplified, in fact my layout manager does
more complex stuff):
[-component1-][-component2-------][-component3-]
user resizes component2 to be smaller, my layout manager would adjust
other components so that all of them would take same space as before:
[-component1-][-component2-][-component3-------]
here, the actions should stop, but they go on: now the layout manager
is invoked because of resizing component3
How could I achieve my intention (in an elegant way)?
Thank you.
EDIT:
Removed threading-related information after suggestions by answerers.
This kind of feedback loop is not uncommon when dealing with events. There are several approaches you can use to break out of this loop and the one I suggest you try is to keep track of the calculated sizes of the components. Then, when you handle the resize event, compare the actual size to the calculated size, and just return without doing anything if they are equal. This is probably the most robust approach as it doesn't depend on the order or frequency of the events. As stated elsewhere you shouldn't need to touch anything related to threads from your layout manager.
This isn't a thread synchronization issue.
You said that when users change the size or location of an object other objects must be altered. I'm guessing that you are listing for some kind of change event so that you can trigger a recalculation of the layout whenever the user changes an object. If so, I'm further guessing that your layout manager is triggering this event, causing it to be invoked again.
Of course, this is only speculation without reviewing your code.
I can't speak to the correct implementation of a layout manager, but as far as threading is concerned, all events in Swing are dispatched on the Swing UI thread, i.e. the same thread. Thus, synchronizing objects will have no effect because only one thread is ever involved. You can see what thread is invoking a method by printing Thread.currentThread() or inspecting it in a debugger.
Depending on what you're trying to do, you may want to take a look at miglayout. I've found it very powerful and easy to use. Correctly implementing a Swing layout manager is a non-trivial task.