问题描述
我创建了 JavaFX 应用程序,使整个屏幕变黑。然后我决定添加 TextField 的新实例以获取用户的输入,但注意到现在整个屏幕都是白色的。我什至没有将它添加到任何窗格或场景中。我试图将 TextField 的背景颜色更改为空,但没有去除白色。
package org.medianik.tictactoe;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.Pane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.InputStream;
import static org.medianik.tictactoe.util.Constants.*;
/**
* JavaFX App
*/
public class TicTacToe extends Application{
private static TicTacToe instance;
public static TicTacToe getInstance(){
return instance;
}
private final int width;
private final int height;
final Pane pane;
public TicTacToe(){
width = calculateWidth();
height = calculateHeight();
pane = new StackPane();
instance = this;
}
public static void main(String[] args){
launch();
}
/**
* The entry point
*/
@Override
public void start(Stage stage){
//In Constants.java:
//public static final Color BACKGROUND_COLOR = Color.BLACK;
var scene = new Scene(pane,width,height,BACKGROUND_COLOR);
stage.setScene(scene);
stage.show();
setupIcon(stage);
// new TextField();
}
private int calculateWidth(){
var bounds = Screen.getPrimary().getBounds();
return Math.min((int) bounds.getWidth() - GLOBAL_OFFSET,MAX_WIDTH);
}
private int calculateHeight(){
var bounds = Screen.getPrimary().getBounds();
return Math.min((int) bounds.getHeight() - GLOBAL_OFFSET,MAX_HEIGHT);
}
private void setupIcon(Stage stage){
InputStream inputIcon = getClass().getResourceAsstream("/icon.png");
Image icon = new Image(inputIcon);
stage.getIcons().add(icon);
}
@Override
public void stop() throws Exception{
System.out.println("stop");
}
public int getWidth(){
return width;
}
public int getHeight(){
return height;
}
}
这是窗口: Picture of ordinary person 但是如果我取消注释一行:
/**
* The entry point
*/
@Override
public void start(Stage stage){
//In Constants.java:
//public static final Color BACKGROUND_COLOR = Color.BLACK;
var scene = new Scene(pane,BACKGROUND_COLOR);
stage.setScene(scene);
stage.show();
setupIcon(stage);
new TextField();
}
一切都变白了: Picture of insane one
即使我将背景设为空,也没有任何变化:
/**
* The entry point
*/
@Override
public void start(Stage stage){
var scene = new Scene(pane,BACKGROUND_COLOR);
stage.setScene(scene);
stage.show();
setupIcon(stage);
TextField text = new TextField();
text.setBackground(Background.EMPTY);
}
我该怎么做才能解决这个问题?
解决方法
看到这个有点惊讶(并且没有立即回答;)所以做了一些挖掘:
- 验证我可以在(稍微精简的)示例中重现不同的行为
- 在创建 TextField 之前/之后添加了窗格状态的调试打印输出:注意其背景之前为空,之后不为空
- 在调试器中创建字段:在控件的类加载上记录了 styleSheet init
所以不同的原因是默认的styleSheet加载在类Control的静态代码块中(可能还有其他路径):
static {
...
// Ensures that the default application user agent stylesheet is loaded
if (Application.getUserAgentStylesheet() == null) {
PlatformImpl.setDefaultPlatformUserAgentStylesheet();
}
}
修改示例:
public class TicTacToe extends Application{
public static void main(String[] args){
launch();
}
@Override
public void start(Stage stage){
Pane pane = new StackPane();
var scene = new Scene(pane,500,300,Color.BLACK);
stage.setScene(scene);
stage.show();
System.out.println("pane before styling: " + pane.getBackground());
new TextField();
Platform.runLater(() -> {
System.out.println("pane after styling: " + pane.getBackground());
});
}
}