我有一个基于javafx的桌面应用程序,唯一的要求是它必须连续运行5-6天。我处于测试阶段。
6个量表中的3个量表和折线图必须在几秒钟内更新一次。为此,我使用了一个线程,该线程每秒更新一次此组件。
我已经对该应用程序进行了近3次测试:
三天
26个小时(其中的图表工作正常,并且仪表中的值正在更新,但仪表针被卡在特定的值)
日志中没有异常,UI没有挂起,Just Ui组件没有响应。
我进行了性能分析,但是一切似乎都正常。我也阅读了此post,但在他的情况下,用户界面挂起了,对此我没有任何问题,所有按钮都是clicky,并且我可以更改屏幕没有问题。
重新加载屏幕后,所有屏幕恢复正常。
我用来更新组件的示例代码。
控制器
public class testGaugeController implements Initializable {
// Component
private static final int MAX_DATA_POINTS = 1000;
private int xSeriesData = 0;
private final XYChart.Series<Number, Number> series1 = new XYChart.Series<>();
private ExecutorService executor;
private final ConcurrentLinkedQueue<Number> dataQ1 = new ConcurrentLinkedQueue<>();
private NumberAxis xAxis,yAxis;
LineChart<Number, Number> lineChart;
DatabaseHandler dh = new DatabaseHandler();
Connection connect = dh.MakeConnection();
@FXML
private JFXDrawer drawer;
@FXML
private JFXHamburger burger;
@FXML
private Gauge Gauge;
/**
* Initializes the controller class.
*
* @param url
* @param rb
*/
public void initialize(URL url, ResourceBundle rb) throws IOException {
initializeRecorder();
start_recording();
}
private void initializeRecorder() throws IOException {
try {
xAxis = new NumberAxis(0, MAX_DATA_POINTS, MAX_DATA_POINTS / 100);
xAxis.setForceZeroInRange(false);
xAxis.setAutoRanging(true);
xAxis.setTickLabelsVisible(true);
xAxis.setTickMarkVisible(true);
xAxis.setMinorTickVisible(true);
yAxis = new NumberAxis();
// Create a LineChart
lineChart = new LineChart<Number, Number>(xAxis, yAxis) {
// Override to remove symbols on each data point
@Override
protected void dataItemAdded(XYChart.Series<Number, Number> series, int itemIndex, XYChart.Data<Number, Number> item) {
}
};
lineChart.setAnimated(false);
lineChart.setTitle("");
lineChart.setHorizontalGridLinesVisible(true);
series1.setName("Test Value");
lineChart.getData().addAll(series1);
drawer.setSidePane(lineChart);
drawer.setOverLayVisible(false);
} catch (Exception e) {
}
HamburgerBackArrowBasicTransition burgermove = new HamburgerBackArrowBasicTransition(burger);
burgermove.setRate(-1);
burger.addEventHandler(MouseEvent.MOUSE_PRESSED, (evt) -> {
burgermove.setRate(burgermove.getRate() * -1);
burgermove.play();
if (drawer.isShown()) {
drawer.close();
} else {
drawer.open();
}
});
}
int count_executer_status = 0;
boolean initial_start_trend = true;
private void start_recording() {
if (initial_start_trend) {
initial_start_trend = false;
} else {
xSeriesData = 0;
System.out.println("Clearing dataQue");
dataQ1.clear();
series1.getData().clear();
}
xAxis.setLowerBound(0);
count_executer_status++;
System.out.println("Cleared dataQue");
executor = Executors.newCachedThreadPool((Runnable r) -> {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
});
count_executer_status = 0;
AddToQueue addToQueue = new AddToQueue();
executor.execute(addToQueue);
//-- Prepare Timeline
prepareTimeline();
}
private class AddToQueue implements Runnable {
String query = "SELECT test_value FROM test_data_reader ORDER BY test_data_reader_id DESC LIMIT 1";
ResultSet rs;
@Override
public void run() {
try {
// add a item of random data to queue.
rs = dh.getData(query, connect);
if (rs.next()) {
double test_value = Double.parseDouble(rs.getString("test_value"));
dataQ1.add(test_value);
String Record_data = "INSERT INTO `test_data_record` (`test_value`, `date_time`) VALUES( '" + rs.getString("test_value") + "', NOW());";
dh.execute(Record_data, connect);
Platform.runLater(() -> {
Gauge.setValue(test_value);
});
}
xaxis_count++;
Thread.sleep(1000);
executor.execute(this);
} catch (Exception ex) {
}
}
}}
//-- Timeline gets called in the JavaFX Main thread
private void prepareTimeline() {
// Every frame to take any data from queue and add to chart
new AnimationTimer() {
@Override
public void handle(long now) {
addDataToSeries();
}
}.start();
}
int xaxis_count = 0;
private void addDataToSeries() {
try {
for (int i = 0; i < 20; i++) {
//-- add 20 numbers to the plot+
if (dataQ1.isEmpty()) {
break;
}
series1.getData().add(new XYChart.Data<>(xaxis_count, dataQ1.remove()));
}
if (series1.getData().size() > MAX_DATA_POINTS) {
series1.getData().remove(0, series1.getData().size() - MAX_DATA_POINTS);
}
// update
xAxis.setLowerBound(xSeriesData - MAX_DATA_POINTS);
xAxis.setUpperBound(xSeriesData - 1);
} catch (Exception e) {
}
}
FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import com.jfoenix.controls.JFXDrawer?>
<?import com.jfoenix.controls.JFXHamburger?>
<?import eu.hansolo.medusa.Gauge?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="e913_300mt.testGaugeController">
<children>
<VBox prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<HBox fx:id="sectionHeader" minHeight="-Infinity" prefHeight="50.0" prefWidth="600.0" style="-fx-background-color: #2F333E;">
<children>
<VBox alignment="CENTER" layoutX="10.0" layoutY="10.0" HBox.hgrow="ALWAYS" />
<VBox alignment="CENTER" HBox.hgrow="ALWAYS" />
<VBox alignment="CENTER" HBox.hgrow="ALWAYS" />
<VBox alignment="CENTER" HBox.hgrow="ALWAYS" />
<VBox alignment="CENTER" HBox.hgrow="ALWAYS">
<children>
<JFXHamburger fx:id="burger" />
</children>
</VBox>
</children>
</HBox>
<HBox prefHeight="100.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<children>
<Gauge fx:id="gauge" autoScale="false" borderPaint="#0099ff" borderWidth="3.0" decimals="0" foregroundPaint="#0000000b" highlightSections="true" innerShadowEnabled="true" knobType="METAL" lcdDesign="RED" lcdFont="LCD" majorTickMarkType="PILL" majorTickSpace="250.0" markersVisible="true" maxValue="3000.0" mediumTickMarkType="TRAPEZOID" mediumTickMarksVisible="false" minorTickSpace="50.0" needleSize="THIN" needleType="VARIOMETER" shadowsEnabled="true" threshold="300.0" title="Test Gauge" unit="unit" HBox.hgrow="ALWAYS">
<HBox.margin>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</HBox.margin>
</Gauge>
</children>
</HBox>
</children>
</VBox>
<JFXDrawer fx:id="drawer" defaultDrawerSize="600.0" direction="RIGHT" layoutY="56.0" prefHeight="344.0" prefWidth="600.0" />
</children>
</AnchorPane>
图书馆
出于测试目的,我仅更新一个仪表。系统配置为:
对此有任何想法。