Impossible Java Memory Consistency Error - java

first of all I'm not an English native speaker so I apologize for any eventual “weird” writing.
I'm developing a Swing Java application on Eclipse that updates a Jpanel. This panel contains several sub-panels, and I'm constantly switching the panels “modes”, what happens to be a MouseListener changing so they respond in a slightly different manner to the user mouse inputs.
Regardless of what the application do, it's happening an error that seems to have no logical explanation to me. At some point in my code I try to update the panels to what I called neutralMode. This happens on the following method:
//Guarded block (see http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html)
private synchronized boolean waitsForUserSatisfactionAnswer()
{
while(!userIndicatedSatisfaction)
{
try {
wait();
} catch (InterruptedException e) {}
}
userIndicatedSatisfaction = false; //reset for future new query
getObjectSetVisualizationPanel().neutralMode();
//getObjectSetVisualizationPanel().queryPatternMode();
return userSatisfied;
}
This updating doesn't work (the call to neutralMode() dont do what is expected). However the call to queryPatternMode() (commented on the line right below) works perfectly. So I decided to COPY queryPatternMode()'s body and PASTE it on neutralMode()'s body ECXATLY THE SAME! AND IT STILL DOESNT WORK!
The methods code is like this:
public void queryPatternMode()
{
System.out.println("Inside queryPatternMode!!!");
System.out.println("panels.size(): " + panels.size());
for (DigitalObjectPanel panel : panels)
{
System.out.println("Inside the loop!!!");
panel.resetBehavior();
panel.setQuerySelectionBehavior(gui);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panel.validate();
}
});
}
}
public void neutralMode()
{
System.out.println("Inside neutralMode!!!");
System.out.println("panels.size(): " + panels.size());
for (DigitalObjectPanel panel : panels)
{
System.out.println("Inside the loop!!!");
panel.resetBehavior();
panel.setQuerySelectionBehavior(gui);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
panel.validate();
}
});
}
}
What happens is that, when I call neutralMode(), the “panels” collection happens to be empty (panels.size() equals zero). However when I call queryPatternMode() instead, the collection happens to have it's expected size (20 panels). But both methods are equals, and both are called from the same place!!!
What it could be??? Is there any possible explanation for that??

It definitely looks like a synchronisation issue. You should check how many threads are accessing the collection 'panels'.
It is just a stroke of luck that it works for you with queryPatternMode() all the time, and not with neutralMode(). On another fine day, it might be other way around.

Related

Display an image using EventDispatchThread vs without

So I'm trying to display an image(ball) which I'll eventually control with user input. For know, the image just gets displayed over intervals using thread's sleep method.
I've made 2 classes, one that extends JPanel and the other extends JFrame.
The JPanel subclass looks like this:
public class BallPanel extends JPanel {
private Image ball;
private int x,y;
public BallPanel(){
try {
ball=ImageIO.read(new File("C:\\Users\\Owner\\Desktop\\ball.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
x=10;
y=10;
Thread thread = new Thread() {
#Override
public void run(){
loop();
}
};
thread.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(ball,x,y,null);
}
public void loop(){
while(true){
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
In the loop method I call the sleep method to allow repaint to be called over intervals. Then, loop() is called in the constructor.
The JFrame subclass looks like this:
public class BallFrame extends JFrame {
public BallFrame(){
setVisible(true);
setSize(800,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setContentPane(new BallPanel());
}
public static void main(String args[]){
//SwingUtilities.invokeLater(new Runnable() {
// #Override
// public void run() {
new BallFrame();
// }
//});
}
}
Now the interesting, or perhaps confusing thing, is that when I run the code as it is shown here, with the anonymous inner class commented out, the ball doesn't always appear. Sometimes I need to re-size the frame (i.e call repaint) before the ball is shown. However, when I call it through the even dispatch thread using the anonymous inner class the ball appears every time I run the code. What is the reason for this?
It has little to do with starting the UI from within the EDT or not (although you should cause that can cause lots of other weird and interesting issues) and more to do with the fact that you've called setVisible before you've established the contents of the UI.
This is possibly an example of a race condition between the system trying to get the EDT up and running and the OS calls responding before it's established.
In either case you SHOULD start the UI from within the EDT and call setVisible last.
Swing can be lazy about updating the UI, this is actually a deliberate design choice as well as a good idea. You don't always want the UI updated after each and every change you make (like adding/removing components), so it hands over some of the control to the developer to decided when it's best to revalidate container hierarchy and request repaints
I would also avoid using a Thread to update the state of the UI as this could cause dirty paints as Swing uses a passive rendering approach (painting when it feels it's required) and consider using a Swing Timer which updated from within the EDT OR use a BufferStrategy and employ a active rendering approach, which you can then control

Concurrency in Java - wait for execution to be finished

So I am currently doing some work with Multi-Threading in Java and I'm pretty stuck on a, most likely, simple thing.
I currently have a JButton that, when pressed invokes the method as follows:
private void clickTest() throws InterruptedException{
statOrganizer.incrementHappiness();
Thread t = new Thread(new Happiness(workspaceHappy));
t.start();
}
and then takes around 10-30 seconds to complete. During this time however, it is still possible to re-click the JButton so that it messes with how the information is displayed.
What I want to do is during the time this particular thread is "alive", disable the button so that it is no longer possible to click it(and thus activate this thread once it's already going). Once the thread is finished, I want to re-enable the button again.
The button code just looks like this
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
if (evt.getClickCount() == 1) {
try {
clickTest();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Disable the button right before starting the thread. In the thread, at the end, post an event that would re-enable the button (using invokeLater).
You may also need a cancel option, but that's a separate question.
Try the following:
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
if (evt.getClickCount() == 1) {
try {
clickTest();
button.setEnabled(false);//this assume 'button' is final
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
Then, modify the run method of your Happiness class:
public void run()
{
//your processing code here
...
button.setEnabled(true);
//reference to button can be passed in constructor of Happiness
// or access using getter, ... This really depend on your implementation.
}
The nice solution for this is to use a glass pane to capture all events and stopping them from propagating to any of your UI elements on the panel under the glass pane. Of course while you only have one or two, you can call setEnabled(false) on them manually but glass panes give you more flexibility, you'll never have to worry about adding a new element to your UI and forgetting to disable it during background processing.
Probably an overkill for one button though.
Another, unrelated thing you should consider is the use of Executors instead of launching threads for background tasks. It results in cleaner and more scalable code.

Program displays filenames in a JTextArea as it walks the directory tree but I don't know how to stop it via a keypress

There are two windows: a GUI for user input and Output window for list of filenames found. Execution must be user-stoppable via a keypress and must leave both windows open because the program processes subdirectories, so it can run a long time, possibly stepping thru 100_000 files, either producing tons of output or none at all, depending on how user's filename pattern matches files encountered in the selected starting node.
Here's my question:
How do I look for a keypress (e.g., ESC or CTRL-C) to allow user to terminate? (Clicking red X isn't an option since that closes windows; user needs to see what's been found before termination. Doing so does not close either window anyway since all buttons are disabled once tree walk begins.)
I've tried putting keyListeners in several places, but once the "Start" button is clicked, all the swing components are disabled.
This seems like such a common situation that I'm surprised I can't find any textbook, thread, or Google info that directly answers the question. So I'm afraid it's not gonna be at all easy. That would be no surprise. I may have found a clue here but I can't get it to compile and the link contained there doesn't lead to that code snippet.
The search begins when the Search button is clicked:
private void jbSearchActionPerformed(ActionEvent evt) {
SearchyGUI.doIt();
}
The doIt() method walks the directory tree by an extension of SimplefileVisitor:
public class OverriddenFileVisitor extends SimpleFileVisitor<Path> {
...
}
public static void doIt(){
try {
visitor = new OverriddenFileVisitor();
info.setVisible(true);
Files.walkFileTree(SearchyGUI.p , visitor);
}
catch (Exception e) { }
}
}
Output is written to jTextArea1 via the report() method:
public static void report(String s){
Output.jTextArea1.append(s + "\n");
}
This is done primarily in the visitFile() method of SimpleFileVisitor:
public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException {
report(foundkt + "--" + f.getFileName().toString());
return FileVisitResult.CONTINUE;
}
Here's the main class:
public class SearchyGUI {
static Output info;
static Path p ;
static FileVisitor visitor ;
static GUI gui
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
gui = new GUI();
gui.setVisible(true);
}
});
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
info = new Output();
}
});
}
The problem is you are hogging the GUI thread, so the GUI thread can't process any events originating from the user.
You need to create a new Thread and do the work in there. Then, to display output from that thread, you can use SwingUtilities.invokeLater or something like that.
The Key Bindings API is probably the best choice for monitoring key strokes.
I would also add a [Cancel] button to the UI, which shared the same action...
public class CancelAction extends AbstractAction {
public CancelAction() {
putValue(NAME, "Cancel");
}
public void actionPerformed(ActionEvent evt) {
// Perform the cancel operation...
}
}
Then some where else in your code...
CancelAction cancelAction = new CancelAction();
JButton cancelButton = new JButton(cancelAction);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "Cancel");
am.put("Cancel", am);
Now the other problem you're going to have is the fact that you look like you are running a long running task within the context of the Event Dispatching Thread. This is going to prevent your program from being able to update the UI or allow the user to interact with the UI.
If you need to make changes to the UI (ie, show the output of the file processing), you should try a SwingWorker.
The main reason being is that it allows you to execute the long running task in another thread, but provides the mechanism for re-syncing updates back to the EDT, where it is safe to make changes to the UI.
Take a look at Concurrency in Swing for more details.
Regardless of which direction you take, you're going to need to supply a reference to the object that is carrying out the task and provide some kind of "cancel" flag, which the "task" object will need to monitor
The way I had left this program last night was unsatisfactory since Exit resulted in user not being able to see the output so far displayed (it could be useful). So I established window listeners and used the close event to set a boolean aborted to true to prevent further output to the window, but the thread kept running, which led to intermittent problems if another search was started before the thread ended.
Here's how I fixed it.
The FileVisitor interface has 4 methods to implement to walk the tree--two for each file visited, two for each directory. Each returns a FileVisitResult which is normally FileVisitResult.CONTINUE. By changing the return value to FileVisitResult.TERMINATE in the file visitor thread, it terminates appropriately! That is, I set a flag that the thread could check and take appropriate action, which is exactly what #MadProgrammer suggested.
public static FileVisitResult disposition = FileVisitResult.CONTINUE;
...
private static void report(String s){
if (! aborted)
try{
Output.jTextArea1.append(s + "\n");
}
catch (Exception e){
aborted = true ;
disposition = FileVisitResult.TERMINATE;
}
}
...
#Override
public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException {
f1 = new File(f.getParent().toString() + "\\" + f.getFileName().toString());
long filesize = f1.length();
report(f.getFileName().toString() + "\t found in " + f.getParent().toString());
return disposition;
}
I am one happy camper! Thank you BOTH for your ideas and input.
Well, I made it stop. I guess if you wander the woods long enough you'll find a gnome. I read Robin's hint last week and sort of gave up. Then I read some more and more. And then more. But Robin assured me that gnomes DO exist in these here woods!
The code I used was a modification of some I found for a MatLab/Java app. (Why'd I even look at it?? Best apparent Google hint.)
I made the "file visitor" (directory tree walker component) startable as a thread as Robin advised:
public class OverriddenFileVisitor extends SimpleFileVisitor<Path> implements Runnable{
// ................................................................^^^^^^^^^^^^^^^^^^^
In doIt() I made a couple of changes, moving the lines that process the directory to the now-runnable class and started the file visitor as its own thread in doIt():
public static void doIt(){
try {
new OverriddenFileVisitor().startTh();
//^^^^^^^^^^
//(moved) Files.walkFileTree(SearchyGUI.p , visitor);
...
I added the new method in the previous line to OverriddenFileVisitor class: (This is the main part of the MatLab/Java code that made sense to me so I used and modified it.)
public void startTh() {
Thread t = new Thread(this);
t.start();
}
And I inserted the overridden run() method for the class:
public void run() {
try {
Files.walkFileTree(SearchyGUI.p , this); // Used to be in doIt().
}
catch (IOException ex) { }
}
It ran and gave correct results and stopped when I hit Exit button, which "became" enabled after revising the file visitor to run in its own thread, which is what #Robin Green was saying. I almost feel like I know what I've done.
P.S. Note that I already was able to get my output via invokeLater()--last several lines of original question.
It's not finished but it's much more satisfactory.

Multiple JFrame application, how do I bring them all to front together?

My users like having multiple JFrames; it allows them to resize the different components and place them wherever they want on the screen. However, I have a request to make all the child windows come to the front together... in other words, lets say they maximize another window in front of all the windows, and then use the task bar to click on just one of the JFrames. How can I set it so that they all come to the front? Note: it is also possible to close the child windows; if they are actually hidden, I do not want them to come to the front. I have a class ApplicationModel that keeps track of whether a window is hidden or not.
Things I've tried:
Using windowActivated() and focusGained() to try to bring them all to the front. This usually results in an infinite loop. The problem is that my eventing framework sends these requests off the Event Dispatch Thread, so any sort of blocking with an AtomicBoolean doesn't last long enough.
The main problem is not that I can't make them come to the front... I have made them come to the front. The problem is that they KEEP trying to come to the front, as bringing a window to the front throws the focusGained and windowActivated events, which creates an endless loop...
Making one window the master, and making the others a JDialog. Unfortunately, either the windows are modeless (and therefore don't come to front with the master window), or they are modal, (and therefore block the master window).
How can I fix either of these problems, or is there an entirely different third solution?
You can use a boolean field as a flag to prevent the infinite loop:
private boolean movingAllFramesToFront;
public void windowActivated(WindowEvent event) {
if (movingAllFramesToFront) {
return;
}
movingAllFramesToFront = true;
List<Frame> frames = getAllApplicationFrames();
for (Frame frame : frames) {
if (!applicationModel.isHidden(frame)) {
frame.toFront();
}
}
event.getWindow().toFront();
event.getWindow().requestFocus();
EventQueue.invokeLater(new Runnable() {
public void run() {
movingAllFramesToFront = false;
}
);
}
Another thing you can try is the new autoRequestFocus property introduced in Java 1.7. I have never tried using it, but here's my understanding of how it works:
public void windowActivated(WindowEvent event) {
final List<Frame> frames = getAllApplicationFrames();
for (Frame frame : frames) {
if (!applicationModel.isHidden(frame)) {
frame.setAutoRequestFocus(false);
frame.toFront();
}
}
EventQueue.invokeLater(new Runnable() {
public void run() {
for (Frame frame : frames) {
if (!applicationModel.isHidden(frame)) {
frame.setAutoRequestFocus(true);
}
}
}
);
}
I have an application with a lot of windows and had a problem similar to yours. My workaround is:
#Override
public void windowActivated(WindowEvent e) {
if (e.getOppositeWindow() == null) {
//front every window
}
}
First I created a class "SlveFrame" (Slve being the name of my app), a child of "JFrame".
public class SlveFrame extends JFrame implements WindowListener {
static ArrayList<SlveFrame> frames = new ArrayList<SlveFrame>();
public SlveFrame () {
addWindowListener(this); / /to make JFrame fire WindowListener's method
}
/ /... every method added from WindowListener
#Override
public void windowActivated(WindowEvent e) {
if (e.getOppositeWindow() == null) { // return null if window is not from my (or Your) work
for (SlveFrame frame : frames) { // if you have no idea what this is, look for "for each loop java" in google
frame.toFront();
}
}
}
/**
* The use of SlveFrame is almost the same as Jframe
*/
#Override
public void setVisible (boolean b) {
if (b)
frames.add(this);
else
frames.remove(this); // may raise an exception if you're not careful
super.setVisible(b); // or your window will simply not be visible.
}
#Override
public void dispose () {
frames.dispose(this) // may raise an exception you'll want to handle
}
}
The trick being that WindowEvent.getOppositeWIndow() returns a Jframe if the JFrame (or child class) is from your own program, meaning that if you switch to another program or app (such as eclipse, Firefox or a text editor) then back to any of your windows, then a call to getOppositeWindow() will return a 'null'. A simple if (e.getOppositeWindow()) makes it fairly easy to determine whether your window gain focus in condition that would require you to bring every window to the front, or rather to let everything be.
The overriding of setVisible (boolean b) and dispose () are optional but allow the dev to use it as a regular window.
I hope i could be of some help. Sincerly ~a lama

Making FEST:s component lookup mechanism wait for a component to exist [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Making FEST to wait for the application to load
NOTE: This question is basically identical to this question. Since there were no answers to that question, I decided to extend the example from there into a runnable SSCE, and provide some additional information, hoping to get some help.
So, the question is about how you should handle component lookups when the sought component might not yet exist. Look at this simple one label GUI.
public class MyFrame extends JFrame {
JLabel theLabel;
public MyFrame() {
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
theLabel = new JLabel();
theLabel.setName("theLabelName");
computeLabelContentOnWorkerThread();
}
private void computeLabelContentOnWorkerThread() {
new SwingWorker<String, Void>() {
#Override
protected String doInBackground() throws Exception {
Thread.sleep(5000);
return "Info from slow database connection";
}
#Override
protected void done() {
try {
theLabel.setText(get());
add(theLabel);
pack();
setVisible(true);
} catch (InterruptedException ignore) {
} catch (ExecutionException ignore) {
}
}
}.execute();
}
}
And this test case:
public class TestOfDelayedComponent extends FestSwingJUnitTestCase {
FrameFixture frameWrapper;
#Before
public void onSetUp() {
MyFrame frame = GuiActionRunner.execute(new GuiQuery<MyFrame>() {
protected MyFrame executeInEDT() {
return new MyFrame();
}
});
frameWrapper = new FrameFixture(robot(), frame);
frameWrapper.show();
}
#Test
public void testLabelContent() {
String labelContent = frameWrapper.label("theLabelName").text();
assertTrue(labelContent.equals("Info from slow database connection"));
}
}
What happens? The construction of the label component is delegated to a slow worker thread. So the label will not appear right away when the GUI appears. When the test case is run, the label has not appeared, so when executing the component lookup at frameWrapper.label("theLabelName"), a ComponentLookupException is thrown.
The question is how do I prevent this exception from being thrown? If it was a top level component, I could do WindowFinder.findFrame("title").withTimeout(10000) to get a FrameFinder object which finds can find frames even if there is a delay before they appear. What I want is something similar to that, but for other types of components, such as e.g. a JLabel.
NOTE: Surely, it wouldn't be all that difficult to implement the functionality by yourself. It would be rather simple to do:
while(noComponentFound and notReachedTimeout){
look for component using FEST
sleep for a short delay
}
However, it would be nice to not be forced to clutter the test scripts with such loops. It feels as if waiting for components is not a too unusual task in test scripts. So, in my opinion, there ought to be support for doing this in FEST. Maybe this is not the case? Is it not possible to wait for components?
There is a way you can write Conditions for pausing and waiting. Here is the example for your needed while(noComponentFound and notReachedTimeout). This can be done with Pause.pause(new ComponentFoundCondition(...),timeout_milis). Example:
frame = WindowFinder.findFrame("frame0").using(robot);
//Wait for the event of loading tables in the GUI before we fail looking for them concurrently
final GenericTypeMatcher<JTable> matcher = new GenericTypeMatcher<JTable>(JTable.class) {
#Override protected boolean isMatching(JTable table){ return (table instanceof myTable && table.getColumnCount()<20); } //Condition has to be totally identitary for one particular component. If not, we will never reach condition and so a timeout will be thrown in next line
};
Pause.pause(new ComponentFoundCondition("Waiting for myTable to load before I look for it...", frame.robot.finder(), matcher, frame.target), 50000); //frame.target argument can be omitted. We also put an associated 50 sec timeout even if the condition is never satisfied
fixedTable = frame.table(matcher); //Look finally for the table now we are sure its loaded
You can play with different matchers. For example, if there were just one type of table myTable under the frame it would be much simple:
final ComponentMatcher matcher = new TypeMatcher(myTable.class); // We could use an easier TypeMatcher, because we would not need to add any additional distinction apart from the class type
Pause.pause(new Condition("Waiting for myTable to load...") { // If we are totally sure that there will be only one occurrence, we can use here the simplest form like above new ComponentFoundCondition("DebugMsg", frame.robot.finder(), matcher, frame.target)
#Override public boolean test() { return !frame.robot.finder().findAll(frame.target, matcher).size().isEmpty(); } // If not we need a custom condition that checks for >0 instead of =1 results like ComponentNotFound.
}, 50000);
The problem is too that (component->frame).table(matcher) does not accept a TypeMatcher, but just a GenericMatcher, so we should create GenericMatcher after all anyway
IF you can not find anything, theres always the alternative of fixing estatically a Pause.pause(5, TimeUnit.SECONDS);
I don't use Fest but Pause.pause looks interesting on this page:
http://www.pushing-pixels.org/2009/09/23/using-fest-swing-to-test-flamingo-components.html

Categories