本帖最后由 Gaowen_HAN 于 2013-08-19 19:13:43 编辑

解决方案 »

  1.   

    我只是计算机业余爱好者本行做营销的,对编程方面的知识涉及面很窄,只是下班回来后查了查网上资料有感而写的小程序而已。具体开发大项目还从来没做过或者精通java也谈不上。
      

  2.   

    我只是计算机业余爱好者本行做营销的,对编程方面的知识涉及面很窄,只是下班回来后查了查网上资料有感而写的小程序而已。具体开发大项目还从来没做过或者精通java也谈不上。业余爱好能发展到这水平很厉害了。
      

  3.   

    我只是计算机业余爱好者本行做营销的,对编程方面的知识涉及面很窄,只是下班回来后查了查网上资料有感而写的小程序而已。具体开发大项目还从来没做过或者精通java也谈不上。业余爱好能发展到这水平很厉害了。哦,反正就是平时喜欢,几年来一直利用休息时间看看CSDN论坛,自己编程写写自己想要实现的东西,然后就是什么想学一点。。发现国外的很多网站做得很好,受益不少。
      

  4.   

    我用Swing做出的例子:JavaFX做出的界面:后来又做出了自己编写的一套基于Synth的L&F,其与直接在代码中重绘某个组件不同,最大优点是具有可插拔性,即在不改变原有程序代码的情况下,用户可以自己选择切换风格,通用性增强。对于前面的JLayer的界面切换成MyLNF后的效果:
    (获得焦点效果)(失去焦点后的效果)(鼠标移到Container内容面板上后显示的效果)最后说下自己的感想:
    1、现在Java界面编程真的不是首选。可插拔式的Look and feel不论基于Basic还是Metal编写繁琐,开发周期长。后来1.7推出的Synth基于XML导入式概念虽然新颖,但是对于Components Specific Properties的支持不够例如对于JTable的Properties支持很少导致可定制性降低。基于Nimbus编写的话,首先运行效率不如Metal,然后重绘每个Component也很麻烦,用图片做背景需要九宫格技术的支持。无论如何,Look and feel由于Java内部本身的限制,提供定制的范围确实有限,有些东西你customize不了,因为它没有提供那样的接口。
    2、但是简单的界面编写如对动态效果没什么要求,对Desktop集成没什么要求(Java需要调用JNI来集成一些桌面特性,如WIn7任务栏图片的进度加载显示,还有比如SystemTray也只能用AWT的PopupMenu导致没法定制出和QQ、迅雷等一样的托盘效果),使用Swing还是可以的,Swing的优势也就在于跨平台性好,优于SWT。建议简单界面能使用Swing的还是不要使用SWT,对于简单界面,自己编写的L&F也搓搓有余了。
    3、对于想要Charts、多媒体支持、动画效果、滤镜支持、触摸事件感应处理等富Internet绚丽界面的追求的话,建议选择用JavaFX,可插拔式用外部链接的CSS代替,一般界面的编写可以用FXML,逻辑处理用Java语言或者JavaScript。这样结构化很明显,也很现代化(参见MVC设计模式)。但是JavaFX目前Bug还是很多,很多功能不完善,比如SystemTray没有支持,Print打印功能也是在未来Java8中绑定,但是对于打印表格table似乎还没有支持(我不大确定,因为我只是初步的看了一下,还没有深入研究)。但其UI组件未来会逐渐增多。
    4、目前的话Java界面编写还是JavaFX比较有前途,但是就目前的JavaFX而言似乎没有什么明显的竞争力,只能期待以后的发展了。
    5、建议还是用目前主流的软件编写工具(例如论坛同志所说的“要做Desktop GUI 推荐QT C++,ui tool 和 qml 非常易用强大。”)。想要在Windows下使用的话,还是尽量调用本地化的windows API。
    6、用数据库相结合的小软件编写,Java还是不错的。内置的JavaDB就不错,MySQL以及Microsoft Database也有很多开发案例,使用Oracle大型数据库就更不用说了。Swing给我印象最深的就是绘图机制十分强大,至少在引入Android的NinePatch技术上领先JavaFX(如果有同志知道如何在JavaFX上使用类似于Android的NinePatch技术的,非常感谢告知我),一定要深刻理解java界面的绘图机制。像背景图片什么绘制是很简单的,至于图像的缩放,运用ImageOP写个缩放的,或者模糊效果等等,在Java 界面代码中用paintComponent()方法来定制背景图片的可以根据addComponentListener()中的componentResize()来缩放就可以了(使用repaint())。绘制Border或者Button的背景,图片最好使用九宫格技术,防止图片拉伸失真。在Synth中,它自带把图片分为9块的技术,使用起来十分方便,然而不如Android的NinePatch技术,因为她不仅可以分图片为9块,而且可以根据需要分为若干块我非常欣赏。最近正在写一套的基于Nimbus的lnf(当然使用了Android的NinePatch技术),感觉还不错,推荐诸位试一下,我顺带研究JavaFX,觉得前途还是有的,因为Oracle计划不断随着Java8,9,10的推出更新、支持JavaFX。
      

  5.   

    谢谢楼主分享,我之前有个朋友研究html5,好像也很有前途,我现在想转行做java,我想学学java的框架,spring之类的,所以楼主的示例代码可不可以发给我  [email protected],谢谢
      

  6.   

    修改楼主的MVC例子版本:
    <?xml version="1.0" encoding="UTF-8"?>
    <?language javascript?><?import javafx.scene.text.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.Scene?><!-- "id" serves to CSS, "fx:id" serves to controller(java or js) and CSS -->
    <Scene xmlns:fx="http://javafx.com/fxml" width="300" height="275">
    <fx:script source="info.js"/>
    <GridPane styleClass="grid-pane">
    <Text styleClass="welcome-text" text="%welcome" 
        GridPane.columnIndex="0" GridPane.rowIndex="0" 
        GridPane.columnSpan="2"/>
    <Label text="%userName" 
        GridPane.columnIndex="0" GridPane.rowIndex="1"/>
    <TextField 
        GridPane.columnIndex="1" GridPane.rowIndex="1"/>
    <Label text="%password" 
        GridPane.columnIndex="0" GridPane.rowIndex="2"/>
    <PasswordField 
        GridPane.columnIndex="1" GridPane.rowIndex="2"
        onAction="#handlePFAction"/>
    <HBox styleClass="h-box"
        GridPane.columnIndex="1" GridPane.rowIndex="4">
    <Button fx:id="submitButton" text="%signIn" 
    onAction="#handleSubmitButtonAction"/>
    </HBox>
    <Text fx:id="actionTarget" 
    GridPane.columnIndex="1" GridPane.rowIndex="6"/>
    <!-- <gridLinesVisible>true</gridLinesVisible> -->
    </GridPane>
    <fx:script>
        var System = java.lang.System;
        var message = "this is the end of XML contents";
        System.out.println(message);
        </fx:script>
    </Scene>
    /* applies to the root node of Scene, it can specify global common properties */
    .root {
        -fx-background-image: url("background.jpg");
    }.label {
        -fx-font-size: 12px;
        -fx-font-weight: bold;
        -fx-text-fill: #333333;
        -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 );
    }.button {
        -fx-text-fill: white;
        -fx-font-family: "Arial Narrow";
        -fx-font-weight: bold;
        -fx-background-color: linear-gradient(#61a2b1, #2A5058);
        -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5,0,0,1 );
    }.button:hover, .button:armed { /* pseudo-classes */   
        -fx-background-color: linear-gradient(#2A5058, #61a2b1);
    }.grid-pane {
    -fx-hgap: 10;
    -fx-vgap: 10;
    -fx-alignment: center;
    -fx-grid-lines-visible: false;
    -fx-padding: 25 25 10 25;
    }.h-box {
    -fx-spacing: 10;
    -fx-alignment: bottom-right;
    }.welcome-text {
        -fx-font-size: 32px;
        -fx-font-family: "Arial Black";
        -fx-fill: #818181;
        -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7), 6,0,0,2 );
    }#actionTarget {
        -fx-fill: FIREBRICK;
        -fx-font-weight: bold;
        -fx-effect: dropshadow( gaussian, rgba(255,255,255,0.5), 0,0,0,1 );
    }
    // Provide some necessary infos
    importClass(java.lang.System);
    var info = "starts loading of XML file";
    System.out.println(info);
    # This is a default resource bundle when a searching in getBundle() with the 
    # given locale fails.
    welcome=Welcome
    userName=User Name:
    password=Password:
    signIn=Sign In
    actionTarget=Sign in button pressed
    # This is a Chinese resource bundle. It is encoded by ISO-8859-1. In this case, 
    # characters that cannot be directly represented in ISO-8859-1 encoding can be 
    # written using Unicode escapes as defined in section 3.3 of The Java\u2122 
    # Language Specification.
    welcome=\u6B22\u8FCE
    userName=\u7528\u6237\u540D\uFF1A
    password=\u5BC6\u7801\uFF1A
    signIn=\u767B\u9646
    actionTarget=\u767B\u9646\u6309\u94AE\u88AB\u6309\u4E0B
    # This is a en_US resource bundle.
    welcome=Welcome
    userName=User Name:
    password=Password:
    signIn=Sign In
    actionTarget=Sign in button pressed
    # This is a fr_FR resource bundle.
    welcome=Bienvenue
    userName=Identifiant:
    password=Mot de Passe:
    signIn=Se connecter
    actionTarget=Bouton appuyé
    package loginfxml;import java.net.URL;
    import java.util.ResourceBundle;import javafx.animation.PauseTransition;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Button;
    import javafx.scene.text.Text;
    import javafx.util.Duration;/**
     * It is often preferable to define more complex application logic in a
     * compiled, strongly-typed language such as Java. For example, some complex
     * event handlers and any other application logic.
     * <p>
     * It implements an <code>Initializable</code> interface, which defines
     * <code>an initialize()</code> method. It will be called once on an
     * implementing controller when the contents of its associated document have
     * been completely loaded. It allows the implementing class to perform any
     * necessary post-processing on the content.
     * 
     * @author HAN
     * 
     */
    public class Controller implements Initializable {
    // If the controller member fields or methods are private or protected, it
    // should be annotated so as to be accessible to up. If they are public,
    // the javafx.fxml.FXML annotation is not necessary.
    @FXML
    private Button submitButton; @FXML
    private Text actionTarget;

    private ResourceBundle resources;

    @FXML
    private void handlePFAction() {
    PauseTransition pressTime = new PauseTransition(Duration.millis(220));
    pressTime.setOnFinished(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
    submitButton.disarm();
    submitButton.fire();
    }
    });
    submitButton.arm();
    pressTime.play();
    }

    @FXML
    private void handleSubmitButtonAction() {
    actionTarget.setText(resources.getString("actionTarget"));
    } @Override
    public void initialize(URL location, ResourceBundle resources) {
    System.out.println("location: " + location);
    System.out.println("resources: " + resources);
    this.resources = resources;

    System.out.println("to perform any necessary post-processing on the "
    + "content, which will be called once when the contents of "
    + "its associated document have been completely loaded");
    // For example, to process lookup() method with the given CSS selector,
    // which normally in java code should be placed after Stage.show(). Note
    // that the button defined in FXML can not be invoked in Model java code
    // file which is proven by my practice.
    System.out.println("name of submit button: " + submitButton.getText());
    System.out.println(submitButton.lookupAll(".button"));
    Button button = (Button) submitButton.lookup(".button");
    button.setText("Sign in");
    System.out.println("new name of submit button: "
    + submitButton.getText());
    }
    }
    package loginfxml;import java.util.Locale;
    import java.util.Map;
    import java.util.ResourceBundle;import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Scene;
    import javafx.stage.Stage;public class Model extends Application {
    public static void main(String[] args) {
    launch(args);
    } @Override
    public void start(Stage stage) throws Exception {
    Locale locale = getCurrentLocale();
    FXMLLoader fxmlLoader = new FXMLLoader();
    fxmlLoader.setLocation(Model.class.getResource("View.fxml"));
    ResourceBundle resources = ResourceBundle.getBundle(
    "loginfxml/MyResources", locale, Model.class.getClassLoader());
    fxmlLoader.setResources(resources);
    fxmlLoader.setController(new Controller());
    Scene scene = (Scene) fxmlLoader.load();
    scene.getStylesheets().add(
    Model.class.getResource("login.css").toExternalForm());
    stage.setTitle("Welcome FXML");
    stage.setScene(scene);
    stage.setResizable(false);
    stage.show();
    } private Locale getCurrentLocale() {
    Map<String, String> namedParams = getParameters().getNamed();
    String languageParam = namedParams.get("language");
    String countryParam = namedParams.get("country"); Locale locale = Locale.getDefault();
    if (languageParam != null && languageParam.trim().length() > 0) {
    if (countryParam != null && countryParam.trim().length() > 0) {
    locale = new Locale(languageParam.trim(), countryParam.trim());
    } else {
    locale = new Locale(languageParam.trim());
    }
    }
    return locale;
    }
    }所有资源下载链接:
    View.fxml
    login.css
    info.js
    MyResources.properties
    MyResources_zh_CN.properties
    MyResources_en_US.properties
    MyResources_fr_FR.properties
    Controller.java
    Model.java运行结果(注:在命令行中设置语言包,或者在你的JNLP文件中设置以便Applet或者WebStart应用):
      

  7.   

    运行结果(注:在命令行中设置语言包,或者在你的JNLP文件中设置以便Applet或者WebStart应用):
      

  8.   

    +1
    有些 basic ui 类有明显的设计缺陷,很多东西被硬编码,导致扩展功能比较困难……SwingLabs (SwingX) 的很多组件都没有加进 JDK ……据说 SwingApplicationFramework (JSR 296) 曾经试图加进JDK,未果……
    如果有 SwingApplicationFramework 的话,也许至少会帮助初学者写出线程基本正确的Swing程序(由于对Swing线程机制的不理解,很多很多的Swing程序线程都是错的,新手开始写Swing程序极少有人把线程写对。留意过一些培训课程,很多“名师”,甚至专讲Swing入门的课程,里面的线程居然也是错的)Oracle 在UI方面的重心还是放在 JavaFX 上了,Swing基本上是处于维护状态。Swing 里的 MVC 也许不是很好的学习的例子,因为可以从不同的层面理解……,而有些层面是 M + VC,其中的 VC 就是一些硬编码的ui类我觉得 Swing 里面最有学习价值的大概是它的单线程机制,因为这种单线程机制是在很多UI框架都通用的知识。有一篇很老的文章今天也没有过时:
    https://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html
      

  9.   

    嗯,Swing的线程重要性是绝对的。EDT,main,SwingWorker或者自定义一个线程都可以丰富Swing的开发比如组件动态效果响应等。SwingWorker可以优化Swing编写复杂界面响应慢或无响应的问题。组件的创建在EDT,不要直接在main线程里直接new JFrame()等等。有几个外国权威网站写的关于Swing Thread的写的比较好,英语无障碍的推荐去看一下。
      

  10.   

    嗯,Swing的线程重要性是绝对的。EDT,main,SwingWorker或者自定义一个线程都可以丰富Swing的开发比如组件动态效果响应等。SwingWorker可以优化Swing编写复杂界面响应慢或无响应的问题。组件的创建在EDT,不要直接在main线程里直接new JFrame()等等。有几个外国权威网站写的关于Swing Thread的写的比较好,英语无障碍的推荐去看一下。还想说一点,MVC只是一个设计模式,比如Swing JButton的ButtonUI就是View,ButtonModel就是Model,JButton的一些方法就起到控制的作用。但是Swing的整体设计好像还达不到我上面列举的JavaFX Login程序的MVC模式。这样使得一个Swing程序特别是复杂界面的程序往往比较混杂,不利于可读性和以后的可维护性。
      

  11.   

    <?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.Scene?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.control.cell.PropertyValueFactory?>
    <?import javafx.collections.FXCollections?>
    <?import addressbook.*?><Scene xmlns:fx="http://javafx.com/fxml" fx:controller="addressbook.Controller" 
        stylesheets="addressbook/addressbook.css">
        <GridPane styleClass="grid-pane">
            <Label id="address-book" text="%addressBook" 
                GridPane.columnIndex="0" GridPane.rowIndex="0"/>
            <TableView fx:id="tableView" tableMenuButtonVisible="true"
                GridPane.columnIndex="0" GridPane.rowIndex="1">
                <columns>
                    <TableColumn fx:id="firstNameColumn" 
                     text="%firstName" prefWidth="100">
                     <cellValueFactory>
                     <PropertyValueFactory property="firstName"/>
                     </cellValueFactory>
                     <cellFactory>
                     <FormattedTableCellFactory alignment="CENTER"/>
                     </cellFactory>
                    </TableColumn>
                    <TableColumn 
                     text="%lastName" prefWidth="100">
                     <cellValueFactory>
                     <PropertyValueFactory property="lastName"/>
                     </cellValueFactory>
                    </TableColumn>
                    <TableColumn 
                     text="%email" prefWidth="210" sortable="false">
                     <cellValueFactory>
                     <PropertyValueFactory property="email"/>
                     </cellValueFactory>
                    </TableColumn>
                </columns>
                <Person firstName="Jacob" lastName="Smith"  
                    email="[email protected]"/>
         <Person firstName="Isabella" lastName="Johnson" 
              email="[email protected]"/>
         <Person firstName="Ethan" lastName="Williams" 
              email="[email protected]"/>
         <Person firstName="Emma" lastName="Jones"
              email="[email protected]"/>
    <Person firstName="Michael" lastName="Brown" 
              email="[email protected]"/>
                <sortOrder>
               <fx:reference source="firstNameColumn"/>
          </sortOrder>
            </TableView>
            <HBox styleClass="h-box" GridPane.columnIndex="0" GridPane.rowIndex="2">
             <TextField fx:id="firstNameField" promptText="%firstName"
                    prefWidth="90"/>
              <TextField fx:id="lastNameField" promptText="%lastName"
                    prefWidth="90"/>
              <TextField fx:id="emailField" promptText="%email"
                    prefWidth="150"/>
            <Button text="%add" onAction="#addPerson"/>
            </HBox>
        </GridPane>
    </Scene>.grid-pane {
        -fx-alignment: center;
        -fx-hgap: 10;
        -fx-vgap: 10;
        -fx-padding: 10;
    }#address-book {
        -fx-font: NORMAL 20 Tahoma;
    }.h-box {
    -fx-spacing:10;
    -fx-alignment: bottom-right;
    }# Title of window
    title=FXML Address Book# Name of label above the table view
    addressBook=Address Book# Name of the first table column 
    # & Prompt text of text field for the first table column
    firstName=First Name# Name of the second table column
    # & Prompt text of text field for the second table column
    lastName=Last Name# Name of the third table column
    # & Prompt text of text field for the third table column
    email=Email Address# Name of button for adding rows to table
    add=Add# Title of window
    title=FXML\u5730\u5740\u7C3F# Name of label above the table view
    addressBook=\u5730\u5740\u7C3F# Name of the first table column 
    # & Prompt text of text field for the first table column
    firstName=\u540D\u5B57# Name of the second table column
    # & Prompt text of text field for the second table column
    lastName=\u59D3# Name of the third table column
    # & Prompt text of text field for the third table column
    email=\u7535\u5B50\u90AE\u4EF6# Name of button for adding rows to table
    add=\u6DFB\u52A0package addressbook;import java.text.Format;import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.geometry.Pos;
    import javafx.scene.Node;
    import javafx.scene.control.ContextMenu;
    import javafx.scene.control.MenuItem;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableRow;
    import javafx.scene.text.TextAlignment;
    import javafx.util.Callback;public class FormattedTableCellFactory<S, T> implements
    Callback<TableColumn<S, T>, TableCell<S, T>> {
    private TextAlignment alignment;
    private Format format; public TextAlignment getAlignment() {
    return alignment;
    } public Format getFormat() {
    return format;
    } public void setAlignment(TextAlignment alignment) {
    this.alignment = alignment;
    } public void setFormat(Format format) {
    this.format = format;
    } @Override
    public TableCell<S, T> call(TableColumn<S, T> arg0) {
    final TableCell<S, T> cell = new TableCell<S, T>() {
    @Override
    protected void updateItem(T item, boolean empty) {
    if (item == getItem()) {
    return;
    }
    super.updateItem(item, empty);
    if (item == null) {
    setText(null);
    setGraphic(null);
    } else if (item instanceof Node) {
    setText(null);
    setGraphic((Node) item);
    } else if (format != null) {
    setText(format.format(item));
    setGraphic(null);
    } else {
    setText(item.toString());
    setGraphic(null);
    } /* add a context menu */
    addCM(this);
    }
    };
    if (alignment == null) alignment = TextAlignment.LEFT;
    cell.setTextAlignment(alignment);
    switch (alignment) {
    case CENTER:
    cell.setAlignment(Pos.CENTER);
    break;
    case RIGHT:
    cell.setAlignment(Pos.CENTER_RIGHT);
    break;
    default:
    cell.setAlignment(Pos.CENTER_LEFT);
    }
    return cell;
    } private MenuItem delete = new MenuItem("Delete");
    private ContextMenu contextMenu = new ContextMenu(delete); private void addCM(final TableCell<S, T> cell) {
    @SuppressWarnings("rawtypes")
    final TableRow row = cell.getTableRow();
    delete.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent e) {
    cell.getTableView().getItems().remove(row.getItem());
    }
    });
    if (row != null) {
    if (row.getItem() != null) {
    row.setContextMenu(contextMenu);
    }
    }
    }
    }package addressbook;import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;/**
     * A Bean convention based data model.
     * 
     * @author HAN
     */
    public class Person {
    private StringProperty firstName = new SimpleStringProperty();
    private StringProperty lastName = new SimpleStringProperty();
    private StringProperty email = new SimpleStringProperty(); public Person() {
    this("", "", "");
    } public Person(String firstName, String lastName, String email) {
    setFirstName(firstName);
    setLastName(lastName);
    setEmail(email);
    } public final String getFirstName() {
    return firstName.get();
    } public final String getLastName() {
    return lastName.get();
    } public final String getEmail() {
    return email.get();
    } public final void setFirstName(String firstName) {
    this.firstName.set(firstName);
    } public final void setLastName(String lastName) {
    this.lastName.set(lastName);
    } public final void setEmail(String email) {
    this.email.set(email);
    } public StringProperty firstNameProperty() {
    return firstName;
    } public StringProperty lastNameProperty() {
    return lastName;
    } public StringProperty emailProperty() {
    return email;
    }
    }/**
     * An address book application.
     * 
     * @author HAN
     */
    package addressbook;package addressbook;import javafx.fxml.FXML;
    import javafx.scene.control.TableView;
    import javafx.scene.control.TextField;public class Controller {
    @FXML
    private TableView<Person> tableView;
    @FXML
    private TextField firstNameField;
    @FXML
    private TextField lastNameField;
    @FXML
    private TextField emailField; @FXML
    private void addPerson() {
    tableView.getItems().add(
    new Person(firstNameField.getText(), lastNameField.getText(),
    emailField.getText()));
    firstNameField.clear();
    lastNameField.clear();
    emailField.clear();
    }
    }package addressbook;import java.util.Locale;
    import java.util.Map;
    import java.util.ResourceBundle;import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Scene;
    import javafx.stage.Stage;public class Model extends Application {
    public static void main(String[] args) {
    launch(args);
    } @Override
    public void start(Stage stage) throws Exception {
    Locale locale = getCurrentLocale();
    ResourceBundle resources = ResourceBundle
    .getBundle("addressbook/addressbook", locale,
    Model.class.getClassLoader());
    stage.setTitle(resources.getString("title"));
    stage.setScene((Scene) FXMLLoader.load(
    Model.class.getResource("View.fxml"), resources));
    stage.show();
    } private Locale getCurrentLocale() {
    Map<String, String> namedParams = getParameters().getNamed();
    String languageParam = namedParams.get("language");
    String countryParam = namedParams.get("country"); Locale locale = Locale.getDefault();
    if (languageParam != null && languageParam.trim().length() > 0) {
    if (countryParam != null && countryParam.trim().length() > 0) {
    locale = new Locale(languageParam.trim(), countryParam.trim());
    } else {
    locale = new Locale(languageParam.trim());
    }
    }
    return locale;
    }
    }