JavaFX で英語力を補う
このエントリーは、JavaFX Advent Calendar 2014, 11日目のおまけです。
昨日は @toruwest さんの「JavaFXのTreeViewでアニメーションしてみる」でした。
明日は @skrb さんの「Java Advent Calendarと一緒になにか書きます」です。
JavaFX Advent Calendar 2014、6日目の Katsumi Kokuzawa さんの「JavaFXでMarkdownエディタを作る」を読んで
リアルタイムに入力されたテキストが変換され表示されるのって格好いいなぁって思ったので自分もチャレンジしてみた。
私は英語が駄目な残念な人間なので Google さんと JavaFX さんに助けてもらうことにしました。
翻訳と音声は java-google-translate-text-to-speech を利用させていただきました。
翻訳は下記 FXMLDocumentController クラスのソースコード 145 行目から 152 行目までのところで処理をしています。
文字を一部置き換えているのはエラーが出るためのその場しのぎの適当な対応です。
それと長文になるとエラーが出ます。
そういう仕様なのかバグなのか、使い方が悪いのかは解りません。(^_^;)
とりあえず的な(使い物にならない)翻訳機を作ったよというお話しでした。
動画とプログラムのコードを貼っておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.text.*?> <?import javafx.geometry.*?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" prefHeight="300.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="jp.yucchi.javafx.google.translater.FXMLDocumentController"> <children> <VBox layoutX="195.0" layoutY="129.0" prefHeight="300.0" prefWidth="800.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> <children> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="200.0"> <children> <Label fx:id="jp" alignment="CENTER" prefHeight="17.0" prefWidth="400.0" text="Japanese"> <HBox.margin> <Insets left="10.0" right="5.0" /> </HBox.margin> <font> <Font size="14.0" /> </font> </Label> <Label fx:id="en" alignment="CENTER" prefHeight="17.0" prefWidth="400.0" text="English"> <HBox.margin> <Insets left="5.0" right="10.0" /> </HBox.margin> <font> <Font size="14.0" /> </font> </Label> </children> </HBox> <HBox prefHeight="250.0" prefWidth="800.0"> <children> <TextArea fx:id="jTextArea" prefHeight="200.0" prefWidth="400.0" wrapText="true"> <padding> <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" /> </padding> <HBox.margin> <Insets left="10.0" right="5.0" top="5.0" /> </HBox.margin> <font> <Font size="18.0" /> </font> </TextArea> <TextArea fx:id="eTextArea" prefHeight="200.0" prefWidth="400.0" wrapText="true"> <padding> <Insets bottom="3.0" left="3.0" right="3.0" top="3.0" /> </padding> <HBox.margin> <Insets left="5.0" right="10.0" top="5.0" /> </HBox.margin> <font> <Font size="18.0" /> </font> </TextArea> </children> </HBox> <HBox alignment="CENTER" prefHeight="50.0" prefWidth="800.0"> <children> <Button fx:id="clearButton" mnemonicParsing="false" onAction="#clearButtonAction" prefHeight="25.0" prefWidth="400.0" text="Clear"> <HBox.margin> <Insets left="10.0" right="5.0" /> </HBox.margin> <font> <Font size="14.0" /> </font> </Button> <Button fx:id="eSpeakButton" mnemonicParsing="false" onAction="#eSpeakButtonAction" prefHeight="25.0" prefWidth="400.0" text="Speak"> <HBox.margin> <Insets left="5.0" right="10.0" /> </HBox.margin> <font> <Font size="14.0" /> </font> </Button> </children> </HBox> </children> </VBox> <ProgressIndicator fx:id="progressIndicator" layoutX="289.0" layoutY="64.0" opacity="0.8" prefHeight="155.0" prefWidth="224.0" /> </children> </AnchorPane> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package jp.yucchi.javafx.google.translater; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Scene; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; /** * * @author Yucchi */ public class JavaFXGoogleTranslater extends Application { @Override public void start(Stage stage) throws Exception { FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml")); loader.load(); AnchorPane root = loader.getRoot(); Scene scene = new Scene(root); FXMLDocumentController controller = loader.getController(); controller.setStage(stage); stage.setResizable(false); stage.setTitle("JavaFX Google Translater"); stage.setScene(scene); stage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
package jp.yucchi.javafx.google.translater; import com.gtranslate.Audio; import com.gtranslate.Language; import com.gtranslate.Translator; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ResourceBundle; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.StringProperty; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ProgressIndicator; import javafx.scene.control.TextArea; import javafx.stage.Stage; import javazoom.jl.decoder.JavaLayerException; /** * * @author Yucchi */ public class FXMLDocumentController implements Initializable { @FXML private Label jp; @FXML private Label en; @FXML private TextArea jTextArea; @FXML private TextArea eTextArea; @FXML private Button clearButton; @FXML private Button eSpeakButton; @FXML private ProgressIndicator progressIndicator; private ExecutorService service; private Task<Void> task; @FXML private void clearButtonAction(ActionEvent event) { jTextArea.setText(""); eTextArea.setText(""); if (!task.isCancelled()) { task.cancel(); } } @FXML private void eSpeakButtonAction(ActionEvent event) { eSpeakButton.setVisible(false); progressIndicator.setVisible(true); task = new Task<Void>() { @Override protected Void call() throws Exception { InputStream sound = null; try { Audio audio = Audio.getInstance(); sound = audio.getAudio(eTextArea.getText(), Language.ENGLISH); audio.play(sound); } catch (IOException | JavaLayerException ex) { Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex); } finally { try { sound.close(); } catch (IOException ex) { Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex); } } return null; } @Override protected void succeeded() { eSpeakButton.setVisible(true); progressIndicator.setVisible(false); } ; @Override protected void cancelled() { eSpeakButton.setVisible(true); progressIndicator.setVisible(false); } @Override protected void failed() { eSpeakButton.setVisible(true); progressIndicator.setVisible(false); } }; service.submit(task); } @Override public void initialize(URL url, ResourceBundle rb) { progressIndicator.setVisible(false); service = Executors.newSingleThreadExecutor(); eSpeakButton.disableProperty() .bind( Bindings.when(eTextArea.textProperty().isEmpty()) .then(true) .otherwise(false)); clearButton.disableProperty() .bind( Bindings.when(jTextArea.textProperty().isEmpty().and(eTextArea.textProperty().isEmpty())) .then(true) .otherwise(false)); jTextArea.textProperty().addListener(observable -> { final String s = ((StringProperty) observable).get(); // エラー出るため適当に置き換え final String _s = s.replaceAll("\\r\\n|\\r|\\n", "").replaceAll("。", ".").replaceAll("、", "").replaceAll("?", "?").replaceAll("!", "!"); Translator translate = Translator.getInstance(); String englishText = translate.translate(_s, Language.JAPANESE, Language.ENGLISH); eTextArea.setText(englishText); }); } void setStage(Stage stage) { stage.setOnCloseRequest(we -> { if (service != null && !service.isShutdown()) { service.shutdownNow(); } Platform.exit(); System.exit(0); }); } } |
これで英語力が上がるとうれしいけど努力しないでってのは完全に無理な話しですね。
JavaFX 楽しい!
TAGS: JavaFX | 2014年12月11日1:23 AM
Comment-
Ransays:
-
Yucchisays:
-
best laptops for collegesays:
-
hdmi cable with rca jackssays:
-
best gaming laptop under 800says:
-
baofeng repeatersays:
2014年12月12日 11:40 AM
good job!
It’s a useful sample.
But,your blog is difficult to understand for me,because I never learned Japanese.so,I can understand the code only.
It’s great if your blog could be write in English.
2014年12月15日 10:26 AM
Thank you.
I just started to study English.
Therefore, my blog is Japanese only.
2014年12月15日 1:11 PM
Laptop computers make great Christmas gifts, but there are
so many to choose from today and often times it can be hard to decide which ones are
the very best. To begin with, the price of the laptops ought to be reasonable because
most from the students do not have access to enough savings
to get one. best laptops for college pc laptops for college Because of this, laptops are now being put in smaller and smaller casing, which enhances the threat of overheating,
as there is less room for air to circulate.
Toshiba Satellite M645- S4055 costs about $1,050 and is considered to be the most
effective choice for gamers. Anyone trying to find a laptop that needs to
last several years would be best served by buying an ASUS or
Toshiba laptop.
2014年12月20日 4:49 PM
And it truely does work well when using either a desktop or laptop computer that
comes with a S-video port. s demands as well as their needs
always are considered and satisfied from the company
by giving them with the appliance that leaves them fully
contented of purchasing the right machine. hdmi cable with rca jacks cable cord best
buy
2015年1月2日 11:03 PM
Such reasons tend to make a long distinct consumers in a very
store that posts cheap laptops available signs for their
windows. This can make it possible to savor games but additionally use the M11x for approximately five hours on battery (your
exact life cycle of battery will depend around the processor you decide on).
Gaming laptop vs regular laptop If you’re looking to the cheaper option, you might need a HP laptop.
To ensure the most beneficial possible and enhanced gaming experience you have to
select high quality Laptops. From my make sure reviews I think
that one of the most dominate make of best gaming laptop under 800 headsets will be the Turtle Beach Ear – Force brand.
2015年1月8日 5:39 PM
The users never got used towards the system of pressing
Up and Down buttons for changeing frequencies or channels, this also model promised to handle this issue.
Actually these modern manufacturers allow those services to meet emerging
the needs in the customers. Baofeng cross mode As the word goes, music can soothe even the most
savage beast.
Finally, hack the computer outside Vera’s room to shut around the speakers.
baofeng repeater uv-5r
ht You obtain the facility of downloading the favorite new music or other applications for upcoming listening.
Everybody inside media understood that time that it is very serious,
not a sort of joke.
Trackback URL