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