Event dispatching thread remove from List exception SWING - java

Hi I have this strange exception when trying to remove a element from list in JPanel which implements the State interface. Here is the code:
public static class ButtonListener implements ActionListener {
private State state;
public ButtonListener(State state) {
this.state = state;
}
#Override
public void actionPerformed(ActionEvent e) {
state.applyMove(state.getMoves().get(0));
}
}
And the JPanel where is the implementation of "applyMove" method:
public class RushHourBoard extends JPanel implements MouseListener, MouseMotionListener, State {
...
private List<Vehicle> vehicles;
...
#Override
public State applyMove(Move vehicleMove) {
VehicleMove move = (VehicleMove) vehicleMove;
Vehicle moved = move.getVehicle();
vehicles.remove(moved);
...
And the trace of the exception:
Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at entrery.rushhour.RushHourBoard.applyMove(RushHourBoard.java:174)
at entrery.rushhour.MyDragDemo$ButtonListener.actionPerformed(MyDragDemo.java:59)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6504)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6269)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4860)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2713)
at java.awt.Component.dispatchEvent(Component.java:4686)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:680)
at java.awt.EventQueue$4.run(EventQueue.java:678)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:677)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Is this something with UI thread security policy ? Thanks in advances for your help.

The instance assigned to RushHourBoard.vehicles does not support removal. Perhaps it is from Arrays.asList or Collections.unmodifiableList.
List, like many in Java collections, is a poor interface. It's so unspecific many of the methods may not be implemented (usefully). Even with a loose contract, many of the collection implementations don't even conform to the minimal terms of the interfaces they implement.

Related

Java Swing Null Pointer Exception in Netbeans IDE

I'm still fairly new to Java and I've started on a simple GUI project with the netbeans java IDE 8.2 using swing and am running into a null pointer exception.
I've removed the majority of the code down to the bottom portion in order to try and find where the issue is coming from and I still get an exception running only these lines of code.
package finalmodel;
import javax.swing.*;
public class FinalModel extends JFrame {
public static void main (String[] args) {
new FinalModel();
}
public FinalModel () {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
}
The application runs fine, and as far as I can tell, the exception doesn't affect functionality (a window pops up and can be successfully closed from the above code), but the exception is thrown upon the window's closure.
The stack trace given to me by the IDE is
java.lang.NullPointerException: peer
at sun.awt.windows.WInputMethod.openCandidateWindow(Native Method)
at sun.awt.windows.WInputMethod.access$400(WInputMethod.java:45)
at sun.awt.windows.WInputMethod$1.run(WInputMethod.java:602)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
at java.awt.EventQueue$4.run(EventQueue.java:733)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:159) [catch]
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Version Info
your example is very minimal. it might be missing some properties. give this a try:
package finalmodel;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FinalModel extends JFrame {
public FinalModel () {
setTitle("setTitle()");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
FinalModel fm = new FinalModel ();
fm.setVisible(true);
}
}
here's a good article on jframe, for practice jframes
Netbeans bug! Reinstall Netbeans with un updated version or something like that.

JavaFX with Junit

I would like to test methods that have JavaFX scene elements like TextField or DatePicker. I found here How do you unit test a JavaFX controller with JUnit how to run test for JavaFX app and it works fine for me if I have just one test class where Thread is initialized. But what about if I have two classes? I am not able to initialize the same thread with launch method because exception will be thrown. If I will not create thread in second test class there is also another exception. Below you can find test classes and stack trace. I was also thinking about stopping this thread in method with #AfterClass annotation and then starting it in second class again but I do not think it is possible. Does anyone can help me?
FirstTestClass
#RunWith(PowerMockRunner.class)
#PrepareForTest({TextField.class, DatePicker.class})
public class FirstTestClass {
#BeforeClass
public static void javaFXInitializer() throws SQLException, InterruptedException {
Thread thread = new Thread("JavaFX Init Thread") {
public void run() {
Application.launch(Main.class);
}
};
thread.setDaemon(true);
thread.start();
Thread.sleep(5000);
}
#Test
public void firstTest() {
TextField textFieldMock = mock(TextField.class);
DatePicker datePickerMock = mock(DatePicker.class);
TestClass objectUnderTest = new TestClass();
when(textFieldMock.getText()).thenReturn("2000");
when(datePickerMock.getValue()).thenReturn(LocalDate.of(1992,1,1));
//rest of code to test
}
}
SecondTestClass
#RunWith(PowerMockRunner.class)
#PrepareForTest({TextField.class, DatePicker.class})
public class SecondTestClass {
#BeforeClass
public static void javaFXInitializer() throws SQLException, InterruptedException {
Thread thread = new Thread("JavaFX Init Thread") {
public void run() {
Application.launch(Main.class);
}
};
thread.setDaemon(true);
thread.start();
Thread.sleep(5000);
}
#Test
public void firstTest() {
TextField textFieldMock = mock(TextField.class);
DatePicker datePickerMock = mock(DatePicker.class);
TestClass objectUnderTest = new TestClass();
when(textFieldMock.getText()).thenReturn("5000");
when(datePickerMock.getValue()).thenReturn(LocalDate.of(1990,1,1));
//rest of code to test
}
}
Exception when I initialize thread in two classes
Exception in thread "JavaFX IncomeTest Init Thread" java.lang.RuntimeException: java.lang.UnsatisfiedLinkError: Native Library C:\Program Files\Java\jdk1.8.0_144\jre\bin\glass.dll already loaded in another classloader
at com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:267)
at com.sun.javafx.application.PlatformImpl.startup(PlatformImpl.java:211)
at com.sun.javafx.application.LauncherImpl.startToolkit(LauncherImpl.java:675)
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:695)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.UnsatisfiedLinkError: Native Library C:\Program Files\Java\jdk1.8.0_144\jre\bin\glass.dll already loaded in another classloader
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1907)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at com.sun.glass.utils.NativeLibLoader.loadLibraryFullPath(NativeLibLoader.java:201)
at com.sun.glass.utils.NativeLibLoader.loadLibraryInternal(NativeLibLoader.java:94)
at com.sun.glass.utils.NativeLibLoader.loadLibrary(NativeLibLoader.java:39)
at com.sun.glass.ui.Application.loadNativeLibrary(Application.java:112)
at com.sun.glass.ui.Application.loadNativeLibrary(Application.java:120)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$1.run(WinApplication.java:118)
at com.sun.glass.ui.win.WinApplication$1.run(WinApplication.java:91)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.glass.ui.win.WinApplication.<clinit>(WinApplication.java:91)
at com.sun.glass.ui.win.WinPlatformFactory.createApplication(WinPlatformFactory.java:39)
at com.sun.glass.ui.win.WinPlatformFactory.createApplication(WinPlatformFactory.java:36)
at com.sun.glass.ui.Application.run(Application.java:146)
at com.sun.javafx.tk.quantum.QuantumToolkit.startup(QuantumToolkit.java:257)
... 5 more
Exception when Thread is initialized only in first class
java.lang.ExceptionInInitializerError
at sun.reflect.GeneratedSerializationConstructorAccessor12.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:45)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:14)
at org.powermock.api.mockito.repackaged.ClassImposterizer.createProxy(ClassImposterizer.java:149)
at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:64)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:121)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:69)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46)
at org.powermock.api.mockito.PowerMockito.mock(PowerMockito.java:141)
at
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:326)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:298)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:218)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:160)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:134)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:136)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:57)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268)
at com.sun.javafx.application.PlatformImpl.setPlatformUserAgentStylesheet(PlatformImpl.java:550)
at com.sun.javafx.application.PlatformImpl.setDefaultPlatformUserAgentStylesheet(PlatformImpl.java:512)
at javafx.scene.control.Control.<clinit>(Control.java:87)
... 50 more
Create a class MockApp extends Application and have a static method init(). In that method create a new single thread in which to invoke the JavaFX platform start (basically what you've done already) with an appropriate guard. The guard (a boolean flag) guarantees that the method gets called maximum once. The point is that the thread never terminates, thus allowing you to access the JavaFX platform during the lifetime of all your tests. The catch is you need to add something like:
#BeforeClass
public void init() {
MockApp.init();
}
for each test class where you use JavaFX since you don't know the order in which tests run.
The approach (with minor changes) can be seen in practice here.

ConcurrentModificationException but not removing anything from ArrayList

So I'm making a game and every 5 seconds there must spawn an enemy, know when I run my application it throws an exception 'ConcurrentModificationException'.
This is a part of my code:
private void tick() {
exec.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
enemyY = enemyYRand.nextInt(6);
enemy.add(new Enemy(enemyY, 10, enemyImg));
}
}, 0, 5, TimeUnit.SECONDS);
if (player.y > getHeight() - playerImg.getHeight(null)) {
player.setY(-10);
}
if (player.y < 0) {
player.setY(+10);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(Enemy enemys : enemy) {
enemys.render(g);
}
player.render(g);
}
First the tick method get's called then paintComponent method.
This is the output:
Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at _47b3n.spaceinvaders.framework.Main.paintComponent(Main.java:141)
at javax.swing.JComponent.paint(JComponent.java:1053)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5223)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:290)
at javax.swing.RepaintManager.paint(RepaintManager.java:1265)
at javax.swing.JComponent._paintImmediately(JComponent.java:5171)
at javax.swing.JComponent.paintImmediately(JComponent.java:4982)
at javax.swing.RepaintManager$4.run(RepaintManager.java:824)
at javax.swing.RepaintManager$4.run(RepaintManager.java:807)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:807)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:782)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:731)
at javax.swing.RepaintManager.access$1300(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1720)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
It appears that you have 2 threads each operating on an ArrayList at the same time.
One of them is in the event dispatch thread, where paintComponent is called. You are using an enhanced for loop, which uses an Iterator internally. This iterator is what is throwing the ConcurrentModificationException.
You are modifying the ArrayList in the tick method, in some other thread, when you call enemy.add(new Enemy(enemyY, 10, enemyImg));.
The Iterator noticed that the ArrayList was modified and threw the exception. When you are displaying the enemies, it is necessary to have a consistent view of your ArrayList.
Synchronize access to this ArrayList on some object (maybe even enemy itself) by enclosing read and write operations on this ArrayList in synchronized blocks. That means that only one of these blocks can be executing at the same time.
synchronized (enemy) {
enemy.add(new Enemy(enemyY, 10, enemyImg));
}
and
synchronized (enemy) {
for(Enemy enemys : enemy) {
enemys.render(g);
}
}

Java Timer synchronize with GUI

I'm trying to do an incremental display of a Component because it takes too much time to make all the calculations. So i don't want to freeze the graphic interface i'd like to display my image ( a fractal ) every 2.3 seconds. The function which calculate all the points is compute. Before i want to make the incremental display this method was calculating all points. Now it only calculates 10000 points.
class FlameBuilderPreviewComponent:
Timer timer1=new Timer(1000,new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
time=time+10000;
fa= builder.build().compute(density,frame,getWidth(),getHeight(),accumulator);
}
});
timer1.start();
for (int z = 0; z <fa.height(); z++) {
for (int j = 0; j < fa.width(); j++) {
image.setRGB(j,z,fa.color(palette, background, j, fa.height()-1-z).asPackedRGB());
}
}
g0.drawImage(image,0,0,null);
if (time>density*getWidth()*getHeight()){
timer1.stop();
}
Then the other part of the program is the GUI interface, i put another timer this one is responsible of repainting the image.
class FlameMakerGUI :
fBPC=new FlameBuilderPreviewComponent(builder, background, palette, r1, density);
Timer timer = new Timer(2500,new ActionListener(){
public void actionPerformed(ActionEvent e) {
fBPC.repaint();
System.out.println("titi");
}
});
timer.start();
fractale.add(fBPC,BorderLayout.CENTER);
Then this is the error that the program show each time timer is executed:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at ch.epfl.flamemaker.gui.FlameBuilderPreviewComponent.paintComponent(FlameBuilderPreviewComponent.java:82)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1512)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1443)
at javax.swing.RepaintManager.paint(RepaintManager.java:1236)
at javax.swing.JComponent._paintImmediately(JComponent.java:5169)
at javax.swing.JComponent.paintImmediately(JComponent.java:4980)
at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
at javax.swing.RepaintManager$3.run(RepaintManager.java:784)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:784)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:757)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:706)
at javax.swing.RepaintManager.access$1000(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1651)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Thank you for helping
You are creating a action listener every second, that doesn't make any sense. You obviously do not understand how event listeners work or how the Timer class works.
Also, tasks on the EDT (event dispatch thread) must finish quickly; if they don't, unhandled events back up and the user interface becomes unresponsive
You need to use Swing Worker in order to archive proper concurrency.
From the Oracle website:
Swing consists of three kinds of threads:
Initial threads, the threads that execute initial application code.
The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also
execute on this thread.
Worker threads, also known as background threads, where time-consuming background tasks are executed.

How do you unit test a JavaFX controller with JUnit

What's the proper way of initializing the JavaFX runtime so you can unit test (with JUnit) controllers that make use of the concurrency facilities and Platform.runLater(Runnable)?
Calling Application.launch(...) from the #BeforeClass method results in a dead lock. If Application.launch(...) is not called then the following error is thrown:
java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:121)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:116)
at javafx.application.Platform.runLater(Platform.java:52)
at javafx.concurrent.Task.runLater(Task.java:1042)
at javafx.concurrent.Task.updateMessage(Task.java:987)
at com.xyz.AudioSegmentExtractor.call(AudioSegmentExtractor.java:64)
at com.xyz.CompletionControllerTest.setUp(CompletionControllerTest.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Followup: this is the motif I've been using based on recommendation by #SergeyGrinev.
... // Inside test class
public static class AsNonApp extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
// noop
}
}
#BeforeClass
public static void initJFX() {
Thread t = new Thread("JavaFX Init Thread") {
public void run() {
Application.launch(AsNonApp.class, new String[0]);
}
};
t.setDaemon(true);
t.start();
}
... // controller tests follow...
Calling launch() from #BeforeClass is a correct approach. Just note that launch() doesn't return control to calling code. So you have to wrap it into new Thread(...).start().
A 7 years later update:
Use TestFX! It will take care of launching in a proper way. E.g. you can extend your test from a TestFX's ApplicaionTest class and just use the same code:
public class MyTest extends ApplicationTest {
#Override
public void start (Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(
getClass().getResource("mypage.fxml"));
stage.setScene(scene = new Scene(loader.load(), 300, 300));
stage.show();
}
and write tests like that:
#Test
public void testBlueHasOnlyOneEntry() {
clickOn("#tfSearch").write("blue");
verifyThat("#labelCount", hasText("1"));
}
I found this to work,... but only after adding a Thread.sleep(500) after starting the JavaFX application thread. Presumably it takes some time to get the FX environment up and ready (about 200ms on my MacBook Pro retina)
#BeforeClass
public static void setUpClass() throws InterruptedException {
// Initialise Java FX
System.out.printf("About to launch FX App\n");
Thread t = new Thread("JavaFX Init Thread") {
public void run() {
Application.launch(AsNonApp.class, new String[0]);
}
};
t.setDaemon(true);
t.start();
System.out.printf("FX App thread started\n");
Thread.sleep(500);
}
This works for me as well for testing code that uses JavaFX concurrency constructs such as javafx.concurrent.Task. Compared to the other solutions it does not need explicit Thread management or supplying a dummy Application.
#BeforeAll
public static void setUpJavaFXRuntime() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
Platform.startup(() -> {
latch.countDown();
});
latch.await(5, TimeUnit.SECONDS);
}
#AfterAll
public static void tearDownJavaFXRuntime() throws InterruptedException {
Platform.exit();
}

Categories