本文目录导读:

Java在大屏展示领域通常作为后端服务提供数据接口,前端则使用Vue/React+ECharts等技术,但如果你需要纯Java技术栈(如JavaFX、Swing)或结合Web技术实现大屏,以下提供几个完整案例思路和代码模板:
基于JavaFX的桌面大屏案例
项目结构
bigscreen-demo/
├── src/main/java/com/example/bigscreen/
│ ├── BigScreenApp.java # 主入口
│ ├── controller/
│ │ └── DashboardController.java
│ ├── service/
│ │ └── DataService.java # 模拟数据服务
│ └── util/
│ └── ChartUtil.java # 图表工具类
└── resources/
├── css/dashboard.css # 大屏样式
└── fxml/dashboard.fxml # 布局文件
完整代码示例
BigScreenApp.java
package com.example.bigscreen;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.Screen;
public class BigScreenApp extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/dashboard.fxml"));
Parent root = loader.load();
// 设置全屏显示
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("数据可视化大屏");
primaryStage.setFullScreen(true); // 切换全屏
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
dashboard.fxml(布局布局)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.chart.*?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="com.example.bigscreen.controller.DashboardController"
styleClass="dashboard-root">
<!-- 顶部标题栏 -->
<top>
<VBox styleClass="header" alignment="CENTER">
<Label text="智慧运营数据大屏" styleClass="title"/>
<Label fx:id="timeLabel" styleClass="subtitle"/>
</VBox>
</top>
<!-- 中间内容区 -->
<center>
<GridPane hgap="10" vgap="10" styleClass="content-grid">
<!-- 第一列:关键指标 -->
<VBox styleClass="panel" GridPane.columnIndex="0" GridPane.rowIndex="0">
<Label text="核心指标" styleClass="panel-title"/>
<HBox spacing="20">
<VBox alignment="CENTER">
<Label text="总销售额" styleClass="metric-label"/>
<Label fx:id="salesValue" text="0" styleClass="metric-value"/>
</VBox>
<VBox alignment="CENTER">
<Label text="用户数量" styleClass="metric-label"/>
<Label fx:id="userValue" text="0" styleClass="metric-value"/>
</VBox>
</HBox>
</VBox>
<!-- 第二列:实时图表 -->
<VBox styleClass="panel" GridPane.columnIndex="1" GridPane.rowIndex="0">
<Label text="销售趋势" styleClass="panel-title"/>
<LineChart fx:id="salesChart" prefWidth="600" prefHeight="300"/>
</VBox>
<!-- 第三列:饼图 -->
<VBox styleClass="panel" GridPane.columnIndex="2" GridPane.rowIndex="0">
<Label text="品类占比" styleClass="panel-title"/>
<PieChart fx:id="categoryPie" prefWidth="400" prefHeight="300"/>
</VBox>
</GridPane>
</center>
</BorderPane>
DashboardController.java
package com.example.bigscreen.controller;
import com.example.bigscreen.service.DataService;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.chart.*;
import javafx.scene.control.Label;
import javafx.util.Duration;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.ResourceBundle;
public class DashboardController implements Initializable {
@FXML private Label timeLabel;
@FXML private Label salesValue;
@FXML private Label userValue;
@FXML private LineChart<String, Number> salesChart;
@FXML private PieChart categoryPie;
private DataService dataService = new DataService();
private XYChart.Series<String, Number> trendSeries;
@Override
public void initialize(URL location, ResourceBundle resources) {
initChart();
startTimer();
}
private void initChart() {
// 初始化折线图
trendSeries = new XYChart.Series<>();
trendSeries.setName("销售额");
salesChart.getData().add(trendSeries);
salesChart.setCreateSymbols(false);
salesChart.setAnimated(true);
// 初始化饼图
updatePieChart();
}
private void startTimer() {
Timeline timeline = new Timeline(
new KeyFrame(Duration.seconds(2), e -> updateData())
);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
private void updateData() {
// 更新时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
timeLabel.setText(sdf.format(new Date()));
// 更新指标数据
Map<String, Number> metrics = dataService.getCoreMetrics();
salesValue.setText(String.format("¥%,.0f", metrics.get("sales").doubleValue()));
userValue.setText(String.valueOf(metrics.get("users").intValue()));
// 更新折线图
updateLineChart();
}
private void updateLineChart() {
// 添加新数据点(模拟实时流)
trendSeries.getData().add(
new XYChart.Data<>(getCurrentTime(), dataService.getRandomSales())
);
// 只保留最近20个点
if (trendSeries.getData().size() > 20) {
trendSeries.getData().remove(0);
}
}
private void updatePieChart() {
Map<String, Double> categoryData = dataService.getCategoryData();
categoryPie.getData().clear();
categoryData.forEach((name, value) -> {
PieChart.Data slice = new PieChart.Data(name, value);
categoryPie.getData().add(slice);
});
categoryPie.setLegendVisible(true);
}
private String getCurrentTime() {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
return sdf.format(new Date());
}
}
DataService.java(模拟数据)
package com.example.bigscreen.service;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class DataService {
private Random random = new Random();
private double baseSales = 500000;
private int baseUsers = 12000;
public Map<String, Number> getCoreMetrics() {
Map<String, Number> metrics = new HashMap<>();
metrics.put("sales", baseSales + random.nextInt(100000));
metrics.put("users", baseUsers + random.nextInt(5000));
return metrics;
}
public double getRandomSales() {
return 300 + random.nextDouble() * 200;
}
public Map<String, Double> getCategoryData() {
Map<String, Double> data = new HashMap<>();
data.put("电子产品", 35.5);
data.put("服装鞋帽", 28.3);
data.put("日用品", 22.7);
data.put("其他", 13.5);
return data;
}
}
dashboard.css(样式)
.dashboard-root {
-fx-background-color: #0f1923;
-fx-font-family: "Microsoft YaHei";
}
.header {
-fx-padding: 20px 0;
-fx-background-color: linear-gradient(to bottom, #1e3c72, #2a5298);
}
{
-fx-font-size: 36px;
-fx-text-fill: white;
-fx-font-weight: bold;
-fx-effect: dropshadow(gaussian, #00ffff, 10, 0.5, 0, 0);
}
{
-fx-font-size: 16px;
-fx-text-fill: #7ec8e3;
-fx-padding: 5px 0;
}
.content-grid {
-fx-padding: 20px;
-fx-hgap: 20px;
-fx-vgap: 20px;
}
.panel {
-fx-background-color: rgba(255, 255, 255, 0.05);
-fx-background-radius: 10px;
-fx-padding: 15px;
-fx-border-color: rgba(0, 255, 255, 0.2);
-fx-border-radius: 10px;
}
.panel-title {
-fx-font-size: 18px;
-fx-text-fill: #00ffff;
-fx-padding: 0 0 10px 0;
-fx-border-width: 0 0 1px 0;
-fx-border-color: rgba(0, 255, 255, 0.3);
}
.metric-label {
-fx-font-size: 14px;
-fx-text-fill: #a0a0a0;
}
.metric-value {
-fx-font-size: 28px;
-fx-text-fill: #00ff88;
-fx-font-weight: bold;
}
/* 图表样式覆盖 */
.chart {
-fx-background-color: transparent;
}
.chart-plot-background {
-fx-background-color: transparent;
}
.chart-vertical-grid-lines {
-fx-stroke: rgba(0, 255, 255, 0.1);
}
.chart-horizontal-grid-lines {
-fx-stroke: rgba(0, 255, 255, 0.1);
}
.chart-line-symbol {
-fx-background-color: #00ffff, white;
}
.chart-legend {
-fx-background-color: rgba(0, 255, 255, 0.1);
-fx-border-color: rgba(0, 255, 255, 0.3);
}
基于Java Web的Spring Boot大屏后端
如果你需要为大屏前端提供数据接口,这是一个标准的后端接口案例:
package com.example.bigscreen.controller;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@RestController
@RequestMapping("/api/bigscreen")
public class ScreenDataController {
private final Map<String, Object> dataCache = new ConcurrentHashMap<>();
// 模拟实时数据接口
@GetMapping("/realtime")
public Map<String, Object> getRealTimeData() {
Map<String, Object> result = new HashMap<>();
result.put("timestamp", System.currentTimeMillis());
result.put("traffic", new Random().nextInt(5000));
result.put("orders", new Random().nextInt(800));
result.put("revenue", Math.round(10000 + Math.random() * 90000));
result.put("activeUsers", new Random().nextInt(1200));
return result;
}
// 获取趋势数据
@GetMapping("/trend")
public List<Map<String, Object>> getTrendData(@RequestParam(defaultValue = "24") int hours) {
List<Map<String, Object>> trendList = new ArrayList<>();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
for (int i = hours; i > 0; i--) {
Map<String, Object> point = new HashMap<>();
point.put("time", sdf.format(new Date(System.currentTimeMillis() - i * 3600000)));
point.put("value", 50 + Math.random() * 100);
trendList.add(point);
}
return trendList;
}
}
运行与部署建议
JavaFX运行命令
# 编译 mvn clean javafx:compile # 运行 mvn javafx:run
大屏设计要点
- 分辨率适配:支持1920×1080/4096×2160等多种大屏
- 数据刷新频率:2-5秒定时轮询后端接口
- 视觉风格:深色科技感背景 + 高亮数据色
- 性能优化:使用WebSocket推送替代轮询
如果需要更复杂的大屏(3D/地图/视频流),建议采用Java后端 + Web前端方案(如Vue+ECharts),Java专注提供高性能数据接口。