简体   繁体   English

Java Swing图形未更新

[英]Java swing graphics not updating

I have a java application that uses Swing graphics which has a 2D array of textfields, each of which are updating their text properly throughout the application. 我有一个使用Swing图形的Java应用程序,该图形具有2D文本字段数组,每个文本字段都在整个应用程序中正确更新其文本。 On each iteration of change, I change the text of the textfield then I make it's background green for half a second and turn it back to white. 每次更改时,我都会更改文本字段的文本,然后将其背景变为绿色半秒钟,然后将其变回白色。 The issue is that, after the first iteration of the change, the textfields no longer flash green. 问题是,在第一次更改之后,文本字段不再闪烁绿色。 When I comment out the portion that converts the background back to white, the rest works and the cells progressively turn green one by one (correctly), which indicates that it is working and executing properly. 当我注释掉将背景转换回白色的部分时,其余部分起作用,并且单元逐渐(正确)逐渐变为绿色,这表明它正在正常运行。 I tried to address this by repainting and revalidating the UI but it's not working. 我试图通过重新粉刷和重新验证UI来解决此问题,但是它不起作用。 What is going on? 到底是怎么回事?

Below is my code that updates the UI. 下面是我的代码,用于更新UI。

    try {
        textfieldArray[row][col].repaint();
        textfieldArray[row][col].revalidate();
        textfieldArray[row][col].setBackground(Color.green);
        textfieldArray[row][col].repaint();
        textfieldArray[row][col].revalidate();
        Thread.sleep(300);
        textfieldArray[row][col].setBackground(Color.white);
        textfieldArray[row][col].repaint();
        textfieldArray[row][col].revalidate();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Swing is a single threaded framework, it also NOT thread safe. Swing是一个单线程框架,它也不是线程安全的。 This means two things. 这意味着两件事。

First, you should never perform any long running or blocking operations within the context of the Event Dispatching Thread and... 首先,您永远不要在事件调度线程和...的上下文中执行任何长时间运行或阻止的操作。

Secondly, you should never update/modify the UI, or anything the UI depends on, from outside the context of the Event Dispatching Thread. 其次,永远不要从事件调度线程的上下文之外更新/修改UI或UI依赖的任何内容。

This means, your Thread.sleep is blocking the EDT, preventing from process paint requests. 这意味着您的Thread.sleep阻止了EDT,从而阻止了进程绘制请求。

Instead, you need some way you can trigger an update to occur after a specified delay. 相反,您需要某种方式可以触发指定的延迟后发生更新。 If that doesn't scream Swing Timer , I don't know what does 如果那没有尖叫Swing Timer ,我不知道该怎么办

I would highly recommend taking the time to read through Concurrency in Swing for the background of why your code isn't working and possibly How to Use Swing Timers for a solution 我强烈建议花点时间阅读Swing中的并发性,以了解为什么代码无法正常工作的背景以及可能如何使用Swing计时器的解决方案

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JTextField field;

        public TestPane() {
            setLayout(new GridBagLayout());
            field = new JTextField("All your bases beloging to us", 20);
            JButton blink = new JButton("Blink");
            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    field.setForeground(null);
                    field.setBackground(null);
                }
            });
            timer.setRepeats(false);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            add(field, gbc);

            blink.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    field.setForeground(Color.WHITE);
                    field.setBackground(Color.GREEN);
                    timer.start();
                }
            });

            add(blink, gbc);
        }

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM