【问题标题】:How to add a timestamp in java on a pane如何在窗格中的Java中添加时间戳
【发布时间】:2021-12-12 21:06:47
【问题描述】:

我目前正在处理这个任务,即使我没有真正弹出任何错误,我似乎也无法让这个程序运行?我也在尝试向窗格添加时间戳,但每次我将时间戳的“ts”名称添加到窗格或 Hbox 的 get children 代码时,它都会变红。我不确定我到底在做什么错了,如果有人能指出我正确的方向,我将不胜感激......

package PCK1;

import javafx.event.ActionEvent;  
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import java.sql.Timestamp;    
import java.util.Date;  
import java.text.SimpleDateFormat;  

public class MainClass
{

    public static void start(Stage stage)
    {
    
    // Time Stamp
    Date date = new Date();  
     Timestamp ts=new Timestamp(date.getTime());  
     SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
       System.out.println(formatter.format(ts));
   
    //Create a Circle
    Circle c1 = new Circle(75,100,20);  



    //Create a Pane
    Pane p = new Pane();
    p.setMinSize(100, 150);
    p.setBackground(new Background(new BackgroundFill( Color.rgb(190, 220, 190), null, null) 
    ));
    p.getChildren().addAll(c1);

   
   
    //Create a Button
    Button btnUp = new Button("Up");
    btnUp.setOnAction((ActionEvent e) -> {double y = c1.getCenterY();
    y -= 20.0;
    c1.setCenterY(y);
     });

    Button btnDown = new Button("Down");
    btnDown.setOnAction((ActionEvent e) -> {double y = c1.getCenterY();
    y += 20.0;
    c1.setCenterY(y);
     });



    //Create a HBox
    HBox hb = new HBox();
    hb.getChildren().addAll(btnUp, btnDown, p, ts);
    hb.setBackground(new Background(new BackgroundFill(Color.rgb(150,200,150),null,null)));
    hb.setMinSize(100, 50);
    hb.setPadding(new Insets(10,10,10,10));

  

 
    Scene scene = new Scene(hb);
  
      stage.setScene(scene);
      stage.setTitle("JavaFx");
      stage.setWidth(250);
      stage.setHeight(250);
      stage.show();
    }
}

【问题讨论】:

  • 什么是“变红”?
  • TimeStap 是一个节点吗?是 POJO 吗?
  • 顺便说一句:不要使用过时的日期(和相关)类,而是使用新的 LocalDate/Time
  • tutorial trail 表示您应该使用的时间类。请花一些时间研究它并相应地调整您的代码。时间 API 选择是一个最佳实践问题,而不是您当前代码的(多个)编译和运行时问题的直接原因,这将不起作用。

标签: java javafx timestamp pane


【解决方案1】:

显示时间戳的答案

具体来说,关于时间戳的问题,请看下面的示例代码:

private Label createTimestampLabel() {
    LocalDateTime now = LocalDateTime.now();
    String formattedTimestamp = now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);

    return new Label(formattedTimestamp);
}

它使用Oracle Date Time tutorial 中解释的java.time API 从 LocalDateTime 获取当前时间,并使用标准格式将其格式化为字符串。

它将格式化的时间戳字符串设置为标签节点的文本。

现在返回的元素是一个节点,它可以放置在场景图中而不会产生您在原始示例中看到的编译错误。

在您的问题中,使用java.time API 优于java.sql.Timestampjava.util.Date 代码。你没有使用 SQL,所以你不应该使用java.sql.Timestampjava.time 类还对其他 Java 包(如 java.util)中使用的过时日期和时间函数进行了许多改进。

通过重写示例代码在上下文中回答

所提供的示例应用程序有很多错误或惹恼我的地方。

所以我重新编写了它以更接近我通常编写此类应用程序的方式。

在选择如何实施重写时可能有一百个不同的小决定,在这里解释它们太冗长了。

希望您可以将重新编写的代码与您的原始代码进行比较,注意其中的一些差异,并从中学习一些东西。

GraphicControlApp.java

package org.example.javafx.demo.graphiccontrol;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class GraphicControlApp extends Application {

    public void start(Stage stage) {
        GraphicController graphicController = new GraphicController();

        Scene scene = new Scene(graphicController.getUI());

        stage.setScene(scene);
        stage.setTitle("JavaFX Interactive Graphic Control Demonstration");
        stage.show();
    }

}

GraphicController.java

import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * UI creator and controller for application logic.
 *
 * Normally, most UI elements would be defined externally in FXML,
 * however, for a simple application, we define the UI via private functions in this class.
 */
public class GraphicController {
    // amount to move the circle across the surface on interaction.
    private static final double MOVEMENT_DELTA = 20.0;

    // default spacing between UI elements.
    private static final double SPACING = 10;

    // normally the styles would be configured in an external css stylesheet,
    // but we place the background definitions here for a simple application.
    private static final Color SURFACE_COLOR = Color.rgb(190, 220, 190);
    private static final Background surfaceBackground = createBackground(SURFACE_COLOR);
    private static final Color APP_BACKGROUND_COLOR = Color.rgb(150, 200, 150);
    private static final Background appBackground = createBackground(APP_BACKGROUND_COLOR);

    private Button up;
    private Button down;

    /**
     * @return the complete layout for the application with event handlers attached for logic control.
     */
    public Pane getUI() {
        Circle circle = new Circle(75, 100, 20);

        Pane surface = createSurface(circle);
        HBox controls = createControls(circle);
        Label timestampLabel = createTimestampLabel();

        Pane layout = createLayout(surface, controls, timestampLabel);
        attachKeyboardHandlers(layout);

        return layout;
    }

    /**
     * Create a label formatted with the current time in ISO standard format (e.g. '2011-12-03T10:15:30')
     *
     * @return label with the current timestamp.
     */
    private Label createTimestampLabel() {
        LocalDateTime now = LocalDateTime.now();
        String formattedTimestamp = now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);

        return new Label(formattedTimestamp);
    }

    /**
     * Create a surface on which a circle can move.
     *
     * @param circle the circle which can move on the surface.
     * @return the created surface.
     */
    private Pane createSurface(Circle circle) {
        Pane surface = new Pane();

        surface.setMinSize(100, 150);
        surface.setBackground(surfaceBackground);
        surface.getChildren().addAll(circle);

        // we must define a clip on the surface to ensure that elements
        // in the surface do not render outside the surface.
        Rectangle clip = new Rectangle();
        clip.widthProperty().bind(surface.widthProperty());
        clip.heightProperty().bind(surface.heightProperty());
        surface.setClip(clip);

        return surface;
    }

    private VBox createLayout(Pane surface, HBox controls, Label timestampLabel) {
        VBox layout = new VBox(SPACING, controls, surface, timestampLabel);

        layout.setBackground(appBackground);
        layout.setPadding(new Insets(SPACING));

        VBox.setVgrow(surface, Priority.ALWAYS);

        return layout;
    }

    /**
     * Create controls which can control the movement of a circle.
     *
     * @param circle the circle which can be controlled
     * @return the created controls with handlers attached for circle movement control.
     */
    private HBox createControls(Circle circle) {
        up = new Button("Up");
        up.setOnAction(e -> moveVertically(circle, -MOVEMENT_DELTA));

        down = new Button("Down");
        down.setOnAction(e -> moveVertically(circle, MOVEMENT_DELTA));

        return new HBox(SPACING, up, down);
    }

    private void moveVertically(Circle circle, double delta) {
        double y = circle.getCenterY();

        // we only restrict movement in the up direction,
        // but allow unlimited movement in the down direction
        // (even if that movement would mean that the circle would extend totally
        // outside the current visible boundary of the surface).
        if ((y + delta) < 0) {
            return;
        }

        circle.setCenterY(y + delta);
    }

    /**
     * Adds standard keyboard handling logic to the UI.
     * 
     * Handlers are attached to the relevant scene whenever 
     * the scene containing the UI changes.
     *
     * @param layout the UI which will respond to keyboard input.
     */
    private void attachKeyboardHandlers(Pane layout) {
        EventHandler<KeyEvent> keyEventHandler = event -> {
            switch (event.getCode()) {
                case UP -> { up.requestFocus(); up.fire(); }
                case DOWN -> { down.requestFocus(); down.fire(); }
            }
        };

        layout.sceneProperty().addListener((observable, oldScene, newScene) -> {
            if (oldScene != null) {
                oldScene.removeEventFilter(
                        KeyEvent.KEY_PRESSED,
                        keyEventHandler
                );
            }

            if (newScene != null) {
                newScene.addEventFilter(
                        KeyEvent.KEY_PRESSED,
                        keyEventHandler
                );
            }
        });
    }

    private static Background createBackground(Color surfaceColor) {
        return new Background(new BackgroundFill(surfaceColor, null, null));
    }
}

【讨论】:

    【解决方案2】:

    您应该将时间戳显示为带有TextField (Doc) 的文本:

    TextField myText = new TextField();
    myText.setText("Time: " + formatter.format(ts));
    // set what you want to the TextField object: padding, size, color etc...
    p.getChildren().addAll(myText);
    

    【讨论】:

      【解决方案3】:

      那是因为ts 不是 Node 对象。如果你想添加它,你可以将它包含在 Label 这样的,或任何其他 Node 对象中,例如TextArea, TextField.

      //Create a HBox
      HBox hb = new HBox();
      hb.getChildren().addAll(btnUp, btnDown, p, new Label(formatter.format(ts).toString()));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多