more confusing! >:(
the error occured when typing JTextField in a panel
if typing in standalone JTextField, nothing happen, it works fine ???
this is the code
Game.java
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Random;
import java.util.Locale;
import java.io.File;
public class Game implements Runnable {
private final MainFrame mainFrame;
private Font defaultFont = new Font("Helvetica", Font.PLAIN, 12);
private GraphicsDevice myDevice;
private Dimension appDimension;
private BufferStrategy bufferStrategy = null;
/* Thread animation */
private Thread animate = null;
private boolean running = false;
/* Frame per second */
private int fps;
private boolean showFPS = true;
private long oldTime, newTime;
private int ticks = 0, currentFPS = 0;
private long msDelay, targetMs;
private long timeDiff;
private long startTime, finishTime;
public Game() {
myDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
GraphicsConfiguration gc = myDevice.getDefaultConfiguration();
mainFrame = new MainFrame(gc, "test frame");
appDimension = new Dimension(640, 480);
setFPS(40);
JTextField text = new JTextField("this JTextField is thread safety");
text.setBounds(80,200,300,40);
mainFrame.add(text);
JPanel pane = new JPanel();
JTextField textInPane = new JTextField("type fast or repetitive in this text field to get crash! :)");
textInPane.setPreferredSize(new Dimension(320,50));
pane.setBounds(80,80,360,100);
pane.setBorder(BorderFactory.createTitledBorder("why JTextField in a panel causing deadlock???"));
pane.add(textInPane);
mainFrame.add(pane);
JButton btn = new JButton("safety button");
btn.setBounds(200,25,120,30);
mainFrame.add(btn);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setVisible(true);
int width = appDimension.width + mainFrame.getInsets().left + mainFrame.getInsets().right,
height = appDimension.height + mainFrame.getInsets().top + mainFrame.getInsets().bottom;
mainFrame.setSize(width, height);
mainFrame.createBufferStrategy(2);
bufferStrategy = mainFrame.getBufferStrategy();
mainFrame.validate();
}
protected final void setFPS(int targetFPS) {
fps = targetFPS;
msDelay = 1000/fps;
targetMs = msDelay;
}
protected final void startGame() {
running = true;
// create rendered thread
animate = new Thread(this);
animate.setDaemon(true);
animate.setPriority(Thread.MAX_PRIORITY-1);
animate.start(); // start the rendered thread
/* The Game Loop */
mainLoop();
}
private synchronized void mainLoop() {
try {
while (running) {
try { wait(); } catch (Exception e) { }
//update(); // updating the screen
doActiveRender();
}
} finally {
} }
private void render(Graphics2D g) {
g.setColor(Color.red);
g.fillRect(0,0,appDimension.width,appDimension.height);
mainFrame.getContentPane().paintComponents(g);
if (showFPS) {
g.setFont(defaultFont); g.setColor(Color.black);
g.drawString("FPS : "+currentFPS, 20, 50);
g.drawString("FPS : "+currentFPS, 21, 50);
}
}
private void doActiveRender() {
Graphics2D bufferGfx;
/* Active rendering using buffer strategy. */
do {
bufferGfx = (Graphics2D) bufferStrategy.getDrawGraphics();
bufferGfx.translate(mainFrame.getInsets().left, mainFrame.getInsets().top);
render(bufferGfx);
bufferGfx.dispose();
} while (bufferStrategy.contentsLost()); // if (contentsLost) re-rendering
bufferStrategy.show(); // draw to screen
}
private void calculateFPS() {
// calculating current FPS
newTime = System.currentTimeMillis();
if (newTime > oldTime+1000) {
currentFPS = ticks; ticks = 0;
oldTime = newTime;
}
}
public void run() {
startTime = System.currentTimeMillis();
oldTime = startTime;
while (running) {
try { Thread.sleep(msDelay);
} catch (Exception e) { }
ticks++;
if (showFPS) calculateFPS();
synchronized(this) { notifyAll(); }
if (ticks%fps == 0) {
finishTime = System.currentTimeMillis();
timeDiff = ((finishTime-startTime)/fps) - targetMs;
if (timeDiff > 0) msDelay--; else
if (timeDiff < 0) msDelay++;
startTime = finishTime;
//System.out.println("Sleep for "+msDelay+" target = "+targetMs+" time diff = "+timeDiff);
}
}
synchronized(this) { notifyAll(); }
}
/** Quit the game and back to system. */
public void quitGame() { running = false; }
public static void main(String[] args) {
Game game = new Game();
game.startGame();
}
}
and MainFrame.java code:
import java.awt.Component;
import java.awt.Container;
import java.awt.GraphicsConfiguration;
import java.awt.Cursor;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComponent;
import javax.swing.*;
final class MainFrame extends JFrame {
private final JDesktopPane pane = new JDesktopPane();
public MainFrame(GraphicsConfiguration gc, String title) {
super(title, gc);
setResizable(false);
setIconImage(null);
setContentPane(pane);
/* sets all frame child to ignore repaint */
getContentPane().setIgnoreRepaint(true);
getRootPane().setIgnoreRepaint(true);
getLayeredPane().setIgnoreRepaint(true);
setIgnoreRepaint(true);
}
void add(JComponent c) {
setRepaintOff(c);
pane.add(c);
validate();
}
/* recursively turn off double buffering and
sets component to ignore repaint. */
private void setRepaintOff(Component c) {
c.setIgnoreRepaint(true);
if (c instanceof JComponent) ((JComponent)c).setDoubleBuffered(false);
if (c instanceof Container) {
Component[] children = ((Container)c).getComponents();
for(int i=0;i < children.length;i++)
setRepaintOff(children[i]);
}
}
}
mattocks, i’m not modify the gui by press any button or code modify, so can’t use swing.invokeLlater