수색…


리소스 묶음로드 중

JavaFX는 사용자 인터페이스를 국제화하는 쉬운 방법을 제공합니다. FXML 파일에서 뷰를 생성하는 동안 FXMLLoader 에 리소스 번들을 제공 할 수 있습니다.

Locale locale = new Locale("en", "UK");
ResourceBundle bundle = ResourceBundle.getBundle("strings", locale);

Parent root = FXMLLoader.load(getClass().getClassLoader()
                                  .getResource("ui/main.fxml"), bundle);

이 번들은 % 시작하는 FXML 파일의 모든 텍스트를 자동으로 번역하는 데 사용됩니다. 속성 파일 strings_en_UK.properties 에 다음 줄이 포함되어 있다고 strings_en_UK.properties .

ui.button.text=I'm a Button

FXML에 버튼 정의가있는 경우 다음과 같이하십시오.

<Button text="%ui.button.text"/>

ui.button.text 키에 대한 번역이 자동으로 수신됩니다.

제어 장치

자원 번들은 로케일 고유의 객체를 포함합니다. 생성하는 동안 번들을 FXMLLoader 전달할 수 있습니다. 컨트롤러는 Initializable 인터페이스를 구현하고 initialize(URL location, ResourceBundle resources) 메서드를 오버라이드해야합니다. 이 메소드의 두 번째 매개 변수는 ResourceBundle 로 FXMLLoader에서 컨트롤러로 전달되며 컨트롤러가 텍스트를 더 번역하거나 다른 로케일 종속 정보를 수정하는 데 사용할 수 있습니다.

public class MyController implements Initializable {

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        label.setText(resources.getString("country"));
    }
}

응용 프로그램이 실행 중일 때 동적으로 언어 전환

이 예제는 응용 프로그램이 실행되는 동안 언어를 동적으로 전환 할 수있는 JavaFX 응용 프로그램을 작성하는 방법을 보여줍니다.

다음은이 예제에 사용 된 메시지 번들 파일입니다.

messages_en.properties :

window.title=Dynamic language change
button.english=English
button.german=German
label.numSwitches=Number of language switches: {0}

messages_de.properties :

window.title=Dynamischer Sprachwechsel
button.english=Englisch
button.german=Deutsch
label.numSwitches=Anzahl Sprachwechsel: {0}

기본 아이디어는 유틸리티 클래스 I18N을 갖는 것입니다 (대안으로 이것은 싱글 톤으로 구현 될 수 있습니다).

import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.concurrent.Callable;

/**
 * I18N utility class..
 */
public final class I18N {

    /** the current selected Locale. */
    private static final ObjectProperty<Locale> locale;

    static {
        locale = new SimpleObjectProperty<>(getDefaultLocale());
        locale.addListener((observable, oldValue, newValue) -> Locale.setDefault(newValue));
    }

    /**
     * get the supported Locales.
     *
     * @return List of Locale objects.
     */
    public static List<Locale> getSupportedLocales() {
        return new ArrayList<>(Arrays.asList(Locale.ENGLISH, Locale.GERMAN));
    }

    /**
     * get the default locale. This is the systems default if contained in the supported locales, english otherwise.
     *
     * @return
     */
    public static Locale getDefaultLocale() {
        Locale sysDefault = Locale.getDefault();
        return getSupportedLocales().contains(sysDefault) ? sysDefault : Locale.ENGLISH;
    }

    public static Locale getLocale() {
        return locale.get();
    }

    public static void setLocale(Locale locale) {
        localeProperty().set(locale);
        Locale.setDefault(locale);
    }

    public static ObjectProperty<Locale> localeProperty() {
        return locale;
    }

    /**
     * gets the string with the given key from the resource bundle for the current locale and uses it as first argument
     * to MessageFormat.format, passing in the optional args and returning the result.
     *
     * @param key
     *         message key
     * @param args
     *         optional arguments for the message
     * @return localized formatted string
     */
    public static String get(final String key, final Object... args) {
        ResourceBundle bundle = ResourceBundle.getBundle("messages", getLocale());
        return MessageFormat.format(bundle.getString(key), args);
    }

    /**
     * creates a String binding to a localized String for the given message bundle key
     *
     * @param key
     *         key
     * @return String binding
     */
    public static StringBinding createStringBinding(final String key, Object... args) {
        return Bindings.createStringBinding(() -> get(key, args), locale);
    }

    /**
     * creates a String Binding to a localized String that is computed by calling the given func
     *
     * @param func
     *         function called on every change
     * @return StringBinding
     */
    public static StringBinding createStringBinding(Callable<String> func) {
        return Bindings.createStringBinding(func, locale);
    }

    /**
     * creates a bound Label whose value is computed on language change.
     *
     * @param func
     *         the function to compute the value
     * @return Label
     */
    public static Label labelForValue(Callable<String> func) {
        Label label = new Label();
        label.textProperty().bind(createStringBinding(func));
        return label;
    }

    /**
     * creates a bound Button for the given resourcebundle key
     *
     * @param key
     *         ResourceBundle key
     * @param args
     *         optional arguments for the message
     * @return Button
     */
    public static Button buttonForKey(final String key, final Object... args) {
        Button button = new Button();
        button.textProperty().bind(createStringBinding(key, args));
        return button;
    }
}

이 클래스에는 JavaFX ObjectProperty 래핑 된 Java Locale 객체 인 정적 필드 localeObjectProperty 속성에 대한 바인딩을 만들 수 있습니다. 첫 번째 메소드는 JavaFX 속성을 가져오고 설정하는 표준 메소드입니다.

get(final String key, final Object... args)ResourceBundle 에서 메시지를 추출하는 데 사용되는 핵심 메소드입니다.

createStringBinding 이라는 두 메서드는 locale 필드에 바인딩 된 StringBinding 을 만들고 locale 속성이 변경 될 때마다 바인딩이 변경됩니다. 첫 번째 인수는 위에서 언급 한 get 메소드를 사용하여 메시지를 검색하고 형식을 지정하기 위해 인수를 사용하고, 두 번째 인수는 Callable 로 전달되어 새로운 문자열 값을 생성해야합니다.

마지막 두 메서드는 JavaFX 구성 요소를 만드는 메서드입니다. 첫 번째 메서드는 Label 을 만드는 데 사용되며 내부 문자열 바인딩을 위해 Callable 을 사용합니다. 두 번째 것은 Button 만들고 String 바인딩 검색에 키 값을 사용합니다.

물론 MenuItem 이나 ToolTip 처럼 더 많은 다른 객체를 만들 수 있지만이 두 객체는 ​​예제로 충분할 것입니다.

이 코드는 응용 프로그램 내에서이 클래스가 사용되는 방법을 보여줍니다.

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.util.Locale;

/**
 * Sample application showing dynamic language switching,
 */
public class I18nApplication extends Application {

    /** number of language switches. */
    private Integer numSwitches = 0;

    @Override
    public void start(Stage primaryStage) throws Exception {

        primaryStage.titleProperty().bind(I18N.createStringBinding("window.title"));

        // create content
        BorderPane content = new BorderPane();

        // at the top two buttons
        HBox hbox = new HBox();
        hbox.setPadding(new Insets(5, 5, 5, 5));
        hbox.setSpacing(5);

        Button buttonEnglish = I18N.buttonForKey("button.english");
        buttonEnglish.setOnAction((evt) -> switchLanguage(Locale.ENGLISH));
        hbox.getChildren().add(buttonEnglish);

        Button buttonGerman = I18N.buttonForKey("button.german");
        buttonGerman.setOnAction((evt) -> switchLanguage(Locale.GERMAN));
        hbox.getChildren().add(buttonGerman);

        content.setTop(hbox);

        // a label to display the number of changes, recalculating the text on every change
        final Label label = I18N.labelForValue(() -> I18N.get("label.numSwitches", numSwitches));
        content.setBottom(label);

        primaryStage.setScene(new Scene(content, 400, 200));
        primaryStage.show();
    }

    /**
     * sets the given Locale in the I18N class and keeps count of the number of switches.
     *
     * @param locale
     *         the new local to set
     */
    private void switchLanguage(Locale locale) {
        numSwitches++;
        I18N.setLocale(locale);
    }
}

이 응용 프로그램은 I18N 클래스에 의해 생성 된 StringBinding 을 사용하는 세 가지 다른 방법을 보여줍니다.

  1. 윈도우 타이틀은 StringBinding 을 직접 사용하여 바인딩됩니다.
  2. 버튼은 메시지 키와 함께 도우미 메서드를 사용합니다.
  3. 레이블은 Callable 과 함께 도우미 메서드를 사용합니다. 이 Callable I18N.get()I18N.get() 메서드를 사용하여 실제 스위치 수를 포함하는 형식화 된 변환 문자열을 가져옵니다.

버튼을 클릭하면 카운터가 증가하고 I18N 의 로케일 속성이 설정되고 문자열 바인딩이 변경되어 UI 문자열이 새 값으로 설정됩니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow