Not sure why this graphic screen is not updating

This is the screen I'm trying to redraw, but it is not redrawing properly.

public class arenaScreenBuild extends JPanel{ int pX=200, pY=150; public void updateScreen(){ repaint(); } public void paintComponent(Graphics g) { g.drawString("x:"+pX, 535, 525); g.drawString("y:"+pY, 535, 545); } public void refreshXY(int x, int y){ pX=x; pY=y; System.out.println("Refreshed X&Y"); updateScreen(); } } 

This is a screen displaying graphics. When I start it every time I move (press the right arrow key), it displays "Refreshed X & Y", but even if it calls the updateScreen () method, the displayed items are not redrawn. The code, if it worked, should display x: XVALUE, y: YVALUE after "updated X & Y".

  public class ArenaKeys extends KeyAdapter { arenaScreenBuild arenaBG = new arenaScreenBuild(); int xPos = 0, playerFace = 4,xPPos = 200, yPPos = 150; public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == e.VK_RIGHT) { if (xPos <= 3250) if (((xPos + xPPos) >= 825) && ((xPos + xPPos) <= 910) && (yPPos >= 170) && (yPPos <= 255)) { } else if (((xPos + xPPos) >= 1325) && ((xPos + xPPos)<= 1410) && (yPPos >= 170) && (yPPos <= 255)) { } else xPos += 5; } arenaBG.refreshXY(xPPos+xPos,yPPos); } } 

EDIT: * It turns out that it works, but what I did was add the Drawpanel on top of the other drawpanel, and this code was for the one below, so it did not allow the lower code to update, I solved this by combining the two codes for both panels. *

+4
source share
3 answers

This works for me (this is SSCCE created from your code). Since it works and your code remains almost unchanged, the problem probably does not lie in the code you posted, but in another code. Also, normally you would like to use Key Bindings instead of KeyListener for such things.

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Temp extends JPanel{ int pX=200, pY=150; Dimension preferredSize = new Dimension(500,300); public Temp(){ addKeyListener(new KeyAdapter() { int xPos = 0, playerFace = 4,xPPos = 200, yPPos = 150; public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == e.VK_RIGHT) { if (xPos <= 3250) if (((xPos + xPPos) >= 825) && ((xPos + xPPos) <= 910) && (yPPos >= 170) && (yPPos <= 255)) { } else if (((xPos + xPPos) >= 1325) && ((xPos + xPPos)<= 1410) && (yPPos >= 170) && (yPPos <= 255)) { } else xPos += 5; } refreshXY(xPPos+xPos,yPPos); } }); setFocusable(true); requestFocus(); } public Dimension getPreferredSize(){ return preferredSize; } public void updateScreen(){ repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); g.drawString("x:"+pX, 0, 20); g.drawString("y:"+pY, 0, 40); } public void refreshXY(int x, int y){ pX=x; pY=y; System.out.println("Refreshed X&Y"); updateScreen(); } public static void main(String[] args) { JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(new Temp()); frame.pack(); frame.setVisible(true); } } 
+1
source

In the call to keyPressed EventQueue.invokeLater(new Runnable()) , because keyPressed is called in the event flow, and repainting should be delayed.


There is an AWT event queue in which an event is processed on a single thread. When an event is processed, for example keyPressed , the GUI is frozen; other events are not processed in parallel.

Thus, such events should not do something for a long time or change the display.

The solution is to delay the code that needs to be executed.

This can be done using

 EventQueue.invokeLater(new Runnable() { @Override public void run() { ... the code ... } }); 

In java, there is one single thread (process) that processes GUI events in an infinite loop, for example keyPressed , button click, or (indirectly) paintComponent . To do this, there is an event waiting queue called java.awt.EventQueue .

Thus, this is not done in parallel. This limitation makes encoding a little easier and better displayed on operating systems, such as the old MacOS.

Therefore, when keyPressed is called (in the event stream), the redraw call will have no effect, since it should be processed on the repaintComponent later, in the same stream.

The solution is to invokeLater , which puts the Runnable event in the event queue for future reference.

+3
source

xPos = 0 initially and

  if (xPos <= 3250) { } else xPos += 5; 

This means that xPos never increases.

+2
source

All Articles