JavaFX Как я могу центрировать всплывающую подсказку на узле? - PullRequest
0 голосов
/ 11 января 2019

В настоящее время я работаю над формой, которая имеет функцию проверки при смене фокуса с одного узла на другой, и хочу отобразить всплывающую подсказку с центром над узлом, содержащим ошибку, если таковая существует. Я использую подпись метода show(Node ownerNode, double anchorX, double anchorY) в подсказке, чтобы указать, к какому узлу я хочу присоединить его и где его разместить.

Я пробовал следующий код:

Tooltip tooltip = new Tooltip("Error"); 
tooltip.show(node, 0, 0);
double tooltipMiddle = tooltip.getWidth() / 2;
tooltip.hide(); 
double nodeMiddle = node.getWidth() / 2; 

//Gets the node's x and y position within the window
Bounds bounds = node.localToScene(node.getBoundsInLocal());  

//Tooltip's bottom-right corner is set to the anchor points, so I set x to
//the node's x coordinate plus half the width of the node plus half the width
//of the tooltip 
tooltip.show(node,
             bounds.getMinX() + nodeMiddle + tooltipMiddle, bounds.getMinY());

Это привело меня очень близко к центру, но он все еще выключен. Я был в интернете, пытаясь найти помощь, но я просто не нахожу ее, поэтому я решил спросить здесь.
Есть ли шанс, что я смогу понять, почему я не могу заставить это работать так, как мне бы хотелось?

Validation message screenshot

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Код, который я привожу, обеспечивает правильное позиционирование всплывающей подсказки, но далеко не идеален. Потребовалось бы много работы, чтобы найти комплексное решение (если вы хотите, мы можем это обсудить). Переходя к сути, я думаю, что у вас математическая проблема, и класс Tooltip может оказаться не лучшим вариантом.

import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TooltipApp extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        TextField textField = new TextField();
        textField.setPrefWidth(100.);

        Button button = new Button("Tooltip");

        HBox hBox = new HBox(textField, button);
        hBox.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);

        Label label = new Label("Empty!");
        label.setVisible(false);
        Pane tooltipPane = new Pane(label);
        tooltipPane.setMouseTransparent(true);

        StackPane stackPane = new StackPane(hBox, tooltipPane);
        stackPane.setPrefSize(600., 400.);

        Scene scene = new Scene(stackPane);

        stage.setScene(scene);
        stage.show();

        button.setOnMouseClicked(event -> {
            if (label.isVisible()) {
                label.setVisible(false);
            } else {
                Bounds sceneBounds = textField.localToScene(textField.getBoundsInLocal());
                label.setLayoutX((sceneBounds.getMinX() + (sceneBounds.getWidth() / 2)) - (label.getWidth() / 2));
                label.setLayoutY(sceneBounds.getMinY() - label.getHeight());
                label.setVisible(true);
            }
        });
    }
}
0 голосов
/ 11 января 2019

Сначала вы должны использовать Bounds bounds = node.localToScreen(node.getBoundsInLocal());, так как может быть неясно, что означает Scene.

Тогда вызов tooltip.show(node, bounds.getMinX(), bounds.getMinY()); даст вам всплывающую подсказку с верхним левым углом, идентичным верхнему левому верхнему углу узла.

Теперь, tooltip.show(node, bounds.getMinX() + nodeMiddle - tooltipMiddle, bounds.getMinY() - tooltipHeight); должен дать желаемый результат, и он делает для

double tooltipMiddle = (tooltip.getWidth()-18) / 2;
double tooltipHeight = tooltip.getHeight()-18;
double nodeMiddle = getWidth() / 2;

18 был получен в результате небольшого эксперимента, и я не уверен, почему ширина и высота не соответствуют этой величине, но, похоже, он не зависит от длины или количества строк текста во всплывающей подсказке.

...