有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

javafx如何打印当前CPU使用情况并在Java场景生成器(FXML)中进行更新

我试图在scene builder(FXML)中构建一个CPU监视器工具,但我无法让它更新FXML标签中的CPU使用情况。我可以让它在一开始就打印出cpu使用率,但仅此而已。到目前为止,我已经做到了

java文件

package cpumonitorfxml;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.util.Duration;


public class CPUMonitorFXML extends Application {

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    FXMLDocumentController start = new FXMLDocumentController();
     Timeline timeline = new Timeline(new KeyFrame(Duration.millis(100), (ActionEvent) -> {
        double cpu = FXMLDocumentController.getCPUUsage();
        System.out.println("CPU: " + cpu); 


    }));
    timeline.setCycleCount(100);
    timeline.play();


    Scene scene = new Scene(root);

    stage.setScene(scene);
    stage.show();
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

}

FXMLDocument

    <?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="301.0" prefWidth="206.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="cpumonitorfxml.FXMLDocumentController">
    <children>
        <Button fx:id="button" layoutX="34.0" layoutY="229.0" onAction="#handleButtonAction" prefHeight="25.0" prefWidth="69.0" text="Click Me!" />
        <Label fx:id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" />
      <ImageView fitHeight="150.0" fitWidth="200.0" layoutX="28.0" layoutY="28.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@gauge.png" />
         </image>
      </ImageView>
    </children>
</AnchorPane>

和FXMLDocumentController

package cpumonitorfxml;


import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.util.Duration;


public class FXMLDocumentController implements Initializable {


    private Timeline timeline;
    private KeyFrame keyFrame;
    private final double tickTimeInSeconds = 0.01;
    private double secondsElapsed = 0.0;
    private final double angleDeltaPerSeconds = 6.0;


    @FXML
    private Label label;

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        label.setText("Hello World!");
    }


    public void FXMLDocumentController(){
        timeline.play();
        setupTimer();
    }




       public static double getCPUUsage() {
        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
        double value = 0;
        for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
            method.setAccessible(true);
            if (method.getName().startsWith("getSystemCpuLoad")
                    && Modifier.isPublic(method.getModifiers())) {
                try {
                    value = (double) method.invoke(operatingSystemMXBean);
                } catch (Exception e) {
                    value = 0;
                }
                return value;
            }
        }
        return value;
    }


    public void setupTimer(){
        if(isRunning()){
            timeline.stop();
        }

        keyFrame = new KeyFrame(Duration.millis(tickTimeInSeconds * 1000), 
                (ActionEvent actionEvent) -> {
                    update();
        });

        timeline = new Timeline(keyFrame);
        timeline.setCycleCount(Animation.INDEFINITE);
    }


        private void update(){
        secondsElapsed += tickTimeInSeconds;

        String str = Double.toString(getCPUUsage());
        label.setText(str);
    }


        public boolean isRunning(){
        if(timeline != null){
            if(timeline.getStatus() == Animation.Status.RUNNING){
                return true;
            }
        }
        return false;
    }



    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    

}

我知道这很艰难,我对FXML还很陌生。显然还有很多工作要做,但我要克服的主要障碍是制定时间表(?)这将更新cpu使用率作为标签。我在JavaFX中创建了一个非常类似的程序,使用起来轻松多了


共 (1) 个答案

  1. # 1 楼答案

    我认为您试图使用Main而不是Controller来处理代码,这是在制造混乱

    Main

    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    
    /**
     *
     * @author Sedrick
     */
    public class JavaFXApplication74 extends Application {
    
        @Override
        public void start(Stage stage) throws Exception {
            Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    
            Scene scene = new Scene(root);
    
            stage.setScene(scene);
            stage.show();
        }
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    
    }
    

    Controller

    import java.lang.management.ManagementFactory;
    import java.lang.management.OperatingSystemMXBean;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.animation.KeyFrame;
    import javafx.animation.Timeline;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Label;
    import javafx.util.Duration;
    
    /**
     *
     * @author Sedrick
     */
    public class FXMLDocumentController implements Initializable {
    
        @FXML
        private Label label;
    
        Timeline timeline;
        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
    
        @FXML
        private void handleButtonAction(ActionEvent event) {
            switch(timeline.getStatus())
            {
                case PAUSED:
                case STOPPED:
                    timeline.play();
                    break;
                case RUNNING:
                    timeline.pause();
                    break;
            }
        }
    
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            // TODO
            timeline = new Timeline(new KeyFrame(Duration.seconds(1), (ActionEvent event) -> {            
                label.setText(getCPUUsage().toString());
            }));
            timeline.setCycleCount(Timeline.INDEFINITE);
        }    
    
        public Double getCPUUsage() {
    
            double value = 0;
            for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
                method.setAccessible(true);
                if (method.getName().startsWith("getSystemCpuLoad")
                        && Modifier.isPublic(method.getModifiers())) {
                    try {
                         return (double) method.invoke(operatingSystemMXBean);
                    } catch (Exception e) {
                        value = 0;
                    }
                }
            }
            return value;
        }
    }
    

    FXML

    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    
    <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication74.FXMLDocumentController">
        <children>
            <Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
            <Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
        </children>
    </AnchorPane>