我想使用JavaFX创建带有类似于Firefox配置面板的图标的选项卡面板:

有没有我可以用来看看如何实现这个的例子?
我有一个在FXML中设置如下的MenuBar:
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="true" text="_File">
<items>
<MenuItem mnemonicParsing="true" text="_New Project"/>
<MenuItem mnemonicParsing="true" text="_Open…"/>
<MenuItem mnemonicParsing="false" text="Quit"/>
</items>
</Menu>
</menus>
</MenuBar>
Run Code Online (Sandbox Code Playgroud)
这会产生如下菜单:

我用以下CSS 成功设置MenuBar了Menu 文件和文件的样式:
.menu-bar { /* The menu bar itself */ }
.menu { /* The File menu item */ }
.menu:showing { /* menu when it's being shown (activated) */ }
.menu .label { /* Styles the text on a menu item */ }
.menu:showing .label { /* Styles the …Run Code Online (Sandbox Code Playgroud) 在javaFX中调整画布大小没有这样的方法,唯一的解决方案是从Canvas扩展.
class ResizableCanvas extends Canvas {
public ResizableCanvas() {
// Redraw canvas when size changes.
widthProperty().addListener(evt -> draw());
heightProperty().addListener(evt -> draw());
}
private void draw() {
double width = getWidth();
double height = getHeight();
GraphicsContext gc = getGraphicsContext2D();
gc.clearRect(0, 0, width, height);
}
@Override
public boolean isResizable() {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
从Canvas扩展是唯一使画布Resizable的解决方案?因为这个解决方案只有在我们不想使用FXML时才有效,如果我们在fxml中声明一个画布,我们怎样才能使它可以调整大小?
这是我的代码:
package sample;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Main extends Application {
Controller controller;
@Override
public …Run Code Online (Sandbox Code Playgroud) 我写了一个基本的控件和它的皮肤.A label显示在HBox皮肤中.如果空间不足,此标签应包装其文本.
public class LabelWrap extends Application {
public static void main(String[] args) {
launch(LabelWrap.class);
}
@Override
public void start(Stage stage) throws Exception {
BasicControl basicControl = new BasicControl();
BorderPane borderPane = new BorderPane();
borderPane.setPrefWidth(150);
borderPane.setCenter(basicControl);
stage.setScene(new Scene(borderPane));
stage.centerOnScreen();
stage.show();
}
private static class BasicControl extends Control {
@Override
protected Skin<?> createDefaultSkin() {
return new BasicControlSkin(this);
}
}
private static class BasicControlSkin extends SkinBase<BasicControl> {
protected BasicControlSkin(BasicControl control) {
super(control);
VBox box = new VBox();
Label label …Run Code Online (Sandbox Code Playgroud) 有一个超链接.单击时,我想要在外部浏览器中打开一个链接.
网上引用的常用方法似乎是:
final Hyperlink hyperlink = new Hyperlink("http://www.google.com");
hyperlink.setOnAction(t -> {
application.getHostServices().showDocument(hyperlink.getText());
});
Run Code Online (Sandbox Code Playgroud)
但是我没有参考Application.所述链路是从对话,这是从一个控制器,其经由FXML文件打开打开打开,从而获得到应用程序对象的引用将是相当痛苦.
有谁知道这样做的简单方法?
干杯
我应该使用BorderPane布局并在底部添加标签吗?
有没有更好的办法?
我制作了一个小型演示来举例说明我遇到的问题.关于其使用的演练:
1 - 单击屏幕四次以创建网格.
2 - 单击底部的按钮,为创建的网格提供透视效果.
3 - 再次单击屏幕以绘制圆圈.
我的问题是我不知道我应该在Circle节点上应用什么转换,以便在用户点击的确切位置获得与网格相同的视觉效果.
此时的演示只绘制一个没有变换的圆.
所需的输出如下(我在这里使用Ellipse而不是Circle作弊 - 这不是我的解决方案,因为用户输入了网格的四个坐标):
这是演示的代码.
Main.java
package application;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("View.fxml"));
Scene scene = new Scene(loader.load(), 600, 600);
primaryStage.setScene(scene);
primaryStage.setTitle("Perspective Transformation");
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
View.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import …Run Code Online (Sandbox Code Playgroud) 当加载新的FXML并设置BorderPane的中心时,应用程序会短暂"冻结",无论是来自时间轴还是来自图像视图中的gif,现有动画都将停止.我正在使用此代码更改centerView:
@FXML
public void handleChangeView(ActionEvent event) {
Task<Parent> loadTask = new Task<>() {
@Override
public Parent call() throws IOException {
String changeButtonID = ((ToggleButton) event.getSource()).getId();
Parent newOne = getFxmls().get(changeButtonID);
if (newOne == null) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/" + changeButtonID + ".fxml"));
newOne = loader.load();
getFxmls().put(changeButtonID, newOne);
}
return newOne ;
}
};
loadTask.setOnSucceeded(e -> {
getMainUI().setCenter(loadTask.getValue());
});
loadTask.setOnFailed(e -> loadTask.getException().printStackTrace());
Thread thread = new Thread(loadTask);
thread.start();
}
Run Code Online (Sandbox Code Playgroud)
虽然这确保了在加载时保持UI响应的工作,但是当中心舞台第一次显示时,存在明显的滞后.查看CPU配置文件:
我不确定延迟是来自初始化函数运行还是加载元素.这是程序的GIF,你可以看到可见的延迟:
通过在VLC中加载并逐帧进行,延迟在30 fps视频中看起来是5或6帧,这意味着大约200ms的延迟意味着动画冻结超过50ms左右的初始化方法.(也许整个加载方法会冻结动画?)
问题是,在这期间可以保持动画流畅吗?
//*********EDIT**********//
所以我经历了这个项目并尽可能多地删除了一些方法和类,将整个游戏减少到了6个最小的类.我仍然有按下字符按钮('你'按钮)的延迟.有了这样一个极小的例子,我迷失了可能是错的.我已将此上传到谷歌驱动器供任何人查看.
https://drive.google.com/open?id=17A-PB2517bPJc8Dek-yp2wGXsjTyTj1d
我有这个未修饰的窗口:
public static void initStartPage(final Stage primaryStage) {
final Stage startPage = new Stage();
startPage.initStyle(StageStyle.UNDECORATED);
//startPage.initOwner(primaryStage);
//startPage.toFront();
Scene scene = new Scene(agentsPanel(), 900, 500);
startPage.setScene(scene);
startPage.show();
}
Run Code Online (Sandbox Code Playgroud)
我很感兴趣如何让它拖动可拖动?我希望我将鼠标光标放在它上面以拖动它来改变它的位置.
PS
我测试了这个解决方案,但它不起作用:
private static FlowPane flow;
private static BorderPane bpi;
public static void initStartPage(final Stage primaryStage) {
final Stage startPage = new Stage();
startPage.initStyle(StageStyle.UNDECORATED);
startPage.initOwner(primaryStage);
//startPage.toFront();
Scene scene = new Scene(agentsPanel(primaryStage), 900, 500);
startPage.setScene(scene);
startPage.show();
}
private static double xOffset = 0;
private static double yOffset = 0;
public static BorderPane agentsPanel(final …Run Code Online (Sandbox Code Playgroud) 我有一个TableView,我想绑定a的禁用属性Button与ObservableList表的模型的大小.特别是,我想在ObservableList大于2 的大小时禁用按钮.
我怎样才能做到这一点?
在我使用的表中没有选择任何行时禁用另一个按钮
editRoadButton.disableProperty().bind(roadsTable.getSelectionModel().selectedItemProperty().isNull());
Run Code Online (Sandbox Code Playgroud)
有类似的方法吗?