【问题标题】:GUI Making Arrays of Images that Move Using Mouse EventGUI 制作使用鼠标事件移动的图像数组
【发布时间】:2014-09-25 22:40:44
【问题描述】:

目前,我对这项任务感到不知所措。我才 3 周进入 Java 编程,我得到了这段代码,并被告知以我不完全熟悉的方式对其进行修改。因此,任何帮助将不胜感激。我真的很想了解这一点,所以任何信息都会有所帮助。

我目前正在努力的方向是:

"修改 Model 类以存储 Turtles 的 ArrayList。使 Model.update 为 ArrayList 中的每个 Turtle 调用 Turtle.update。至 测试一下,在 ArrayList 中放两三只海龟,每只从 不同的位置。当您单击时(这会导致“setDestination” 被调用),让所有的海龟前往同一个目的地。得到 在你继续之前还有这么多工作。”

在我创建这些海龟的数组之前,一只海龟表现良好。现在我已经创建了一个数组,我的面板上没有显示任何内容。不过,它确实可以正确编译。我知道我应该制作单独的 Graphics 对象,但是如何以及在哪里是最好的地方呢?这是代码(在 4 个单独的文件中):

Controller.java

import java.awt.Graphics;
import java.io.IOException;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import javax.swing.Timer;

class Controller implements MouseListener
{
    Model model;
    View view;

    Controller() throws IOException, Exception {
        model = new Model();
        view = new View(this);
        new Timer(50, view).start();
    }

    public void update(Graphics g) {
        model.update(g);
    }

    public void mousePressed(MouseEvent e) {
        model.setDestination(e.getX(), e.getY(), view.getWidth(), view.getHeight());
    }

    public void mouseReleased(MouseEvent e) {    }
    public void mouseEntered(MouseEvent e) {    }
    public void mouseExited(MouseEvent e) {    }
    public void mouseClicked(MouseEvent e) {    }

    public static void main(String[] args) throws Exception {
        //  Use the following line to determine which directory your program
        //  is being executed from, since that is where the image files will
        //  need to be.
        //System.out.println("cwd=" + System.getProperty("user.dir"));
        new Controller();
    }
}

模型.java

import java.awt.Graphics;
import java.io.IOException;

class Model
{
    private Turtle[] t;

    Model() throws IOException {
        Turtle[] t = new  Turtle[3];    
            for (int i = 0; i <3; i++)
             t[i] = new Turtle();

       // turtle = new Turtle();
    }

    public void update(Graphics g) {         
        for(int i = 0; i <3; i++)
            t[i].update(g);             
    }

    public void setDestination(int x, int y, int width, int height) {
        for(int i = 0; i <3; i++)
        { 
            t[i].setDest(x, y);
        }    
    }    
}

乌龟.java

import java.awt.Graphics;
import java.awt.Image;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.util.Random;

class Turtle
{
    private int x;
    private int y;
    private int dest_x;
    private int dest_y;
    private Image image;

    Turtle() {
        try {
            image = ImageIO.read(new File("turtle.png"));
        } catch (IOException ioe) {
            System.out.println("Unable to load image file.");                
        }            
    }

    public int getX() { return x; }
    public int getY() { return y; }

    public void setX(int xIn) { x = xIn; }
    public void setY(int yIn) { y = yIn; }

    public void update(Graphics g) {
        // Move the turtle
        if (x < dest_x) {
            x += 1;
        } else if (x > dest_x) {
            x -= 1;
        }

        if (y < dest_y) {
            y += 1;
        } else if (y > dest_y) {
            y -= 1;
        }

        // Draw the turtle                     
    }

    public void setDest(int x, int y) {
        dest_x = x;
        dest_y = y;
    }
}

View.java

import javax.swing.JFrame;
import java.awt.Graphics;
import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class View extends JFrame implements ActionListener {

    private class MyPanel extends JPanel {
        Controller controller;

        MyPanel(Controller c) {
            controller = c;
            addMouseListener(c);
        }

        public void paintComponent(Graphics g) {
            controller.update(g);
            revalidate();
        }
    }


    public View(Controller c) throws Exception{
        setTitle("Assignment 4");
        setSize(1000, 700);
        getContentPane().add(new MyPanel(c));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent evt) {
        repaint();
    }
}

【问题讨论】:

    标签: java arrays object user-interface jpanel


    【解决方案1】:

    老师提供的代码让我非常惊讶;通常它很糟糕,但这个很不错。虽然你只需要修改一个类,但请允许我多评论一下,因为“任何信息也会有帮助”

    控制器

    class Controller extends MouseAdapter
    

    而不是

    class Controller implements MouseListener
    

    让你摆脱所有的空方法

    public void mouseReleased(MouseEvent e) {    }
    public void mouseEntered(MouseEvent e) {    }
    public void mouseExited(MouseEvent e) {    }
    public void mouseClicked(MouseEvent e) {    }
    

    (如果您需要用其他东西扩展控制器,只需创建一个扩展 MouseAdapter 的内部类并使用它。)

    乌龟

    应该公开一个构造函数,例如

    Turtle(int x, int y) {
    
        this();
        this.x = x;
        this.y = y;
    }
    

    这样

    Turtle t = new Turtle();
    t.setX(4);
    t.setY(6);
    

    可以替换为

    new Turtle(4, 6);
    

    此外,dest_xdest_y 应重命名为 destXdestY,因为下划线 (_) 仅用于 final 实例的名称。

    最后,你需要换行

    // Draw the turtle
    

    g.drawImage(image, x, y, null);
    

    查看

    中指定的尺寸
    setSize(1000, 700);
    

    应该定义为字段(不要在代码中散布任意数字)

    int sizeX = 1000, sizeY = 700;
    ...
    setSize(sizeX, sizeY);
    

    并且应该暴露出来,以便在为海龟选择初始位置时它们不会越界。

    型号

    您被问到:Modify the Model class to store an ArrayList of Turtles,但您出于某种原因创建了一个数组。下面是一个示例,说明您可以采取哪些措施使其发挥作用:

    public class Model {
    
        private List<Turtle> turtList = new ArrayList<>();
        private int turtleNumber = 3;
    
        Model() throws IOException {
    
            for (int i = 0; i < turtleNumber; i++) {
                Turtle turt = new Turtle();
                turt.setX(Math.round((float)Math.random() * 1000));
                turt.setY(Math.round((float)Math.random() * 700));
                turtList.add(turt);
            }
        }
    
        public void update(Graphics g) {
    
            for (int i = 0; i < turtleNumber; i++)
                turtList.get(i).update(g);
        }
    
        public void setDestination(int x, int y, int width, int height) {
    
            for (Turtle turt : turtList)
                turt.setDest(x, y);
        }
    }
    

    我将我想要的海龟数量定义为一个字段并在整个代码中使用它,因此当我更改数字时我只需要在一个地方进行更改。

    在构造函数中,我使用给定的海龟构造函数(一个空构造函数)循环并随机将它们放置在框架的边界内(它们应该从ViewsizeXsizeY 中读取)。然后我将修改后的海龟添加到列表中。

    出于教学目的,我为updatesetDestination 使用了两种不同的循环结构。选择你想要的(注意你不需要知道海龟的数量)。

    【讨论】:

    • 哇!你为我打破了这个非常有帮助。对此,我真的非常感激。在下一个方向,他说:“将 Turtle 类的 dest_x 和 dest_y 变量设置为静态变量,因为所有 Turtle 对象实例将共享相同的目标。此外,将 setDest 函数设置为静态并确保从模型中正确调用它。”我得到了一切静态的东西,但我不是 100% 知道如何从模型中正确调用它。我不应该让它保持原样,对吧?那么有什么好的参考呢?谢谢一百万!
    • @Heather 我假设你得到了正确绘制图像的线。由于我们解决了您问题中的问题,我建议您使用新目标和更新的代码创建一个新问题。您可以在此处提供指向此问题的链接以保持连续性。
    • 是的,我做到了。再次感谢!
    • 会的!我是新来的 :)
    【解决方案2】:

    Model 类的构造函数中,您有一行

    Turtle[] t = new  Turtle[3];
    

    你也有类变量,

    Turtle[] t
    

    但没有将在构造函数中初始化的数组分配给类变量,因此仅考虑该方法的范围,因此为什么不绘制任何内容,就像稍后使用变量 t 时一样没有被初始化,所以你得到NullPointerExceptions

    要解决这个问题,只需更改行

    Turtle[] t = new  Turtle[3];
    

    t = new  Turtle[3];
    

    现在这只会显示为一张图像,但实际上是 3 只海龟相互叠加。所以要解决这个问题,你需要一些额外的代码来将海龟放在不同的起始位置,但我会让你弄清楚这部分。

    【讨论】:

    • 感谢您的回复!我不确定当我复制这个不包括在内时如何/为什么,但即使我修复了那个位,我的海龟仍然没有出现。
    • @Heather 哦,真奇怪……那还有什么遗漏的吗?
    • 我不这么认为。我需要为每只海龟使用一个新的图形对象吗?
    • @Heather 不,您不需要单独的图形对象。请参阅我编辑的答案,也应该早些看到。
    猜你喜欢
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多