【问题标题】:Editing Text Area within Controller在控制器中编辑文本区域
【发布时间】:2021-06-07 22:40:54
【问题描述】:

我是 Java 和 JavaFX 的新手。我已经使用 SceneBuilder/FXML 创建了一个 JavaFX 项目,并且我试图在程序开始时添加一个实时时钟,该时钟在屏幕顶部的整个程序中运行。我创建了一个文本区域并尝试从给定的代码中添加时钟功能,但每次启动程序时,它总是显示为空白。即使尝试手动使用 .setText("string") 函数也不起作用,所以我认为我将代码放在错误的位置。如果可能的话,有人能告诉我这段代码应该去哪里或指向正确的方向吗?

这是我的主要内容:

package application;
import java.lang.ModuleLayer.Controller;
import java.util.Date;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;



public class Main extends Application {
    
    
    
    public static Stage stage = null;
    @Override
    public void start(Stage stage) throws Exception {
        
        Parent root = FXMLLoader.load(getClass().getResource("/Ui.fxml"));      
        Scene scene = new Scene(root);
        stage.initStyle(StageStyle.UNDECORATED);
        stage.setScene(scene);
        this.stage = stage;
        stage.show();
    }
 
    public static void main(String[] args) {
        launch(args);
    }
}

这是我的控制器代码:

package application;

import java.util.Date;

import javafx.fxml.FXML;

import javafx.scene.control.Button;

import javafx.scene.control.TextField;

import javafx.scene.control.TextArea;

public class UiController {
    @FXML
    private TextArea clockTextArea;
    @FXML
    private TextArea transactionLog;
    @FXML
    private TextField recipentField;
    @FXML
    private Button payButton;
    @FXML
    private Button requestButton;
    @FXML
    private TextField commentField;

    
    
    private void refreshClock()
    {
        Thread refreshClock = new Thread()
           {  
              public void run()
              {  
                while (true)
                {
                    Date dte = new Date();
        
                    String topMenuStr = "       " + dte.toString();                       
                    clockTextArea.setText(topMenuStr); 
                           
                    try
                    {
                       sleep(3000L);
                    }
                    catch (InterruptedException e) 
                    {
                       // TODO Auto-generated catch block
                       e.printStackTrace();
                    }
                  
                }  // end while ( true )
                 
            } // end run thread
         };

         refreshClock.start();
    }

    
    
    public void initialize() {
        
        TextArea clockTextArea = new TextArea();

        refreshClock();
        
        
    }
    
    
    
}



【问题讨论】:

  • 您无法从后台线程更新 UI。
  • hmm ...这看起来与stackoverflow.com/questions/66540928/… 非常相似(包括我评论过的错误)-您是否创建了一个新帐户来重新发布?如果是这样,请不要 - 而是编辑以前的内容以使其可回答。至少,修复已经发现的错误..顺便说一句:创建一个本地文本字段并且不以任何方式使用它(初始化)是..没用的。

标签: java javafx textarea fxml scenebuilder


【解决方案1】:

需要注意的是,无论是在Swing还是JavaFX中,更新控件的时候,都需要在事件派发线程EDT中进行,否则将不起作用或抛出异常Not on FX application thread; currentThread = *

此时只需将更新控制代码的代码放在事件派发线程中即可完成。在 JavaFX 中使用以下代码

Platform.runLater(new Runnable() {
     @Override
     public void run() {
         //Update the control code of JavaFX and put it here
     }
});

所以改变你的代码:

Date dte = new Date();
String topMenuStr = "       " + dte.toString();  
Platform.runLater(() -> clockTextArea.setText(topMenuStr));                    

并检查它是否有效。

【讨论】:

    【解决方案2】:

    一种方法是使用Timeline 来处理时钟。它将独立于您的其他代码。

    主要

    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    import java.io.IOException;
    
    /**
     * JavaFX App
     */
    public class App extends Application {
    
    
        @Override
        public void start(Stage stage) {
            try {
                FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource("primary.fxml"));
                Scene scene = new Scene(fxmlLoader.load(), 1080, 720);
                stage.setScene(scene);
                stage.show();
            } catch (IOException ex) {
                System.out.println(ex.toString());
            }
        }
    
    
        public static void main(String[] args) {
            launch();
        }
    
    }
    

    主控制器

    import javafx.animation.KeyFrame;
    import javafx.animation.Timeline;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.scene.control.Label;
    import javafx.util.Duration;
    
    public class PrimaryController {
        
        @FXML Label lblClock;    
        
        Timeline clockHandler;
        
        @FXML
        void initialize()
        {
            Locale locale_en_US = Locale.US ;  
            DateTimeFormatter formatterUS = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( locale_en_US ) ;
    
            clockHandler = new Timeline(
                     new KeyFrame(Duration.seconds(1), (ActionEvent event) -> {
                         LocalTime currentTime = LocalTime.now();
                         String outputUs = currentTime.format(formatterUS);
                         lblClock.setText(outputUs);
            }));
            clockHandler.setCycleCount(Timeline.INDEFINITE);
            clockHandler.play();        
        }
    }
    

    初级 FXML

    
    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.Menu?>
    <?import javafx.scene.control.MenuBar?>
    <?import javafx.scene.control.MenuItem?>
    <?import javafx.scene.layout.AnchorPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.layout.VBox?>
    
    <VBox alignment="TOP_CENTER" prefHeight="720.0" prefWidth="1080.0" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sed.home.javafxrealtimeclock.PrimaryController">
       <children>
          <MenuBar>
            <menus>
              <Menu mnemonicParsing="false" text="File">
                <items>
                  <MenuItem mnemonicParsing="false" text="Close" />
                </items>
              </Menu>
              <Menu mnemonicParsing="false" text="Edit">
                <items>
                  <MenuItem mnemonicParsing="false" text="Delete" />
                </items>
              </Menu>
              <Menu mnemonicParsing="false" text="Help">
                <items>
                  <MenuItem mnemonicParsing="false" text="About" />
                </items>
              </Menu>
            </menus>
          </MenuBar>
          <HBox>
             <children>
                <Label maxWidth="1.7976931348623157E308" HBox.hgrow="ALWAYS" />
                <Label fx:id="lblClock" text="00:00">
                   <HBox.margin>
                      <Insets />
                   </HBox.margin>
                </Label>
             </children>
             <VBox.margin>
                <Insets left="5.0" right="5.0" />
             </VBox.margin>
          </HBox>
          <AnchorPane prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
             <children>
                <Label layoutX="451.0" layoutY="331.0" text="The other parts of the program here" />
             </children>
          </AnchorPane>
       </children>
    </VBox>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-19
      相关资源
      最近更新 更多