Java - 在另一个类的一个类中更改布尔值

时间:2014-01-12 00:10:09

标签: java

我目前,为了好玩,制作一个乒乓球游戏,但我目前卡住试图通过w键按下我的布尔“上升”的值到真实状态。我的渲染类中有布尔值,以及int x和int y,并且设置为false。在这个类中,我绘制一个正方形,其中x为int x,y为int y。在另一个类(Framemake.java)中,我有一个设置为我的Jframe的键监听器。在这堂课中,我有keylistener听w键按下和释放。这就是我的问题出现的地方:如果按下W键,我希望它将upup更改为true,如果已释放,我希望它更改为false;这工作正常,但问题是我的渲染类我已经设置了一个计时器,然后在图形方法中启动(不确定正确的名称)。在我设置的定时器动作中:如果上升是真的,我希望它打印出“up up is true-render”。这就是问题 - 即使由于按下了w键而向上移动,打印也不会打印到屏幕上。 (感谢您阅读本文,我需要您完全了解最新情况 - 即使它可能会或可能不会非常明显)。

这是代码: Starter.java

public class Starter  {

public static void main(String[] args) {
    Frame frame = new Frame(); 
    frame.Start(); 

}

}

这是Frame.java

public class Frame implements Runnable  {
Framemake r = new Framemake();

public void Start(){
    new Thread(this).start();//
}
public void run() {

    try {
        r.framemade();
        }
    catch (Exception e) { //
        e.printStackTrace(); 
    }   

}

    }

这是Render.java的一部分,因为我在这篇文章中遇到了麻烦

public class Render extends JPanel implements ActionListener {

boolean goingup = false;
boolean goingdown = false;
int x = 0; //starting pos of x .
int y = 150;//starting pos of y
Timer tm = new Timer(7, this); //The timer is created



public void paintComponent(Graphics g) {
  Framemake frames = new Framemake();
  super.paintComponent(g);
  tm.start();
  g.setColor(Color.GREEN);
  g.fillRect(x, y, 20, 150);
  g.dispose();
}

public void actionPerformed(ActionEvent e){ //timer
  if(goingup){
    System.out.println("Going up is true- render");
    x++;//for example...
    repaint();
  }
}

这是Framemake.java

public class Framemake implements KeyListener {
    int WIDTH = 500;
    int HEIGHT = 500;
    Render c = new Render();
    public void framemade() {
        System.out.println("Frame starting");
        //Frame is created here 
        Render render = new Render();
        JFrame frame = new JFrame();
        frame.setSize(WIDTH, HEIGHT);
        frame.setVisible(true);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setTitle("Animation");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Window w = frame;
        w.addKeyListener(this);
        frame.add(render); //displays all graphics from render to the screen
    }
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_W) {
            System.out.println("Going up");
            c.goingup = true;
        }
        if (keyCode == KeyEvent.VK_S) {
            System.out.println("Going down");
            c.goingdown = true;
        }
    }
    public void keyReleased(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (keyCode == KeyEvent.VK_W) {
            System.out.println("Up terminated");
            c.goingup = false;
        }
        if (keyCode == KeyEvent.VK_S) {
            System.out.println("Down terminated");
            c.goingdown = false;
        }
    }
    public void keyTyped(KeyEvent e) {}
}

我希望这里的问题很明确(如果我的代码发布错误,很抱歉),我们非常感谢您的帮助。

4 个答案:

答案 0 :(得分:2)

问题是,在您的班级Framemake中,您没有将Render c添加到frame。您正在创建局部变量render

要解决此问题,只需删除

的声明即可
Render render = new Render();

并将c添加到frame

frame.add(c);  // Instead of 'frame.add(render)'

摘要:您的方法framemade()应如下所示:

public void framemade()
{
    System.out.println("Frame starting");
    //Frame is created here 
    JFrame frame = new JFrame();
    frame.setSize(WIDTH, HEIGHT);
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setTitle("Animation");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Window w = frame;
    w.addKeyListener(this);
    frame.add(c); // Change this line
}

修改

我还建议你阅读为什么要使用私有字段,getter和setter。试试thisthis

答案 1 :(得分:0)

我想,你的计时器根本不会发射。您应该只启动一次,而不是paintComponent方法。因为默认情况下它会每7毫秒触发一次。 还要添加一行以查看actionPerformed方法是否实际触发:

public void actionPerformed(ActionEvent e){ //timer
  System.out.println("Timer: actionPerformed");  
  if(goingup){
    System.out.println("Going up is true- render");
    x++;//for example...
    repaint();
  }
}

为什么要在g.dispose();方法中拨打paintComponent?每次重绘都会调用此方法。这很可能也会导致问题。

答案 2 :(得分:0)

你应该能够通过简单地添加这样的方法来实现这一点,然后调用它:     Public void setgoingup(boolean b){     this.goingup = b;     }

Ps:我很累,并没有阅读所有代码 - 对不起,如果我错过了任何事情。

答案 3 :(得分:0)

您需要使用observer(或通知程序)模式。

一个非常简单(天真)的例子: 创建一个将扮演observable角色的类,并且 具有观察者角色的接口及其实现 类。 将列表保存到观察者实例的可观察类,以便在需要时通知

(注意:未经测试的代码):

public interface Observer{
  public void notify();
}

public class Observable{
  public List<Observer> _observers;

  public Observable(){
    _observers = new List<Observer>();
  }

  public void registerObserver(Observer obs){
     _observers.add(obs)
  }

  public void unregisterObserver(Observer obs){
    _observers.remove(obs);
  }

  public void notifyObservers{
    for(Observer obs : _observers) { 
       obs.notify();
    }
  }

}

public class SpecificObserver implements Observer{
  //Properties, Ctors etc

  public void notify(){
    //Do stuff when notified here
  }
}


and in your program:

public static void main(string[] args){

  Observable observable             = new Observable();
  SpecificObserver specificObserver = new SpecificObserver();
  //More init code here

  observable.registerObserver(specificObserver);
  //Etc...

  //read input
  string str = YourClass.GetInput();

  while(!str.Equals("EndString"))
  {
    if(str.Equals("SpecificInput"))
    {
      observable.notifyObservers();
    }
    str = YourClass.GetInput();
  }

}

当然,您可以根据需要对其进行修改(为Notify方法添加参数,将循环运行到另一个检查所需条件的线程而不是输入等)