Saltar al contenido

JavaFX: cambia el idioma de la aplicación sobre la marcha

Ya no necesitas buscar más por todo internet ya que llegaste al espacio correcto, tenemos la respuesta que quieres sin complicaciones.

Solución:

Puedes hacer algo como esto. Como en su respuesta, querrá implementar esto como un singleton o usar un marco DI para inyectar una sola instancia donde lo necesite:

public class ObservableResourceFactory 

    private ObjectProperty resources = new SimpleObjectProperty<>();
    public ObjectProperty resourcesProperty() 
        return resources ;
    
    public final ResourceBundle getResources() 
        return resourcesProperty().get();
    
    public final void setResources(ResourceBundle resources) 
        resourcesProperty().set(resources);
    

    public StringBinding getStringBinding(String key) 
        return new StringBinding() 
             bind(resourcesProperty()); 
            @Override
            public String computeValue() 
                return getResources().getString(key);
            
        ;
    

Ahora puedes hacer cosas como:

ObservableResourceFactory resourceFactory = .... ;

resourceBundle.setResources(...);

Label greetingLabel = new Label();
greetingLabel.textProperty().bind(resourceFactory.getStringBinding("greeting"));

Y cada vez que actualice el recurso con

resourceFactory.setResources(...);

hará que la etiqueta actualice su texto.

Aquí hay un SSCCE (con disculpas por la forma extremadamente fea de forzar un ResourceBundle en una sola clase ejecutable …)

import java.util.ListResourceBundle;
import java.util.Locale;
import java.util.ResourceBundle;

import javafx.application.Application;
import javafx.beans.binding.StringBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class ResourceBundleBindingExample extends Application 

    private static final String RESOURCE_NAME = Resources.class.getTypeName() ;

    private static final ObservableResourceFactory RESOURCE_FACTORY = new ObservableResourceFactory();

    static 
        RESOURCE_FACTORY.setResources(ResourceBundle.getBundle(RESOURCE_NAME));
    

    @Override
    public void start(Stage primaryStage) 
        ComboBox languageSelect = new ComboBox<>();
        languageSelect.getItems().addAll(Locale.ENGLISH, Locale.FRENCH);
        languageSelect.setValue(Locale.ENGLISH);
        languageSelect.setCellFactory(lv -> new LocaleCell());
        languageSelect.setButtonCell(new LocaleCell());

        languageSelect.valueProperty().addListener((obs, oldValue, newValue) -> 
            if (newValue != null) 
                RESOURCE_FACTORY.setResources(ResourceBundle.getBundle(RESOURCE_NAME, newValue));
            
        );

        Label label = new Label();
        label.textProperty().bind(RESOURCE_FACTORY.getStringBinding("greeting"));

        BorderPane root = new BorderPane(null, languageSelect, null, label, null);
        root.setPadding(new Insets(10));
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    

    public static class LocaleCell extends ListCell 
        @Override
        public void updateItem(Locale locale, boolean empty) 
            super.updateItem(locale, empty);
            if (empty) 
                setText(null);
             else 
                setText(locale.getDisplayLanguage(locale));
            
        
    

    public static class ObservableResourceFactory 

        private ObjectProperty resources = new SimpleObjectProperty<>();
        public ObjectProperty resourcesProperty() 
            return resources ;
        
        public final ResourceBundle getResources() 
            return resourcesProperty().get();
        
        public final void setResources(ResourceBundle resources) 
            resourcesProperty().set(resources);
        

        public StringBinding getStringBinding(String key) 
            return new StringBinding() 
                 bind(resourcesProperty()); 
                @Override
                public String computeValue() 
                    return getResources().getString(key);
                
            ;
        

    

    public static class Resources extends ListResourceBundle 

        @Override
        protected Object[][] getContents() 
            return new Object[][] 
                    "greeting", "Hello"
            ;
        

    

    public static class Resources_fr extends ListResourceBundle 

        @Override
        protected Object[][] getContents() 
            return new Object[][] 
                    "greeting", "Bonjour"
            ;
        

    

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

valoraciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *