Java Swing:GUI 未更新某些属性

2024-01-12

编辑:下面是一个最简单、最简单且可检查的问题

RESUME

我正在做一个拉丁方应用程序,它设置一个大小为 s 的正方形,并且您需要使用一些限制来为其着色,例如同一行或同一列中的颜色不同。

但我的麻烦不是问题本身,而是Swing。

我正在尝试使用 Swing 来实现一些图形和更好的外观。

问题是,当我找到解决方案时,我想停下来几秒钟观察它,然后继续寻找其他解决方案(我将使用 Thread.sleep() 来完成此操作)。

但我发现正方形没有着色。只有当完成该方法时,它本身才会发生变化。

主要问题

仅显示它找到的最后一个解决方案,并在完成回溯方法时显示。

当我单击“解析”按钮时,有一个类实现了 ActionListener 接口,该接口具有 actionPerformed 方法,该类调用主框架类的方法来解析正方形。所以问题是,如果我在找到解决方案时停止执行,GUI 不会改变, 但在内部,当我检查属性(调试)时,单元格的颜色已更新,但在 GUI 中却没有。

我不知道为什么:(

更详细

我的想法是,制作一个带有两个面板的框架,一个在左边,一个在中间(也许将来,在右边放一些东西)。

为此,我使用了 BorderLayout。

左侧的第一个面板类似于基本配置菜单,用户可以在其中设置正方形的大小并运行它以获得解决方案。

为此,我有两个按钮,一个用于修改大小,另一个用于解决它。

所以我需要按钮事件。尺寸并没有给我带来问题,但可以解决。

所以我检查了一下,如果我给某个方块着色并暂停执行(Scanner.nextLine()或Thread.sleep())不会在GUI中进行更改,但是当我调试时,方块在属性中被着色,所以我不太明白为什么会失败。

我认为问题出在哪里

所以我有一个按钮,可以在单击时解析正方形。 我想,我真的不知道,但我怀疑,这样做会创建一个新的线程或其他东西,因此无法更新 GUI;并且只有在完成后才去做。

有什么办法可以改变这个吗?

class ResolveListener implements  ActionListener
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                int size = Integer.parseInt(textField.getText());
                latinSquareFrame.resolve(size);
            }
        }

一个简单的问题

我已阅读评论来搜索与此类似的最小且易于检查的问题。

所以我做了。这段代码与我的问题类似,有一个正方形,我想在单击按钮时为其着色。

问题是,如果我暂停它,它不会着色,只有在方法完成时才会着色,我不知道为什么。

我认为这与我之前遇到的问题类似。

这是我能够用于解决我遇到的问题的最少代码。

    package LatinSquare;


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;

public class Test
{
    public static void main(String[] args)
    {
        TestFrame testFrame = new TestFrame();
    }
}

class TestFrame extends JFrame
{

    public TestFrame()
    {
        this.setVisible(true);
        this.setBounds(400,300,400,300);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLayout(new BorderLayout());
        TestJPanel testJPanel = new TestJPanel();
        this.add(testJPanel,BorderLayout.CENTER);

        TestContainerButtonJPanel testContainerButtonJPanel = new TestContainerButtonJPanel(testJPanel);
        this.add(testContainerButtonJPanel, BorderLayout.SOUTH);

        this.revalidate();
        this.repaint();
    }

}

class TestContainerButtonJPanel extends JPanel
{
    private JButton resolve;
    public TestJPanel testJPanel;

    public TestContainerButtonJPanel(TestJPanel testJPanel)
    {
        this.testJPanel = testJPanel;
        this.setVisible(true);
        resolve = new JButton("RESOLVE");
        ActionListener resolveListener = new ResolveListener();
        resolve.addActionListener(resolveListener);
        this.add(resolve);

    }

    class ResolveListener implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            try {
                TestContainerButtonJPanel.this.testJPanel.colourCells();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }


    }
}


class TestJPanel extends JPanel
{
    private JButton[][] board;
    public TestJPanel()
    {
        this.board = new JButton[4][4];
        this.setVisible(true);
        this.setLayout(new GridLayout(4,4));
        for(int i=0; i<4;i++)
        {
            for(int j=0; j<4;j++)
            {
                JButton cell = new JButton();
                board[i][j] = cell;
                board[i][j].setBackground(Color.WHITE);
                this.add(cell);
            }
        }

    }

    public void colourCells() throws InterruptedException {
        for(int i=0; i<4;i++)
        {
            for(int j=0;j<4;j++)
            {
                this.board[i][j].setBackground(Color.RED);
                Thread.sleep(300);

            }
        }

    }


}

好的,首先要做的事情是:

  1. 不要使用以下方式更新您的 GUIThread.sleep()它将阻止 EDT
  2. 您没有将程序放在 EDT 上,请参阅中的第 2 点这个答案 https://stackoverflow.com/questions/42404270/jcomponent-stops-getting-rendered-once-it-goes-off-the-screen/42404808#42404808
  3. 不要延长JFrame,而是创建它的实例,请参阅:扩展 JFrame 与在程序内创建它 https://stackoverflow.com/questions/22003802/extends-jframe-vs-creating-it-inside-the-program
  4. 不要让你的程序可见(即调用setVisible(...)),然后再将所有组件添加到其中。它可能会导致您的程序以错误的方式运行。
  5. 尝试不要创建自己的线程,而是使用Swing Timer or a Swing Worker(问题评论中的链接)

因此,考虑到所有这些,我决定创建一个新程序,该程序遵循上述所有规则,使单元格保持蓝色 3 秒,或在该时间过去后保持白色,同时更新单元格中的文本。JButton以及禁用以防止多个计时器同时执行。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Test {
    private JFrame frame;
    private JPanel pane;
    private JPanel cellsPane;
    private MyCell[][] cells;
    private JButton button;
    private Timer timer;

    private int counter = 3;
    private boolean isFinished = false;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Test().createAndShowGui());
    }

    private void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());

        pane = new JPanel();
        cellsPane = new JPanel();

        pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
        cellsPane.setLayout(new GridLayout(4, 4, 5, 5));

        cells = new MyCell[4][4];

        for (int i = 0; i < cells.length; i++) {
            for (int j = 0; j < cells[i].length; j++) {
                cells[i][j] = new MyCell(Color.WHITE);
                cellsPane.add(cells[i][j]);
            }
        }

        button = new JButton("Press me!");
        timer = new Timer(1000, listener);

        button.addActionListener(e -> {
            button.setEnabled(false);
            isFinished = false;
            updateCellsColors();
            timer.start();
        });

        pane.add(cellsPane);
        pane.add(button);

        frame.add(pane);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private void updateCellsColors() {
        for (int i = 0; i < cells.length; i++) {
            for (int j = 0; j < cells[i].length; j++) {
                cells[i][j].setCellColor(isFinished ? Color.WHITE : Color.BLUE);
            }
        }
    }

    private ActionListener listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (counter == 0) {
                timer.stop();
                counter = 3;
                isFinished = true;
                button.setEnabled(true);
                updateCellsColors();
            }
            if (isFinished) {
                button.setText("Press me!");
            } else {
                button.setText("You have " + counter + " seconds remaining");
            }
            counter--;
        }
    };
}

@SuppressWarnings("serial")
class MyCell extends JPanel {
    private Color cellColor;

    public Color getCellColor() {
        return cellColor;
    }

    public void setCellColor(Color cellColor) {
        this.cellColor = cellColor;
        this.setBackground(cellColor);
    }

    public MyCell(Color cellColor) {
        this.cellColor = cellColor;
        this.setOpaque(true);
        this.setBackground(cellColor);
    }

    @Override
    public Dimension getPreferredSize() {
        // TODO Auto-generated method stub
        return new Dimension(30, 30);
    }
}

你可以复制粘贴它并看到与我相同的结果:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java Swing:GUI 未更新某些属性 的相关文章

  • 如何将画廊意图中的“打开”更改为“完成”?

    我使用以下意图打开画廊来选择多个图像和视频 Intent intent new Intent intent setType image video intent putExtra Intent EXTRA ALLOW MULTIPLE tr
  • Java Runtime.getRuntime().freeMemory() 问题

    我搜索并看到了一些线程 但没有一个能够解决我遇到的具体问题 我正在尝试使用以下方式监视我的内存使用情况Runtime getRuntime freeMemory Runtime getRuntime maxMemory and Runtim
  • 如何在 Firebase 远程配置中从 JSON 获取值

    我是 Android 应用开发和 Firebase 的新手 我想知道如何获取存储在 Firebase 远程配置中的 JSONArray 文件中的值 String 和 Int 我使用 Firebase Remote Config 的最终目标是
  • 打印星号的 ASCII 菱形

    我的程序打印出这样的钻石 但只有当参数或菱形的每一面为4 例如如果我输入6 底部三角形的间距是错误的 我一直在试图找出答案 当参数改变时 底部的三角形不会改变 只有顶部的三角形会改变 它只适用于输入4 public static void
  • 不同类型的数组

    是否可以有一个包含两种不同类型数据的数组 我想要一个包含双精度型和字符串的数组 我尝试过 ArrayList
  • Spring Data JPA 选择不同

    我有一个情况 我需要建立一个select distinct a address from Person a 其中地址是 Person 内的地址实体 类型的查询 我正在使用规范动态构建我的 where 子句并使用findAll Specifi
  • 大数据使用什么数据结构

    我有一个包含一百万行的 Excel 工作表 每行有 100 列 每行代表一个具有 100 个属性的类的实例 列值是这些属性的值 哪种数据结构最适合在这里使用来存储数百万个数据实例 Thanks 这实际上取决于您需要如何访问这些数据以及您想要
  • 如何在代理后面安装 Eclipse Neon

    对于 Neon Eclipse 附带了一个安装程序 我在安装程序中找不到任何配置菜单 我的java版本是 java version java version 1 8 0 72 Java TM SE Runtime Environment b
  • Jackson XML ArrayList 输出具有两个包装器元素

    我在 Jackson 生成的 XML 输出中得到了两个包装器元素 我只想拥有一个 我有一个 Java bean Entity Table name CITIES JacksonXmlRootElement localName City pu
  • 在另一个模块中使用自定义 gradle 插件模块

    我正在开发一个自定义插件 我希望能够在稍后阶段将其部署到存储库 因此我为其创建了一个独立的模块 在对其进行任何正式的 TDD 之前 我想手动进行某些探索性测试 因此 我创建了一个使用给定插件的演示模块 到目前为止 我发现执行此操作的唯一方法
  • 如何避免 ArrayIndexOutOfBoundsException 或 IndexOutOfBoundsException? [复制]

    这个问题在这里已经有答案了 如果你的问题是我得到了java lang ArrayIndexOutOfBoundsException在我的代码中 我不明白为什么会发生这种情况 这意味着什么以及如何避免它 这应该是最全面的典范 https me
  • 了解joda时间PeriodFormatter

    我以为我明白了 但显然我不明白 你能帮我通过这些单元测试吗 Test public void second assertEquals 00 00 01 OurDateTimeFormatter format 1000 Test public
  • 如何在 Spring 属性中进行算术运算?

  • 内部存储的安全性如何?

    我需要的 对于 Android 我需要永久保存数据 但也能够编辑 并且显然是读取 它 用户不应访问此数据 它可以包含诸如高分之类的内容 用户不得对其进行编辑 我的问题 我会 并且已经 使用过Internal Storage 但我不确定它实际
  • Java实现累加器类,提供Collector

    A Collector具有三种通用类型 public interface Collector
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • OpenCSV:将嵌套 Bean 映射到 CSV 文件

    我正在尝试将 bean 映射到 CSV 文件 但问题是我的 bean 具有其他嵌套 bean 作为属性 所发生的情况是 OpenCSV 遍历属性找到一个 bean 然后进入其中并映射该 bean 内的所有数据 如果找到另一个 bean 它就
  • 如何重新启动死线程? [复制]

    这个问题在这里已经有答案了 有哪些不同的可能性可以带来死线程回到可运行状态 如果您查看线程生命周期图像 就会发现一旦线程终止 您就无法返回到新位置 So 没有办法将死线程恢复到可运行状态 相反 您应该创建一个新的 Thread 实例
  • 泛型、数组和 ClassCastException

    我想这里一定发生了一些我不知道的微妙事情 考虑以下 public class Foo
  • 在浏览器刷新中刷新检票面板

    我正在开发一个付费角色系统 一旦用户刷新浏览器 我就需要刷新该页面中可用的统计信息 统计信息应该从数据库中获取并显示 但现在它不能正常工作 因为在页面刷新中 java代码不会被调用 而是使用以前的数据加载缓存的页面 我尝试添加以下代码来修复

随机推荐

  • 如何将可选列表与上下文操作栏一起使用?

    我在这里阅读新的 Android 设计标准 http developer android com design patterns selection html http developer android com design patter
  • 如果批量使用GTR/LSS运算符

    我有一个越来越大的批处理文件 它使用GTR LSS运营商 问题是if语句只允许我输入某些值 在以下示例中 输入值 2 3 或 4 将返回 值太高 char intb set char points 30 set a limit char p
  • wsdl2java - 警告:无法初始化默认密钥管理器

    在生成 java WSDL 客户端时 我收到这些错误 你能帮我理解这些吗 C Users Administrator workspace apache cxf 3 0 2 bin gt wsdl2javahttps example com
  • 使用 TF-IDF 分数进行文本分类的 KNN

    我有一个 CSV 文件 corpus csv 其中包含语料库中以下格式的分级摘要 文本 Institute Score Abstract UoM 3 0 Hello this is abstract one UoM 3 2 Hello th
  • Android studio 防止粘贴时代码重新格式化[重复]

    这个问题在这里已经有答案了 我已经开始使用 Android Studio 取代 Eclipse 但我无法习惯的一件事是 Studio 如何自动 在某些情况下 重新格式化当前文件中的部分甚至全部代码 其中一种情况是将文本粘贴到我的文件中 当我
  • 正则表达式:+$ VS *$ VS 无

    在正则表达式中 有什么区别 a zA Z and a zA Z 我也可以根本不包括它吗 a zA Z or a zA Z 我在网上查了一下 上面写着 匹配前面的字符一次或多次并且 匹配前面的字符零次或一次 但我不知道这在这种情况下意味着什么
  • 删除按钮处于活动状态(单击)时的阴影

    我有这个 CSS 用于按钮动画和其他 btnliner background url images btnbg png no repeat center 105px Fallback display block text align cen
  • 如何用C#模拟浏览器HTTP POST请求并捕获结果

    假设我们有一个带有搜索输入表单的网页 它通过 HTTP GET 将数据提交到服务器 这意味着服务器通过查询字符串接收搜索数据 用户可以看到 URL 也可以自己初始化此请求 通过 URL 查询字符串 我们都知道 这是问题所在 如果这个网页通过
  • Javascript:显示带有复选框值的图像

    我目前正在使用单选按钮和复选框来在 javascript 的帮助下显示图像 具体来说 我在处理复选框和显示图像时遇到问题 使用单选按钮时 只会显示该类别的一张图像 但对于复选框 需要显示多个图像 例如 用户可以检查夹克和手套的字段 并且将显
  • 如何在node.js中使用CasperJS?

    我想在node js 中使用CasperJS 我参考了以下 URL 在 node js 中使用 CasperJS https github com sgentle phantomjs node https github com sgentl
  • Angular Js:类属性指令中的 onchange 不起作用

    控制指令 js function validVehicleyear scope http return restrict C scope ngModel link function scope element attrs ngModel e
  • 在 Docker 中启动并填充 Postgres 容器

    我有一个包含 Postgres 数据库的 Docker 容器 这是用官方的Postgres 图像 https registry hub docker com postgres 其中有一个 CMD 条目在主线程上启动服务器 我想通过运行来填充
  • xcode 8 错误被服务委托拒绝 (SBMainWorkspace)

    尝试在模拟器上运行构建 我收到此错误 打开 com companyname appname 的请求失败 请求被服务委托 SBMainWorkspace 拒绝 原因 安全 权利 启动需要 com apple frontboard debuga
  • 如何传递通用方法的 lambda 表达式参数以检查 MVC EF 4.0 中的重复项

    我的应用程序中有超过 10 个设置屏幕 在每个数据中 我都必须检查重复数据 例如 这是一个示例代码 private void CheckDuplication AIRLINE airline var AIRLINE context AIRL
  • React Native 不会填满 iPad 上的窗口

    我正在运行的任何 React Native 项目 包括 Facebook 的示例 在 iPad 上看起来都很奇怪 它没有填满屏幕 一切看起来 太大 内容左右各有2个黑条 任何帮助都会很棒 谢谢 解决方案 在 xcode 项目中 转到常规选项
  • 使用javascript获取具有多个下拉菜单的选项的选定值

    我有多个功能 其中有多个选项 在选择某个选项时需要更新这些选项 我还需要通过属性元素传递第三条数据 getElementById 适用于单个下拉菜单 但是当页面上有多个菜单时如何使其工作 我努力了var e document getElem
  • jQuery stop(true, true) 跳转到队列中所有动画的末尾

    我一直在使用 jQuerystop true true 方法清除正在运行的动画 以便下一个立即开始 我注意到第一个参数 clearQueue 清除整个动画队列 但第二个参数 jumpToEnd 仅跳转到当前正在运行的动画的末尾 而不是从队列
  • 如何静音AVPlayer中播放的视频?

    我正在 AVPlayer 中播放视频 现在我需要在播放时单独静音音频 请建议如何在 Objective C 中进行操作 谢谢 苏雷什 从iOS7开始你可以设置AVPlayerisMuted财产给true 在 Objective C 中 该属
  • 在 Entity Framework 4.1 Code First 中排除列可更新

    有谁知道我们是否可以在 Entity Framework 4 1 Code First 中排除列的更新 例如 我有 CreatedOn 字段 我不想在进行编辑 更新时包含该字段 这是否可能 即有选择地从 EF Code First 4 1
  • Java Swing:GUI 未更新某些属性

    编辑 下面是一个最简单 最简单且可检查的问题 RESUME 我正在做一个拉丁方应用程序 它设置一个大小为 s 的正方形 并且您需要使用一些限制来为其着色 例如同一行或同一列中的颜色不同 但我的麻烦不是问题本身 而是Swing 我正在尝试使用