Can anyone please tell me why I get the following exceptions
Exception in thread "main" java.lang.IllegalArgumentException adding a window to a container :
java.awt.Container.checkNotAWindow(Unknown Source)
java.awt.Container.addImpl(Unknown Source)
java.awt.Container.add(Unknown Source)
javax.swing.JFrame.addImpl(Unknown Source)
java.awt.Container.add(Unknown Source)
clockframe.<init>(clockframe.java:14)
clockframe.main(clockframe.java:32)
My code which is inside clockpanel.java file is below: I am beginner so I don't know how to work this out......
import java.awt.*;
import javax.swing.*;
public class clockframe extends JFrame
{
public clockframe()
{
super("Clock");
setLookAndFeel();
setSize(225, 125);
FlowLayout flo = new FlowLayout();
setLayout(flo);
clockpanel time = new clockpanel();
add(time);
setVisible(true);
}
private void setLookAndFeel()
{
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
}
catch (Exception exc)
{
// ignore error
}
}
public static void main(String args[])
{
clockframe clock = new clockframe();
}
}
Take a look at the JFrame documentation
IllegalArgumentException - if index is invalid
IllegalArgumentException - if adding the container's parent to itself
IllegalArgumentException - if adding a window to a container
It is looking likely that clockpanel inherits from Window thus triggering the last clause.
Edit: no need to guess any more.. just noticed the top of your stack trace.. this is the cause.
clockpanel probably extends a window such as JFrame. You probably meant to extend JPanel instead (although doing so is not necessary unless adding new functionality such as custom painting to the new JPanel).
Answer lies it self in stack trace :
thread "main" java.lang.IllegalArgumentException adding a window to a container
You are adding window to container, which is not allowed.
Related
I am using Java 11 on Debian 4. I am trying to build a very basic Java GUI. To start with I have the following code:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
public class BasicSwing extends JFrame {
JPanel p = new JPanel();
JButton b = new JButton("Hello");
public static void main (String[] args) {
new BasicSwing();
}
public BasicSwing() {
super("Basic Swing");
setSize(400,300);
setResizable(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
p.add(b);
add(p);
setVisible(true);
}
}
I have the X11 server running. The code does not fail but the GUI does not show up. I am not using Netbeans and I compile and run the code just as I would run and compile any other java code, ie with javac and java commands.The code does not stop and does not throw any error. Am I missing something very basic? I have seen a lot of discussion on the GUI not showing up but I am unable to find a solution to this problem given my specific development environment.
Instead of calling the setVisible method inside of your JFrame extended class's constructor, You should make a call on it in your main function.
Do it this way:
public static void main (String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
BasicSwing mySwingApp = new BasicSwing();
mySwingApp.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
Please read more about why I use a java.awt.EventQueue here.
Update:
It's not good practice to directly create a class that extends JFrame. Also, please read this too, for more clarification.
I'm trying to launch 2 javaFX applications, obviously Application#launch() can only be called once per JVM.
After some browsing one told me to manually create a Scene and call Application#start() for the second Application, and so I did:
public class Launcher extends Application {
private Stage primaryStage;
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
this.primaryStage.setResizable(false);
this.primaryStage.setTitle("title");
initLayout();
}
public void initLayout() throws IOException {
Parent root = FXMLLoader.load(Launcher.class.getResource("myFile.fxml"));
Scene scene = new Scene(root, 450, 300);
this.primaryStage.setScene(scene);
this.primaryStage.show();
}
}
And loading it (from another class) with:
try {
Application launcher = new Launcher();
launcher.start(new Stage());
} catch (Exception e) {}
Though this results in an error saying
Exception in thread "Thread_number" java.lang.NoClassDefFoundError: Could not initialize class javafx.stage.Screen
at javafx.stage.Window.<init><Unknown Source>
at javafx.stage.Stage.<init><Unknown Source>
at javafx.stage.Stage.<init><Unknown Source>
at javafx.stage.Stage.<init><Unknown Source>
at classILaunchedFrom.methodLaunchedFrom<Main.java:lineNumber>
Does anyone know what I'm doing wrong, because I'm completely at a loss here. Been cracking my skull far too long with javaFX now.
Why do you want to completely separate applications? Just make a class that extends stage for your second window and then call it's .show() method from inside the main javafx application thread. Javafx is rather picky when doing things, only one application instance at a time, all work must be done on the same thread and so on.
I want to create a StackPane where, whatever is added, a node of my choice is always at the front (rather than having to be careful about the order I add things in, or remembering to call toFront() on that particular node whenever anything is added.)
In order to do this, I simply place a listener on the child list of the relevant StackPane object, so that whenever anything changes, it calls toFront() on the relevant node, for example:
public class Test extends Application {
#Override
public void start(Stage stage) {
StackPane root = new StackPane();
final Rectangle r1 = new Rectangle(50, 50);
root.getChildren().add(r1);
root.getChildren().addListener(new ListChangeListener<Node>() {
#Override
public void onChanged(ListChangeListener.Change<? extends Node> change) {
try {
while(change.next()) {
if(change.wasAdded()) {
r1.toFront();
}
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
});
root.getChildren().add(new Rectangle(50, 50));
stage.setScene(new Scene(root));
stage.show();
}
}
In Java 7, this works just fine. However, in JFX8 (latest build downloaded just now), it fails with the following:
java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableList.add(Collections.java:1374)
at javafx.collections.ListChangeBuilder.nextRemove(ListChangeBuilder.java:208)
at javafx.collections.ObservableListBase.nextRemove(ObservableListBase.java:150)
at javafx.collections.ModifiableObservableListBase.remove(ModifiableObservableListBase.java:181)
at com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:284)
at com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:209)
at javafx.scene.Parent.impl_toFront(Parent.java:624)
at javafx.scene.Node.toFront(Node.java:1713)
at test.Test$1.onChanged(Test.java:34)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:315)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:72)
at com.sun.javafx.collections.VetoableListDecorator$1.onChanged(VetoableListDecorator.java:77)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:315)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:72)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:200)
at test.Test.start(Test.java:41)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:331)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:297)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:294)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:744)
And yes, test.Test$1.onChanged(Test.java:34) does indeed refer to r1.toFront();.
Is this to be considered a bug, or am I breaking some rule I'm unaware of by trying to achieve things this way? I did wonder whether the list was still being changed while the onChanged() method was executing, and toFront() would also change the list contents, hence the exception - but the Javadoc to onChanged() clearly says:
Called after a change has been made to an ObservableList.
(Bolding is mine.)
EDIT: At this point I'm more certain that it's a bug, so the related bug report is here.
It seems that you are not allowed to modify a (JavaFX) list inside an event handler that is currently handling another (previous) modification event of the same list. Although this seems reasonable it is not self-evident, so there should be a more obvious exception in that case.
Unfortunately non-speeking exceptions are very common in JavaFX.
Fortunately the solution/workaround is pretty easy: Call your modifying code (here: r1.toFront) by Platform.runLater(), it will delay your modification to happen after the originating event:
root.getChildren().addListener(new ListChangeListener<Node>() {
#Override
public void onChanged(ListChangeListener.Change<? extends Node> change) {
Platform.runLater(new Runnable() {
public void run() { r1.toFront(); }
});
}
});
Sidenote: toFront does nothing, if the component is already at front. This prevents infinite loops. Nevertheless, as this is not explicitely mentioned in the documentation, you might not rely on that.
I have a Processing project making use of the ControlP5 library running within eclipse in which, upon any keypress on the keyboard, crashes with an IllegalArgumentException:
Exception in thread "Animation Thread" java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1076)
at processing.core.PApplet.handleKeyEvent(PApplet.java:2848)
at processing.core.PApplet.dequeueKeyEvents(PApplet.java:2793)
at processing.core.PApplet.handleDraw(PApplet.java:2132)
at processing.core.PGraphicsJava2D.requestDraw(PGraphicsJava2D.java:197)
at processing.core.PApplet.run(PApplet.java:1998)
at java.lang.Thread.run(Unknown Source)
The program (running in an applet) runs perfectly fine with mouse dragging, sliders, etc, until a key is pressed. It seems like there is some sort of unknown keylistener waiting for input and using it incorrectly? It is difficult to tell because the exception refers to java code which is unrelated to the processing code which I wrote.
Even if I have a program which only defines a ControlP5 object, the program encounters the same error:
import processing.core.*;
import controlP5.*;
public class Lensing extends PApplet {
ControlP5 controlP5;
public Lensing() {
}
public void setup() {
controlP5 = new ControlP5(this);
}
public void draw() {
}
public static void main(String args[]) {
PApplet.main(new String[] { "--present", "edu.umd.astro.Lensing" });
}
}
Comment out the single controlP5 definition, and no exception occurs.
Turns out it was an issue related to using the 2.0b1 core jar file, and can be remedied by updating to 2.0b3 from http://processing.org/download/
credit to reply on here https://forum.processing.org/topic/using-controlp5-with-processing-in-eclipse-results-in-illegalargumentexception-on-keypress
I have problem, when I want add Node to my GUI from other Thread. It throws IllegalStateException and I don't know how to fix it.
public class DashBoardController implements Initializable {
#FXML
private FlowPane dashBoardPane;
#Override
public void initialize(URL url, ResourceBundle rb) {
try {
RTMClientV2 client = new RTMClientV2("localhost", 9009, new DashBoardArranger(this));
Thread clientTH = new Thread(client);
clientTH.start();
} catch (IOException ex) {
Logger.getLogger(DashBoardController.class.getName()).log(Level.SEVERE, null, ex);
}
}
public synchronized void addToDashBoard(Pane root){
dashBoardPane.getChildren().add(root);
}
}
I just load my .FXML file to GUI with this controller and when program starts it runs Thread responsible for communication with server (clientTH.start();) and everything is OK. But when server send data after init. and I want this data add to my Dashboard, I use method public synchronized void addToDashBoard(Pane root) as before, but it throws java.lang.IllegalStateException and I have no idea why.
btw: I have found this: "If this Parent node is attached to a Scene, then its list of children must only be modified on the JavaFX Application Thread. An IllegalStateException is thrown if this restriction is violated.", but it is not useful for me. Dashboard is added to another Pane in my GUI.
btw: Output:
Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(Unknown Source)
at javafx.scene.Parent$1.onProposedChange(Unknown Source)
at com.sun.javafx.collections.VetoableObservableList.add(Unknown Source)
at com.sun.javafx.collections.ObservableListWrapper.add(Unknown Source)
at probeobserver.gui.probeSite.DashBoardController.addToDashBoard(DashBoardController.java:125)
at probeobserver.gui.probeSite.DashBoardArranger.setCompName(DashBoardArranger.java:66)
at probeobserver.rtm.RTMClientV2.readAllDataAndUpdate(RTMClientV2.java:144)
at probeobserver.rtm.RTMClientV2.run(RTMClientV2.java:80)
at java.lang.Thread.run(Thread.java:722)
In your I/O thread, you need to interact with the UI within the UI thread:
Platform.runLater(new Runnable() {
#Override
public void run() {
Pane root = ...; //if you set any properties of the pane, do it here.
dashBoardController.addToDashBoard(root);
}
}