Java—从一个类更改另一个类中的布尔值

Java—从一个类更改另一个类中的布尔值,java,Java,为了好玩,我现在正在做一个乒乓球游戏,但是我现在一直在尝试通过按w键将布尔值“goingup”设置为真实状态。在我的渲染类中,布尔值上升,以及int x和int y,并设置为false。在这节课上,我画了一个正方形,x为int x,y为int y。在另一个类(Framemake.java)中,我将一个键侦听器设置为Jframe。在这堂课中,我让keylistener监听w键的按下和释放。这里是我的问题出现的地方:如果按W键,我希望它将goingup改为true,如果它被释放,我希望它变为fals

为了好玩,我现在正在做一个乒乓球游戏,但是我现在一直在尝试通过按w键将布尔值“goingup”设置为真实状态。在我的渲染类中,布尔值上升,以及int x和int y,并设置为false。在这节课上,我画了一个正方形,x为int x,y为int y。在另一个类(Framemake.java)中,我将一个键侦听器设置为Jframe。在这堂课中,我让keylistener监听w键的按下和释放。这里是我的问题出现的地方:如果按W键,我希望它将goingup改为true,如果它被释放,我希望它变为false;这很好,但问题是在我的渲染类中,我设置了一个计时器,然后在graphics方法中启动(不确定正确的名称)。在执行的计时器操作中,我设置了:如果向上是真的,我希望它打印出“向上是真的-渲染”。问题就在这里——尽管由于按下了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) {}
}

我希望这里的问题很清楚(如果我错误地发布了我的代码,请原谅),非常感谢您的帮助。

我想,您的计时器根本没有启动。您可能应该只启动一次,而不是使用
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
方法中?每次重新绘制时都会调用此方法。这很可能也会导致问题。

您应该可以通过简单地添加这样一个方法,然后调用该方法: 公共void setgoingup(布尔b){ 这个.goingup=b; }


Ps:我很累,没有阅读所有的代码-如果我遗漏了任何内容,很抱歉。

问题是,在您的课程
Framemake
中,您没有将
渲染c
添加到
框架中。您正在创建一个局部变量
render

要解决这个问题,只需删除

Render render = new Render();
并将
c
添加到
框架中:

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。尝试并。

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

一个非常简单(而且幼稚)的例子: 创建一个将扮演可观察对象角色的类,以及 与观察者角色的接口及其实现 上课。 保存一个观察者实例的可观察类的列表,以便在需要时通知,并以这种方式进行

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

公共接口观察者{
公开无效通知();
}
可观测的公共类{
公众观察员名单;
公众可观察(){
_观察员=新名单();
}
公共无效注册表观察服务器(观察者obs){
_观察员。添加(obs)
}
公开作废注销观察员(观察员obs){
_观察员:移除(obs);
}
公众观察员{
对于(观察员obs:_观察员){
obs.notify();
}
}
}
公共类SpecificObserver实现了Observer{
//房地产、房地产等
公告{
//在这里接到通知时做一些事情
}
}
在您的程序中:
公共静态void main(字符串[]args){
可观测=新可观测();
SpecificObserver SpecificObserver=新SpecificObserver();
//这里有更多的初始化代码
可观察的。注册观察者(specificObserver);
//等等。。。
//读取输入
string str=YourClass.GetInput();
而(!str.Equals(“EndString”))
{
如果(str.Equals(“SpecificInput”))
{
可观察的;
}
str=YourClass.GetInput();
}
}

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

好的一点,OP确实应该将属性设置为私有,并调用执行所需操作的setter或方法。但这并不是他问题的根源。好吧,如果我错了,我很抱歉,正如我上面所说的,我有点累了,实际上我现在要睡觉了。我想我能帮点忙:PI试过了,它确实起作用了计时器:actionPerformed在控制台中重复,表明计时器正在运行,但是你说我应该在别处启动计时器?好的。是,在Render类的构造函数中启动它。它只需要启动一次。哇,谢谢大家的快速回复-谢谢大家,它现在工作得很好:)。@arunptl100看起来你已经明白了。欢迎来到StackOverflow!
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();
  }

}