Ignored components from stream do not redraw in JFrame in Java

I have one class like this

public class BlockSpawner implements Runnable{

public static long timeToSpawn;
private GtrisJFrame frame;

public BlockSpawner(GtrisJFrame frame)
{

    this.frame = frame;
    timeToSpawn = 2000;
}

public void run()
{
    while(true)
    {
        try
        {
            Thread.sleep(timeToSpawn);
        }
        catch(InterruptedException e)
        {
            //Unhandled exception
        }

        //After awake, instanciate 2 blocks
        //get the position of the first one
        int index = Block.getRandomStartPosition();
        new Block(frame, index);
        new Block(frame, index+1);
    }
}

}

I use this class in the main JFrame class and start it as:

private void initBlockSpawner()
{
    spawner = new BlockSpawner(this);
    new Thread(spawner).start();
}

I call this function initBlockSpawner () from the JFrame Constructor. The Block class is really a little big, but in a nutshell it implements runnable and calls its run () method at the end of its constructor. The run () method only makes the block fall at a certain speed. I tried to manually create new blocks in the JFrame constructor, and they work, they repaint and fall. But whenever I want to instantiate blocks from other threads, they seem to fall (i.e., His properties update every loop), but they are not drawn in the JFrame.

NetBeans, JFrame, :

public static void main(String args[])
{
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new GtrisJFrame().setVisible(true);
        }
    });

}

Java Threads, awt- swing. -, , , , swing - ... Is ?

.

EDIT: , , toString Instantiated , [, 0,0,0x0], JFrame, [, 0,0,328x552] . 328x552 , , getPreferredSize()... , :

new Block(this, index).setPreferredSize(new Dimension(328, 552));

, - , [, 0,0,328x552]?

, , !

2: , x: 0 y: 0, ? BlockSpawner run() - :

public void run()
{
    while(true)
    {
        System.out.println("SPAWN");
        int index = Block.getRandomStartPosition();
        new Thread(new Block(frame, index)).start();
        new Thread(new Block(frame, index+1)).start();

        try
        {
            Thread.sleep(timeToSpawn);
        }
        catch(InterruptedException e)
        {
            //Unhandled exception
        }
    }
}

! JFrame , Thread.sleep() , getSize() x: 0 y: 0; One Dispatcher Thread? - ?

+3
3

( ), JFrame ( , "" ) , . Threading Swing .

Swing , Runnable , EventQueue.invokeLater() invokeAndWait().

EDIT:

( , ): , , . JFrame , , . JFrame JPanel, , .

:

  • - . . , , . - , .

  • JFrame . ? , , JFrame, - , ? , , JFrame ( , , ). - . , GUI, JFrame ( JPanel).

  • JPanel JFrame. JPanel JFrame, . JFrame, , , ?

, , - :

BlockAnimator animator = new BlockAnimator();
DispatchThread.invokeLater( 
  new Runnable(){
    public void run(){
      JPanel blockAnimationPanel = new JPanel();
      Block block = new Block(...);
      blockAnimationPanel.add(block);
      JFrame mainFrame = new JFrame();
      mainFrame.add(blockAnimationPanel);
      animator.start(); // note that we probably should start the thread *after* the panel is realized - but we don't really have to.
    }
  }

public class BlockAnimator extends Thread{
  private final List<Block> blocks = new CopyOnWriteArray<Block>(); // either this, or synchronize adds to the list
  public void addBlock(Block block){
    blocks.add(block);
  }
  public void run(){
    while(true){ // either put in a cancel check boolean, or mark the thread as daemon!
      DispatchThread.invokeAndWait(
        new Runnable(){
          public void run(){
            for(Block block: blocks){
              block.moveTo(....); // do whatever you have to do to move the block
            }
          }
        }
      ); // I may have missed the brace/paren count on this, but you get the idea
      spawnNewBlockObjects();
      Thread.sleep(50);
    }
  }
}

..

, . , , ArrayList , .

:

  • . , pause(), .

  • , . EDT. invokeAndWait (, , invokeLater) . , .

, , gnarly, . , , , , .

+4

Swing , , , AWT.

, main(), netbeans. java.awt.EventQueue.invokeLater , AWT.

Runnable BlockSpawner, , sleep() / .

, SwingWorker, , , .

sleep() doInBackground(), done().

+2

javax.swing.Timer

This provides the ability to schedule an action in the event dispatch stream at a specified speed and does not require Java 6

You can plan your BlockSpawner with the following code:

  int timeToSpawn = 2000;

  ActionListener blockSpawner = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          int index = Block.getRandomStartPosition();
          new Block(frame, index);
          new Block(frame, index+1);
      }
  };
  new Timer(timeToSpawn, blockSpawner).start();

This is probably the easiest solution, as it does not require additional threads. Just make sure you use the Timer class in javax.swing and not java.util, otherwise you cannot execute the message flow.

0
source

Source: https://habr.com/ru/post/1733637/


All Articles