2016-05-04 3 views
0

Я создал сетку кнопок в JavaFX.
Когда я изменяю размер окна с помощью сетки внутри, кнопки также изменяются в пределах сетки.
Проблема в том, что текст на этих кнопках не изменяется вместе с ними: он остается одного и того же размера, поэтому, когда кнопки становятся большими, на кнопке много свободного места, а затем крошечный маленький текст в середине, который выглядит ужасно.
Я бы предпочел, чтобы текст автоматически изменялся вместе с этими кнопками, чтобы соответствовать пустому пространству, так что, когда весь пользовательский интерфейс становится больше, текст на кнопках становится больше.
Как я могу это сделать?Масштабирование текста кнопки с помощью кнопки в JavaFX

Я пробовал установить -fx-font-size в таблице стилей CSS на процентные значения, но он, похоже, не работает так же, как и для веб-сайтов: текст не масштабируется в процентах от его контейнера, а в процентах от некоторый предопределенный размер текста.

Редактировать
Это не дубликат! Прекратите отмечать каждый вопрос там, как дубликат! Если бы он был дан ответ, я бы не спросил его в первую очередь!

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

Другая проблема заключалась в масштабировании текста вместе с корневым контейнером/окном с заданным размером шрифта. Это также отличается от того, что мне нужно, потому что я не хочу, чтобы текст был масштабирован с помощью окна , но с размерами кнопок . И его нужно масштабировать определенным образом: чтобы всегда соответствовать размеру кнопки. Вы знаете: текст остается прежним, но растягивается так, что он всегда подходит внутри кнопки (с небольшим отступом, а не с огромной пустой областью вокруг текста).

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

+0

Это может быть дубликат http://stackoverflow.com/questions/34812022/javafx-automatically-resize-buttons-font-size-to-fit-in или http://stackoverflow.com/questions/23705654/bind-font-size-in-javafx – hotzst

+0

Если бы больше людей отвечало на вопросы вместо того, чтобы просто искать дубликаты или потенциальные закрытия, StackOverflow был бы замечательным снова, как в эти старые времена ...; PI прочитал эти два вопроса до спрашивая себя. Если бы я нашел решение там, я бы не стал задавать свой вопрос в первую очередь. (Если я не пропустил что-то в этих потоках.) – SasQ

+0

В чем разница между установкой размера шрифта кнопки при ее создании, чтобы он соответствовал размеру фиксированной кнопки и обновлял размер шрифта при изменении размера кнопки, так что он делает то же самое? Извините: я * действительно * не вижу, как это разные вещи. (Не то, чтобы это решение было особенно приятным, но все же ... как на самом деле это отличается от всего тривиального?) –

ответ

2

Это понравилось связанным вопросам, что-то вроде взлома: но подумайте о масштабировании текстового узла внутри кнопки вместо изменения размера шрифта. Это, кажется, работает нормально:

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.Priority; 
import javafx.stage.Stage; 

public class ScaledButtons extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     GridPane root = new GridPane(); 
     root.setHgap(5); 
     root.setVgap(5); 
     for (int i = 1; i <= 9 ; i++) { 
      root.add(createScaledButton(Integer.toString(i)), (i-1) % 3, (i-1)/3); 
     } 
     root.add(createScaledButton("#"), 0, 3); 
     root.add(createScaledButton("0"), 1, 3); 
     root.add(createScaledButton("*"), 2, 3); 

     primaryStage.setScene(new Scene(root, 250, 400)); 
     primaryStage.show(); 
    } 

    private Button createScaledButton(String text) { 
     Button button = new Button(text); 
     GridPane.setFillHeight(button, true); 
     GridPane.setFillWidth(button, true); 
     GridPane.setHgrow(button, Priority.ALWAYS); 
     GridPane.setVgrow(button, Priority.ALWAYS); 

     button.layoutBoundsProperty().addListener((obs, oldBounds, newBounds) -> 
      scaleButton(button)); 

     button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE); 

     return button ; 
    } 

    private void scaleButton(Button button) { 
     double w = button.getWidth(); 
     double h = button.getHeight(); 

     double bw = button.prefWidth(-1); 
     double bh = button.prefHeight(-1); 

     if (w == 0 || h == 0 || bw == 0 || bh == 0) return ; 

     double hScale = w/bw ; 
     double vScale = h/bw ; 

     double scale = Math.min(hScale, vScale); 

     button.lookup(".text").setScaleX(scale); 
     button.lookup(".text").setScaleY(scale); 
    } 

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

Хм ... интересный. Я не знал, что внутри кнопки есть текстовый узел. Это где-то задокументировано? – SasQ

+0

Я думал, что это задокументировано в документах CSS, хотя, когда я кратко проверил, я не видел его там. –

0

Альтернативный подход, чтобы получить подобный эффект может быть подкласс com.sun.javafx.scene.control.skin.ButtonSkin и переопределить layoutLabelInArea(double x, double y, double w, double h, Pos alignment) метод из родительского кожи (LabeledSkinBase). Затем вы можете явно назначить обновленный скин своей кнопке (либо через CSS, либо через вызовы Java API).

Для этого потребуются подклассы com.sun API, которые могут быть изменены без уведомления в последующих выпусках JavaFX. Также layoutLabelInArea является достаточно сложным в своей работе, поэтому изменение логики компоновки может быть немного сложным.Разумеется, предложение Джеймса применить операцию масштабирования текста, основанную на слушателе, на свойство ограничений границ, проще в этом конкретном случае.

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

+0

Обратите внимание, что в Java 9 класс skin является общедоступным API. –