正在为 Java 中的 JTextArea 更新 UI

Updating UI for JTextArea in Java

我是初学者,在路上遇到了一个坎。

我的问题是我的 JTextArea 没有更新,因为我的程序是 运行。我用运行命令行查看JTextArea的值是否在变化。事实证明是的,但是在 UI 上它一直保持到最后,然后它显示了我所做的最终更改。你能帮我找到解决这个问题的方法吗?

下面是出现问题的代码。 (在我的ActionListener.)

private class ButtonHandler implements ActionListener   //Start of inner class for event handling of buttons
{
        public void actionPerformed( ActionEvent event )
        {//start method that prosesses the events for the buttons

            if(event.getSource() == call)
            {
                do {
                    delay.myDelay(2000); //simply a Thread.sleep(I intend to repeat this a lot so I made a class for it.

                    elevatorFloor = eCall.calling();
                    eCall.setFloor(elevatorFloor);
                    System.out.println("getfloor in call= " +eCall.getFloor()); //Test yields correct value

                    eFloor = ind.level(eCall.getFloor()); //String that gives floor number
                    floorIndicator.setText(eFloor); //DOES NOT CHANGE IN GUI

                    String value = floorIndicator.getText();
                    System.out.println("Floorindicator is= " +value);//Test yields that the value  is changing dynamically in command line

                    floorIndicator.updateUI();  //Stuff I found on the internet that didnt work
                    floorIndicator.revalidate();
                    floorIndicator.validate();


                } while(eCall.getFloor() != eCall.getUserFloor());

                    delay.myDelay(2000);

                    doorImage.setIcon(door1);
                }
           }
      }

在 Java 中,UI(组件、事件等的绘制)由称为 Event Dispatching Thread 的特殊线程处理。由于此线程决定了您的 UI 响应事件的速度,因此您只对它执行 UI 相关操作很重要。

不建议在此线程中执行可能阻塞的操作,例如 Thread.sleep,因为它会阻塞线程的执行,从而使您的应用程序无法及时响应事件。这就是为什么在某些评论中,您被告知您正在阻止 EDT。

在你的情况下,循环也可以避免,因为每次迭代,你都在等待两秒钟的时间(我假设给人的印象是自动扶梯在楼层之间移动)。

这个问题的解决方案(至少其中之一)是将 do...while 循环的整个主体放在一个单独的线程中。然后该线程将由事件处理程序启动。这个解决方案不会阻塞事件调度线程,但是现在有另一个问题:只有 EDT 可以上传 UI,因此,上面的方法本身不会改变文本。

为此目的,Java 提供了 SwingWorker class 允许代码在 EDT 上对项目进行排队。

简而言之,您的代码应该是这样的:

private class ButtonHandler implements ActionListener   //Start of inner class for event handling of buttons
{
        public void actionPerformed( ActionEvent event )
        {//start method that prosesses the events for the buttons

            if(event.getSource() == call)
            {
                //final int elFloor = eCall.calling(); i ran it without this and it worked
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        do{
                        /*There is nothing wrong with calling Thread.sleep directly
                         *wrapping a one liner with your own implementation might cause
                         *more confusion
                         */                     
                        delay.myDelay(2000);

                        //Not sure what is elevatorFloor
                        elevatorFloor = eCall.calling();
                        eCall.setFloor(elevatorFloor);
                        System.out.println("getfloor in call= " +eCall.getFloor()); //Test yields correct value

                        eFloor = ind.level(eCall.getFloor()); //String that gives floor number
                        SwingUtilities.invokeLater(new Runnable(){
                            @Override
                            public void run() {
                                floorIndicator.setText(eFloor); //DOES NOT CHANGE IN GUI
                            }
                        });


                        String value = floorIndicator.getText();
                        System.out.println("Floorindicator is= " +value);//Test yields that the value  is changing dynamically in command line

                        }while(eCall.getFloor() != eCall.getUserFloor());

                        //delay.myDelay(2000);

                        doorImage.setIcon(door1);
                    }
                }).start();
            }
       }
}

注意:上面的代码尚未经过测试,您可能需要进行其他更改,尤其是在如何从线程范围内访问变量方面,但它应该提供您需要执行的操作的概述。