Reputation: 101
I'm having an error when trying to add a component to a JFrame.
This is the first class:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
public class FrameG extends JFrame
{
private static final String MOVE_UP = "move up";
public static int frameID = 1;
private static JFrame window = new JFrame();
private static openWin frame = new frame01();
public static void main(String[] args) {
window.setSize(1500,900);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.setResizable(true);
frame.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), MOVE_UP);
frame.getActionMap().put(MOVE_UP, new movement());
mainloop();
}
private static void mainloop()
{
window.removeAll();
switch(frameID)
{
case 1:
frame = new frame01();
frame.setLayout(new FlowLayout());
System.out.println(frame);
window.add(frame);
break;
default:
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex);
}
mainloop();
}
}
class movement extends AbstractAction
{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("hi");
}
}
and the second class (it extends a class with an abstract paint method that extends JComponent):
import java.awt.Graphics;
import java.awt.*;
import javax.swing.JComponent;
import java.awt.geom.*;
public class frame01 extends openWin{
@Override
public void paint(Graphics g) {
Graphics2D pic = (Graphics2D) g;
pic.setBackground(Color.BLACK);
}
}
The error may be the invalid part, but i'm not sure what it is:
frameg.frame01[,0,0,0x0,invalid,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=]
Upvotes: 0
Views: 363
Reputation:
Never use a Thread and it's start and stops as a timer. Use javax.swing.Timer
instead. Also you've created a recursive function to implement an infinite loop which is very wired and prone to fail. Swing has it's own thread and when you mix it up with another threads unconsciously it transform your code to a monster we are all afraid of.
Upvotes: 1
Reputation: 347204
You code shows a distinct lack of understanding into how Swing works
This...
private static void mainloop()
{
window.removeAll();
switch(frameID)
{
case 1:
frame = new frame01();
frame.setLayout(new FlowLayout());
System.out.println(frame);
window.add(frame);
break;
default:
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex);
}
mainloop();
}
Is a bad idea of two reasons, the first been that it will eventually generate a StackOverflowException
, the second been that it violates the single thread rules of Swing.
Normally, a while-loop
would generally be better, but as you're dealing with Swing based components you should consider using either a Swing Timer
or SwingWorker
, depending on what you are hoping to achieve.
Constantly adding and remove components also seems like a weird idea, but there's no context to the question to know what it is you're hoping to achieve. Having said that, as a general rule, if you want to switch between views a CardLayout
is generally considered the preferred solution
This...
public class frame01 extends openWin{
@Override
public void paint(Graphics g) {
Graphics2D pic = (Graphics2D) g;
pic.setBackground(Color.BLACK);
}
}
is simply doing nothing, other then breaking the paint chain, which could cause no end of weird paint artefacts to be generated. All you code does if temporarily changes the background color of the Graphics
context, but since you don't paint anything with it, it's effectively meaningless
As a general rule, it's recommended to override the paintComponent
method of Swing components (and call super.paintComponent
before you do any custom painting).
I would highly recommend that you take a look at:
Upvotes: 3
Reputation: 1482
Your code has lots of problems. The line private static openWin frame = new frame01();
seems fishy as I said in my comment. But its not the worst part:
THIS:
private static void mainloop()
{
window.removeAll();
switch(frameID)
{
case 1:
frame = new frame01();
frame.setLayout(new FlowLayout());
System.out.println(frame);
window.add(frame);
break;
default:
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(FrameG.class.getName()).log(Level.SEVERE, null, ex);
}
mainloop();
}
Is BAD! And it probably breaks since you are constantly creating a new frame01()
and adding it to your window
.
Also DO NOT override paint
but paintComponent
. Another thing I dont get is why override it in a separate class
and not in openWin
itself.
Another thing, DO NOT SLEEP THE MAIN THREAD, if you really must then run your own and put IT to sleep.
What is the purpose of this code? I'm trying to understand it so I can help you redesign it.
PS: not really an answer, just a bit longer than a comment.
Upvotes: 2