IT小猫咪 2024-06-27 20:19 采纳率: 0%
浏览 5

Java窗口全屏模式无法使用 JavaFX 实现

1:全屏窗口无法退出
2:全屏模式不同步播放视频 选择文件也有问题


package com.example.window;

import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;

public class ManualWindowSwitching extends Application {
    private JFrame frame;
    private JFXPanel fxPanel;
    private MediaPlayer mediaPlayer;
    private Button playButton;
    private boolean isFullScreen = false;

    @Override
    public void start(Stage primaryStage) {
        frame = new JFrame("手动窗口切换");
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        // 设置内容面板背景为黑色
        JPanel panel = new JPanel();
        panel.setBackground(new java.awt.Color(0, 0, 0));
        frame.getContentPane().add(panel, BorderLayout.CENTER);

        // 添加 JavaFX 面板
        fxPanel = new JFXPanel();
        frame.getContentPane().add(fxPanel, BorderLayout.CENTER);

        // 初始化 JavaFX 环境,加载媒体播放器
        Platform.runLater(() -> initFX(primaryStage));

        frame.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    toggleFullScreen(primaryStage);
                }
            }
        });
    }

    private void initFX(Stage primaryStage) {
        // 创建 StackPane 作为场景的根节点
        StackPane root = new StackPane();
        root.setAlignment(Pos.CENTER);
        Scene scene = new Scene(root, Color.BLACK);

        fxPanel.setScene(scene);

        // 创建圆形的播放按钮,去除字体
        playButton = new Button();
        playButton.setStyle("-fx-background-radius: 50%; -fx-background-color: #4CAF50;");
        playButton.setPrefSize(50, 50);
        playButton.setVisible(false);

        // 添加文件选择按钮,并设置中文文本
        JButton chooseFileButton = new JButton("选择文件");
        chooseFileButton.addActionListener(e -> {
            Platform.runLater(() -> {
                FileChooser fileChooser = new FileChooser();
                fileChooser.setTitle("选择媒体文件");
                File file = fileChooser.showOpenDialog(null);
                if (file!= null) {
                    playMedia(file, primaryStage);
                }
            });
        });

        // 将按钮添加到窗口中间(居中位置)
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        buttonPanel.add(chooseFileButton);
        frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);

        // 显示窗口
        frame.setVisible(true);
    }

    private void playMedia(File file, Stage primaryStage) {
        // 创建 Media 和 MediaPlayer
        Media media = new Media(file.toURI().toString());
        mediaPlayer = new MediaPlayer(media);

        // 创建 MediaView 并添加到 StackPane 中
        MediaView mediaView = new MediaView(mediaPlayer);
        StackPane root = (StackPane) fxPanel.getScene().getRoot();
        root.getChildren().clear();
        root.getChildren().add(mediaView);

        // 设置 MediaView 的适应和保持比例
        mediaView.fitWidthProperty().bind(root.widthProperty());
        mediaView.fitHeightProperty().bind(root.heightProperty());
        mediaView.setPreserveRatio(false);

        // 创建一个新的 StackPane 来放置播放按钮
        StackPane buttonPane = new StackPane();
        buttonPane.setAlignment(Pos.CENTER);
        buttonPane.getChildren().add(playButton);
        root.getChildren().add(buttonPane);

        // 播放和暂停按钮
        playButton.setOnAction(e -> {
            if (mediaPlayer.getStatus() == MediaPlayer.Status.PLAYING) {
                mediaPlayer.pause();
                updateButtonToPause();
            } else {
                mediaPlayer.play();
                updateButtonToPlay();
            }
            playButton.setVisible(false); // 点击按钮后再次隐藏
        });

        // 添加屏幕点击事件
        root.setOnMouseClicked(e -> {
            if (e.getClickCount() == 2) {
                toggleFullScreen(primaryStage);
            } else {
                if (playButton.isVisible()) {
                    playButton.setVisible(false);
                } else {
                    playButton.setVisible(true);
                }
            }
        });

        // 添加按钮点击动画效果
        playButton.setOnMouseEntered(e -> {
            FadeTransition fadeTransition = new FadeTransition(Duration.millis(200), playButton);
            fadeTransition.setFromValue(1.0);
            fadeTransition.setToValue(0.7);
            fadeTransition.play();
        });

        playButton.setOnMouseExited(e -> {
            FadeTransition fadeTransition = new FadeTransition(Duration.millis(200), playButton);
            fadeTransition.setFromValue(0.7);
            fadeTransition.setToValue(1.0);
            fadeTransition.play();
        });

        mediaPlayer.play();
    }

    private void updateButtonToPlay() {
        Polygon triangle = new Polygon();
        triangle.getPoints().addAll(
                40.0, 25.0,
                10.0, 25.0,
                25.0, 5.0
        );
        triangle.setFill(Color.WHITE);
        playButton.setGraphic(triangle);
    }

    private void updateButtonToPause() {
        Polygon equalSign = new Polygon();
        equalSign.getPoints().addAll(
                10.0, 10.0,
                40.0, 10.0,
                40.0, 40.0,
                10.0, 40.0
        );
        equalSign.setFill(Color.WHITE);
        playButton.setGraphic(equalSign);
    }

    private void toggleFullScreen(Stage primaryStage) {
        if (isFullScreen) {
            frame.dispose();
            frame.setUndecorated(false);
            frame.setExtendedState(JFrame.NORMAL);
            frame.setVisible(true);
        } else {
            frame.dispose();
            frame.setUndecorated(true);
            frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            frame.setVisible(true);
        }
        isFullScreen =!isFullScreen;
    }

    public static void main(String[] args) {
        launch(args);
    }
}
  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-06-27 20:19
    关注

    引自免费微信小程序:皆我百晓生

    关于你的问题,我有以下解决方案和建议:

    首先,全屏窗口无法退出的问题。你需要设置一个键盘事件以退出全屏模式。这可以通过添加一个全局监听器来实现,当用户按下某个特定的键(例如ESC键)时退出全屏模式。在JavaFX中,可以使用 setOnKeyPressed 方法来处理键盘事件。你可以将以下代码添加到你的 start 方法中:

    primaryStage.setOnKeyPressed(event -> {
        if (event.getCode().equals(KeyCode.ESCAPE)) {
            toggleFullScreen(primaryStage); // Use the method you have for toggling full screen
        }
    });
    

    其次,关于全屏模式下不同步播放视频和选择文件的问题。我认为这可能和你的文件选择逻辑和全屏模式下的窗口尺寸调整有关。当你进入全屏模式时,你的程序尝试用MediaView占据整个窗口空间,并且可能没有正确管理文件选择的显示。全屏模式改变了应用程序的窗口大小,可能需要额外的逻辑来处理这种情况。你可能需要调整你的全屏逻辑以适应全屏模式下的视频播放和文件选择。这可能需要重新设计你的UI布局以适应全屏模式。例如,你可能需要在全屏模式下使用不同的布局管理器或者改变你的UI元素的大小和位置。此外,确保你的视频文件路径是正确的,并且视频文件是可以访问的。你可能需要添加一些错误处理代码来处理文件无法找到或无法播放的情况。我建议你可以试着在你的代码中增加这些错误处理逻辑,以更好地诊断问题。对于不同步播放视频的问题,你需要检查你的视频源是否有问题或者视频的编码格式是否与你的播放器兼容。如果你在处理多媒体播放方面遇到问题,你可以尝试使用其他的库或框架如JavaCV或VLCJ来替代JavaFX的MediaPlayer。至于选择文件的问题,你可以在切换到全屏模式时添加一个弹出窗口来选择文件,或者提供一个固定大小的区域让用户选择文件,同时保留足够的空间用于视频播放。同时检查JavaFX库和JDK版本是否匹配并更新到最新版本,以消除可能的兼容性问题。希望这些建议能帮助你解决问题!

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月27日

悬赏问题

  • ¥15 求解答一下是否可以修改一个软件运行时生成的文件内部内置的文件创建时间?
  • ¥15 求在R环境下用corrplot画一个相关图
  • ¥20 WIN10蓝屏问题!
  • ¥15 Mac经常自动关机,再次打开后提示“电脑因出现问题而重新启动”
  • ¥60 使用ovito软件怎么得到金属玻璃的自由体积
  • ¥15 急!如何实现根据汇编指令推测硬件功能?
  • ¥20 excel处理10000万条数据方法
  • ¥15 hc32串口接收数据
  • ¥15 阻抗控制阻尼参数过小报错
  • ¥15 在Unity开发环境中用NPOI插件输出Word文档可以,当我打包到Windows系统软件的时候输出Word文档就出现文件损坏