1

enter image description hereum.. I made a simple shooting game and I had a problem. this Exception.

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: No such child: 22 at java.awt.Container.getComponent(Container.java:334) at javax.swing.JComponent.rectangleIsObscured(JComponent.java:4390) at javax.swing.JComponent.paint(JComponent.java:1054) at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210) at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579) at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502) at javax.swing.RepaintManager.paint(RepaintManager.java:1272) at javax.swing.JComponent._paintImmediately(JComponent.java:5158) at javax.swing.JComponent.paintImmediately(JComponent.java:4969) at javax.swing.RepaintManager$4.run(RepaintManager.java:831) at javax.swing.RepaintManager$4.run(RepaintManager.java:814) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814) at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789) at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738) at javax.swing.RepaintManager.access$1200(RepaintManager.java:64) at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756) 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.awt.EventQueue.dispatchEvent(EventQueue.java:726) 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) 

If there is something unusual,Exception occurs when I shoot a lot of bullets. what is this? I do not know what is wrong because it works well.

package com.thread; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class ShootingGame extends JFrame{ Container c; Enemy enemy; Thread th; public ShootingGame() { setTitle("Shooting Game"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(500,360); c = getContentPane(); enemy = new Enemy(new ImageIcon("images/enemy_plane.png")); Player player = new Player(new ImageIcon("images/player.png")); c.add(player, BorderLayout.SOUTH); c.add(enemy, BorderLayout.NORTH); c.addKeyListener(new KeyAdapter() { // listener for player move, bullet firing boolean leftControl = true; // for only one move input receive boolean rightControl = true; // for only one move input receive @Override public void keyPressed(KeyEvent e) { // player move, shoot occur if(e.getKeyCode() == KeyEvent.VK_LEFT && leftControl && rightControl) { // Only one movement input is received. leftControl = false; player.pSpeed = -5; // direction is left. th = new Thread(player); // player move while hoding key th.start(); } else if(e.getKeyCode() == KeyEvent.VK_RIGHT && rightControl && leftControl) { // Only one movement input is received. rightControl = false; player.pSpeed = 5; // direction is right th = new Thread(player); // player move while hoding key th.start(); } if(e.getKeyCode() == KeyEvent.VK_SPACE) { // shoot bullet Bullet bul = new Bullet(new ImageIcon("images/bullet.png")); bul.setSize(16,16); bul.setLocation(player.getX()+c.getWidth()/2-10,player.getY()); c.add(bul); c.repaint(); } } @Override public void keyReleased(KeyEvent e) { // if keyReleased, ready to receive right or left move input if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_RIGHT) { th.interrupt(); // quit move thread. leftControl = true; // ready to receive move input rightControl = true; // readt to receive move input } } }); setVisible(true); c.requestFocus(); } class Enemy extends JLabel implements Runnable{ // enemyplane info int speed; public Enemy(ImageIcon enemyplane) { super(enemyplane); this.setSize(64,64); this.setVerticalAlignment(TOP); this.setHorizontalAlignment(LEFT); Thread th = new Thread(this); th.start(); } @Override public void run() { // enemy plane move on x-Axis not change y-Axis speed = -5; int homeX = this.getX(); int homeY = this.getY(); while (true) { this.setLocation(homeX + speed, homeY); if (homeX + speed > -60) { speed -= 5; } else { speed = 0; } homeX = c.getWidth(); // to fit in frame size try { Thread.sleep(20); // 20millsecond, move } catch (InterruptedException e) { return; } } } } class Player extends JLabel implements Runnable { // player plane int pSpeed; public Player(ImageIcon controlPlane) { super(controlPlane); this.setSize(64,64); this.setVerticalAlignment(BOTTOM); this.setHorizontalAlignment(CENTER); } @Override public void run() { // player move thread int pXPosition = this.getX(); int pYPosition = this.getY(); while (true) { pXPosition += pSpeed; this.setLocation(pXPosition, pYPosition); if (pXPosition <= -c.getWidth()/2) { // Move within frame only pXPosition = c.getWidth()/2; } else if (pXPosition > c.getWidth()/2) { // Move within frame only pXPosition = -c.getWidth()/2; } try { Thread.sleep(25); // 25millsecond, move } catch (InterruptedException e) { return; } } } } class Bullet extends JLabel implements Runnable { public Bullet(ImageIcon bullet) { super(bullet); Thread bulletthread = new Thread(this); bulletthread.start(); } @Override public void run() { // bullet is move to top from player. int bulXPosition = this.getX(); int bulYPosition = this.getY(); while(true) { bulYPosition -= 10; this.setLocation(bulXPosition,bulYPosition); if(bulYPosition <= enemy.getY() + 50 && bulYPosition >= enemy.getY()) { if(bulXPosition <= enemy.getX() + 48 && bulXPosition >= enemy.getX()) { // if enemy hit, bullet is removed and thread quit enemy.speed = 200; c.remove(this); break; } } if (bulYPosition < -16) { // if bullet is out of frame, bullet is removed c.remove(this); break; } try { Thread.sleep(25); // 25millsecond, move } catch (InterruptedException e) { return; } } } } public static void main(String[] args) { new ShootingGame(); } } 
5
  • Post the COMPLETE stack trace, including all Caused By sections, and indicate the statement in your code that throws the exception. Nobody is going to read a wall of code to find a needle in a haystack. First rule of asking for help is make it easy for people to help you. Commented Nov 26, 2017 at 0:56
  • im sorry. i edited and posted all error message. Commented Nov 26, 2017 at 1:33
  • You probably have something queued up to be repainted and you remove it before the UI thread has a chance to actually process it. Commented Nov 26, 2017 at 2:47
  • You'd probably have generally more luck using Key Bindings over KeyListener Commented Nov 26, 2017 at 5:09
  • Swing is NOT thread safe. This means that you should NEVER update the UI from outside the context of the Event Dispatching Thread Commented Nov 26, 2017 at 5:10

1 Answer 1

2

Swing is NOT thread safe. This means that you should NEVER update the UI from outside the context of the Event Dispatching Thread.

A solution would be to use a single Swing Timer as the core "main-loop" responsible for updating the state of the game a schedule repaints.

A simpler, overall solution, would be not to use components this way and instead, have a single container which can paint "entities" and use a Swing Timer to update the state of these "entities" on a regular bases. Because both the paintComponent and Swing Timer perform there work within the EDT, it's safe to update the UI from (the Timer) and prevents possible thread violations

Start by having a look at Concurrency in Swing and How to use Swing Timers.

You may also find the key bindings API generally more reliable then KeyListener

You could also have a look at something like this example to get a better idea of what I've just described

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.