【问题标题】:Displaying 2D array contents on GUI colours在 GUI 颜色上显示 2D 数组内容
【发布时间】:2014-02-16 23:35:47
【问题描述】:

我正在创建基于代理的建模程序。到目前为止,我有相关的类来模拟模拟器、网格、不同的代理等。我还创建了一个 2D 对象数组,例如代理在阵列周围移动做任何事情。

我熟悉创建简单的 GUI,但我如何创建一个窗格\面板,然后将其添加到 GUI。它显示了运行时的二维数组,每个对象都有相应的颜色。另外我想尝试使用 MVC 模式来基本上以不同的方式显示模拟数据。例如,一个窗格显示不同的对象颜色,而另一个窗格显示相同的对象,但每个对象的愤怒级别都具有不同的红色深浅。任何指南都会对类似的教程很有帮助。

谢谢

【问题讨论】:

    标签: java model-view-controller simulation multidimensional-array agent-based-modeling


    【解决方案1】:

    我会创建一个队列(JMS 用于非常大的代理列表,但有一些内存中的队列实现使用起来更快)并允许您的所有代理在其中写入他们的状态。然后在另一方面,我会编写一个消费者来侦听队列,以便让您的 GUI 在这些状态即将到来时对其进行处理。

    如果有太多事件,您可能希望根据一些对您有意义的刷新率定期分批处理它们。

    【讨论】:

    • 有什么例子吗?消费者是代理类中的一个方法还是一个单独的类?
    • 如果您的代理适合某种内存集合,请忽略我的回答。请参阅@dakkaron 答案。我只会稍微改进他的解决方案,而不是只设置 4 种颜色,而是使用更广泛的调色板。但我认为他/她都说了。
    【解决方案2】:

    您可以使用 awt 和 swing 之类的 GUI API(例如,查看Java 2D game graphics)来创建一个画布,您可以在该画布上绘制系统的表示。例如,一组圆圈和边缘,如果圆圈被填充,则那里有一个代理,您可以将鼠标悬停在它上面或单击它,另一个面板会显示代理的一些相关属性。也许来自实心圆圈的箭头表示代理接下来要去的地方。

    您可以实例化一个画布(如 java.awt.canvas),它适合您的 GUI,就像任何其他小部件(面板组合框等)一样,它是否具有您可以添加滚动条等的大小。与其他控件(如组合)相反框,画布是一个 2d 区域,您可以在其上绘制任何您想要的东西。

    MVC 是一种设计结构,它沿视图、控制、模型轴分离应用程序关注点。虽然您可以将所有控制逻辑(例如用户输入处理、数据库连接处理、网络操作)都放在画布类事件处理方法中的一个位置,但在 MVC 中,您可以将所有控制逻辑与画布、画布事件处理程序分开只会调用适当的控制器方法(例如handleNewFile)。反过来,控制器查询模型并告诉视图要显示的内容(例如,它遍历模型中的所有代理并将代理“添加”到视图中。视图是您决定如何表示代理的地方,控制器与表示。

    【讨论】:

    • 所以基本上用二维数组的相应行、列创建画布,画布会是进入 GUI 的组件吗?我也可以将它合并到 MVC 模式中。
    • 我的模拟是如何工作的,它遍历集合并调用代理中的 act 方法以有效地围绕网格(二维数组)移动一步。画布绘图的刷新率怎么样 我想在每次模拟的 1 步完成时在画布上绘制图形。我如何实现这一目标?
    • @user3112844 SO 是问答论坛而不是讨论论坛。请专注于一个问题,并保持你的问题集中,否则如果太宽泛,它就会被关闭。接受您认为最有用的答案或澄清为什么答案没有足够的帮助,以便作者可以改进,但不要继续扩展更多问题。尝试获得足够的代表来支持您认为有用的答案(不仅仅是您的问题),这使得 SO 成为如此有用的数据库。
    【解决方案3】:

    一种更简单的方法是创建一个扩展 javax.swing.panel 并覆盖 paintComponent() 方法的新类。

    在新类的构造函数中传递对二维数组的引用。

    在你重写的paintComponent()方法中做这样的事情:

    public void paintComponent(Graphics g) {
        for (int x=0;x<arrayWidth;x++) {
            for (int y=0;y<arrayHight;y++) {
                switch (array[x][y]) {
                    case 1: g.setColor(Color.RED);break;
                    case 2: g.setColor(Color.BLUE);break;
                    case 3: g.setColor(Color.GREEN);break;
                    case 4: g.setColor(Color.YELLOW);break;
                }
                g.drawRect(x*10,y*10,10,10);
            }
        }
    }
    

    只需根据您的需要调整数字和颜色即可。

    编辑:如果您有某种不能在 switch 语句中使用的值(例如,旧 Java 版本中的自定义类或字符串),只需将其替换为 if/elseifs:

    public void paintComponent(Graphics g) {
        for (int x=0;x<arrayWidth;x++) {
            for (int y=0;y<arrayHight;y++) {
                if (array[x][y].equals(value1)) {
                    g.setColor(Color.RED);
                } else if (array[x][y].equals(value2)) {
                    g.setColor(Color.BLUE);
                } else if (array[x][y].equals(value3)) {
                    g.setColor(Color.GREEN);
                } else {
                    g.setColor(Color.YELLOW);
                }
                g.drawRect(x*10,y*10,10,10);
            }
        }
    }
    

    【讨论】:

    • switch 语句出现错误“无法打开 Agent 类型的值。只允许可转换的 int 值、字符串或枚举变量”
    • 那么如果你的数组是Agent,如果你的agent有一个int值,你可以通过Agent.getValue()进行切换
    • 您也可以用 if-elseifs 替换 switch-case 结构。我会将其添加到解决方案中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2014-10-22
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    • 2020-02-02
    相关资源
    最近更新 更多