几周前,我使用NetBeans创建了一个JavaFX示例项目——webview project,并且它可以正常工作。我特别想使用JavaFX在swinginterop应用程序中播放YouTube视频。这是一个更大项目的一部分,因此我使用了NetBeans中的SwingInterop示例,在JFrame上加载播放器。我需要加载多个YouTube视频。一切都很顺利。我正在使用Windows XP、NetBeans 7.2和Java 1.7 9。但是这几天我再次尝试打开应用程序,但是在YouTube上看到"This Video is currently unavailable"。我首先想到的是可能我没有安装最新版本的FlashPlayer......不用说我下载了所有东西......但是应用程序仍然无法播放YouTube视频。我甚至重新安装了Java和NetBeans,但什么也没变。值得一提的是,在我的电脑上安装了Firefox浏览器,YouTube可以正常工作。我知道这很烦人,因为之前一切都好,现在却出了问题。所以现在,我可以在JavaFX Webview中看到网页,但是YouTube视频仍然无法播放。
上次我请求帮助时没有放代码......对此我很抱歉。因此,我又做了一个只有两个类的小项目来展示我做了什么。我没有在其他计算机上测试过这个项目,因为如果它发生了一次,那么它很可能会再次发生。因为事情不会自己解决,我希望能够回答这个问题。感谢jewelsea和Gregory的关注。
以下是代码:
上次我请求帮助时没有放代码......对此我很抱歉。因此,我又做了一个只有两个类的小项目来展示我做了什么。我没有在其他计算机上测试过这个项目,因为如果它发生了一次,那么它很可能会再次发生。因为事情不会自己解决,我希望能够回答这个问题。感谢jewelsea和Gregory的关注。
以下是代码:
package stackoverflow;
import java.awt.Dimension;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
public class PlayersFrame extends JFrame
{
public PlayersFrame()
{
// initialize jframe
setLayout(null);
setTitle(" YouTube on JFrame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
CreatePlayersList();
}
// all the players have the same size
Dimension PlayerSize = new Dimension(300, 230);
private void CreatePlayersList()
{
/*
* create an instance of playerclass
* containing the location and the youtube embedded address
* for each of the four players
*/
Point NewPlayerLocation = null;
PlayerClass NewPlayer = null;
NewPlayerLocation = new Point(10, 10);
NewPlayer = new PlayerClass(NewPlayerLocation, PlayerSize, "http://www.youtube.com/embed/SvcDwPlaWgw?rel=0");
// add player1 class to the players list
Players.add(NewPlayer);
NewPlayerLocation = new Point(320, 10);
NewPlayer = new PlayerClass(NewPlayerLocation, PlayerSize, "http://www.youtube.com/embed/L0huXvTeVvU?rel=0");
// add player2 class to the players list
Players.add(NewPlayer);
NewPlayerLocation = new Point(10, 240);
NewPlayer = new PlayerClass(NewPlayerLocation, PlayerSize, "http://www.youtube.com/embed/rHcnsEoSK_c?rel=0");
// add player3 class to the players list
Players.add(NewPlayer);
NewPlayerLocation = new Point(320, 240);
NewPlayer = new PlayerClass(NewPlayerLocation, PlayerSize, "http://www.youtube.com/embed/vaXuK-RsT6E?rel=0");
// add player4 class to the players list
Players.add(NewPlayer);
// stand by
LoadPlayers();
}
// list of players data
List<PlayerClass> Players = new ArrayList<>();
/*
* a class to hold data about a player
*/
public class PlayerClass
{
public PlayerClass(Point playerLocation, Dimension playerSize, String youTubeAddress)
{
PlayerLocation = playerLocation;
PlayerSize = playerSize;
YouTubeAddress = youTubeAddress;
}
public Point PlayerLocation = null;
public Dimension PlayerSize = null;
public String YouTubeAddress = null;
}
/*
* in this swinginterop project i want to display youtube videos on a jframe
* with webview i get more that i ask for
* webview will display an entire web page
* so a web page is created on the fly containing a frame for the player
*/
private String GeneratePlayerPage(Dimension PlayerSize, String EmbeddedAddress)
{
String GeneratedPage = null;
GeneratedPage = "<html>\n";
GeneratedPage += "<body>\n";
GeneratedPage += "<iframe\n";
GeneratedPage += "style=\"position:absolute;\n";
GeneratedPage += "left:0px;top:0px;" +
"width:" + String.valueOf(PlayerSize.width) +
"px;height:" + String.valueOf(PlayerSize.height) + "px;\"\n";
GeneratedPage += "src=\"" + EmbeddedAddress + "\"" + "\n";
GeneratedPage += "frameborder=\"0\" allowfullscreen>\n";
GeneratedPage += "</iframe>\n";
GeneratedPage += "</body>\n";
GeneratedPage += "</html>";
return(GeneratedPage);
}
/*
* why synchronized ? ...
*
* each javafx object runs on it's own thread
* this means that, sooner or later
* you will have to deal with crossthreading issues
*
* in this project it does not throw an error
* but since the playersform will add controls on a locked procedure,
* and i don't use a single player on the jframe,
* some of the players will not appear on the frame.
*
* if only one player is loaded on the jframe
* then all this is not necessary.
*
* i don't know if the players are there but are not rendered
* or the players were just not loaded
*
* with this synchronized void a callback from the javafx object is handled
*/
public synchronized void OkPlayer()
{
try
{
/*
* a player was loaded
* delay before the next player
*/
Thread.sleep(10);
}
catch(Exception Ex)
{}
/*
* if the players list is empty than all the players have been loaded
* but you also get an error, so check the size ...
*/
if(Players.size() > 0)
{
LoadPlayers();
}
}
void LoadPlayers()
{
/*
* get the data from the first playerclass in the players list
* and create a new player
*/
PlayerClass TempPlayer = Players.get(0);
Dimension playerSize = TempPlayer.PlayerSize;
YouTubePlayer player = new YouTubePlayer(this, playerSize,
GeneratePlayerPage(playerSize, TempPlayer.YouTubeAddress));
add(player);
player.setLocation(TempPlayer.PlayerLocation);
player.setSize(TempPlayer.PlayerSize);
player.setVisible(true);
// remove the used playerclass from the players list
Players.remove(0);
}
}
并且玩家
package stackoverflow;
import java.awt.Dimension;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UnsupportedLookAndFeelException;
public final class YouTubePlayer extends JPanel
{
public YouTubePlayer(PlayersFrame playersFrame, Dimension PlayerSize, String YouTubeAddress)
{
remote = playersFrame;
init(PlayerSize, YouTubeAddress);
}
private static JFXPanel browserFxPanel;
private Pane browser;
public void init(Dimension playerSize, String youTubeAddress)
{
final Dimension PlayerSize = playerSize;
final String YouTubeAddress = youTubeAddress;
browserFxPanel = new JFXPanel();
browserFxPanel.setPreferredSize(new Dimension(PlayerSize.width, PlayerSize.height));
add(browserFxPanel);
Platform.runLater(new Runnable()
{
public void run()
{
// inside the player's thread
createScene(PlayerSize, YouTubeAddress);
}
});
}
/*
* the program will start on the javafx thread
* the main void is placed in the javafx component
*
* maybe there are other ways to launch the program
* but for this one it is good enough ... for now
*/
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
{
// set windows look and feel
if ("Windows".equals(info.getName()))
{
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException Ex)//ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex)
{}
// create an instance of playersframe
PlayersFrame LoadPlayers = new PlayersFrame();
LoadPlayers.setSize(new Dimension(640, 520));
// make it visible
LoadPlayers.setVisible(true);
}
});
}
PlayersFrame remote = null;
private void createScene(Dimension PlayerSize, String YouTubeAddress)
{
browser = createBrowser(PlayerSize, YouTubeAddress);
browserFxPanel.setScene(new Scene(browser));
/*
* player loaded
* let playersform know that it can proceed
* with the next player, if there still is one
*/
remote.OkPlayer();
}
private Pane createBrowser(Dimension PlayerSize, String YouTubeAddress)
{
WebView view = new WebView();
view.setPrefSize(PlayerSize.width, PlayerSize.height);
final WebEngine eng = view.getEngine();
eng.loadContent(YouTubeAddress);
GridPane grid = new GridPane();
grid.getChildren().addAll(view);
return grid;
}
}
这就是它的样子
http://i.stack.imgur.com/UvhcJ.jpg
这就是“那个东西”
http://i.stack.imgur.com/lB4uY.jpg
最后一个玩家的操作与其他玩家相同
如果我使用NetBeans中的示例并粘贴YouTube链接,
我会得到相同的结果
我真的需要知道正在发生什么
谢谢