Dev Parzival Ответов: 2

Почему флаг внутри метода paint всегда ложен?


В приведенной ниже программе я просто пытаюсь переместить коробку на экране на основе нажатой клавиши.Я должен очистить последнее положение коробки и нарисовать ее новое положение .Когда флаг имеет значение true я буду очистить экран и, когда флаг имеет значение false, я буду рисовать его на экране но значение флага ложно, оно не меняется внутри нажатия клавиши(KeyEvent e) способ съемки класс.

Удалите оператор комментария внутри метода paint(Graphics g) класса Shoot, и u обнаружит, что флаг всегда ложен.

Почему это так?
Заранее спасибо ;)

import java.awt.Color;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import java.awt.event.KeyListener;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;

/**
 *
 * @author Dev Parzival
 */
public class Shoot extends JPanel implements KeyListener,WindowListener{
    int x=300,y=300;
    int width=50,height=50;
    boolean flag=false;
    @Override
    public void keyTyped(KeyEvent e) {
    }
    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_LEFT){
            flag=true;
            repaint();
            x--;
            flag=false;
            repaint();
        }
        if(e.getKeyCode()==KeyEvent.VK_RIGHT){
            flag=true;
            repaint();
            x++;
            flag=false;
            repaint();
        }
    }
    
    @Override
    public void paint(Graphics g){
        //System.out.println(flag);
        if(flag){
            g.setColor(getBackground());
            g.drawRect(x, y, width, height);
            g.setColor(Color.black);
        }
        else
        g.drawRect(x, y, width, height);
    }
    
    @Override
    public void windowOpened(WindowEvent e) {
    }

    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }

    @Override
    public void windowClosed(WindowEvent e) {
    }

    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }
    
    public static void main(String $[]){
        JFrame frame =new JFrame();
        frame.setSize(700,700);
        Shoot shoot=new Shoot();
        shoot.setSize(700,700);
        frame.addKeyListener(shoot);
        frame.addWindowListener(shoot);
        frame.add(shoot);
        frame.setVisible(true);
    }

}


Что я уже пробовал:

@Override
    public void paint(Graphics g){
        System.out.println(flag);
        if(flag){
            g.setColor(getBackground());
            g.drawRect(x, y, width, height);
            g.setColor(Color.black);
        }
        else
        g.drawRect(x, y, width, height);
    }


Значение флага всегда будет ложным.

2 Ответов

Рейтинг:
4

Dev Parzival

Проблема с приведенным выше кодом заключалась в том, что значение флага внутри метода keyPressed(KeyEvent e) всегда ложно.
Как @OriginalGriff уже упоминалось, что флаг всегда установлен в false;

package animation;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

/**
 *
 * @author Dev Parzival
 */
public class MovingImage extends JPanel implements KeyListener{

    static class Shooter{
        int startx,starty;
        int width;
        int height;
        Shooter(int x,int y,int w,int h){
            startx=x;
            starty=y;
            width=w;
            height=h;
        }
    }
    Graphics2D g;
    BufferedImage img;
    Shooter shoot;
    MovingImage(){
        setSize(700,700);
        img=new BufferedImage(700,700,BufferedImage.TYPE_4BYTE_ABGR);
        g=img.createGraphics();
        shoot=new Shooter(300,300,50,50);
        g.fillRect(shoot.startx, shoot.starty, shoot.width, shoot.height);
        repaint();
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()==KeyEvent.VK_RIGHT){
            Color back=this.getBackground();
            Color front=g.getColor();
            g.setColor(back);
            g.fillRect(shoot.startx, shoot.starty, shoot.width, shoot.height);
            g.setColor(front);
            shoot.startx++;
            g.fillRect(shoot.startx, shoot.starty,shoot.width , shoot.height);
            g.drawImage(img, 0,0, this);
            repaint();
        }
        if(e.getKeyCode()==KeyEvent.VK_LEFT){
            Color back=this.getBackground();
            Color front=g.getColor();
            g.setColor(back);
            g.fillRect(shoot.startx, shoot.starty, shoot.width, shoot.height);
            g.setColor(front);
            shoot.startx--;
            g.fillRect(shoot.startx, shoot.starty,shoot.width , shoot.height);
            g.drawImage(img, 0,0, this);
            repaint();
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
    @Override
    public void paint(Graphics g){
        g.drawImage(img,0,0, this);
    }
    public static void main(String[] args) {
        JFrame frame =new JFrame();
        frame.setSize(700,700);
        MovingImage moving_img=new MovingImage();
        frame.add(moving_img);
        frame.addKeyListener(moving_img);
        frame.setVisible(true);
    }
}


Рейтинг:
16

OriginalGriff

События происходят не сразу: они попадают в "очередь" и отвечают по порядку (кроме paint - это событие с низким приоритетом, поэтому все более важное будет перемещено вверх по очереди мимо него).

И очередь сообщений проверяется только после того, как обработка текущего even завершена и метод обработчика событий вернулся.
Ваш метод вызывает repaint, который объявляет сообщение Paint в очередь, а затем устанавливает флаг обратно в false - так что к моменту действия события Paint флаг уже был сброшен.
Попробуйте переместить сброс флага в обработчик краски - это может сделать то, что вы хотели.


Dev Parzival

@OriginalGriff спасибо за ваше предложение.
Я попробовал сделать это сейчас, но у меня ничего не вышло.
Можете ли вы прислать мне код?
Заранее спасибо ;)

OriginalGriff

- у меня ничего не вышло."
"Это не работает", вероятно, самый бесполезный отчет о проблеме, который мы получаем - и мы получаем его много. Она ничего не говорит нам о том, что происходит или когда это происходит.
Итак, расскажите нам, что он делает, чего вы не ожидали, или не делает, что вы сделали.
Расскажите нам, что вы сделали, чтобы это произошло.
Сообщайте нам о любых сообщениях об ошибках.

- Ты можешь прислать мне код?"
Ты ведь шутишь, правда? Вы не можете переместить строку кода из одного метода в другой для себя?