ScalaSwingを使ってみた
めでたく、2.7.2.finalもリリースされたことなので、
ScalaSwingを使ってみた。
サンプルを参考に
任意のファイルを、指定して何らかの処理をするツールのGUI部分だけを書き直した。
import java.io._ import swing._ import swing.event._ import javax.swing._ object SsConverterGUI extends SimpleGUIApplication { // ---------------------------------------------------- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName) val chooser = new FileChooser(new File(".")) // ---------------------------------------------------- object fileSelectBtn extends Button { text = "ファイル選択" } object goBtn extends Button { text = "実行" } // ---------------------------------------------------- object textfield extends TextField { columns = 30 text = DefaultFile listenTo(fileSelectBtn) reactions += { case ButtonClicked(button) if (button == fileSelectBtn) => chooser.showOpenDialog(new GridBagPanel) match { case FileChooser.Result.Approve => text = chooser.selectedFile.getPath case FileChooser.Result.Cancel => println("Canceled") case FileChooser.Result.Error => println("UNKNOWN Error") } } listenTo(goBtn) reactions += { case ButtonClicked(button) if (button == goBtn) => try { SsConverter.go(text) Dialog.showMessage(button, "完了しました。") } catch { case e:FileNotFoundException if e.getMessage.matches(".*Permission denied.*") => Dialog.showMessage(button,"ファイルへの書き込み権限がありません\n" + e.getMessage) case e:FileNotFoundException if e.getMessage.matches(".*No such file or directory.*") => Dialog.showMessage(button,"ファイルが見つかりません\n" + e.getMessage) case e => val st = e.getStackTrace Dialog.showMessage(button, e.getMessage) throw(e) } } } // ---------------------------------------------------- val DefaultFile = "input/input.xls" // ---------------------------------------------------- def top = new MainFrame { title = "SsConverter v1.0" minimumSize = new java.awt.Dimension(400, 100) contents = new BoxPanel(Orientation.Vertical) { contents.append(new FlowPanel{ contents.append(textfield, fileSelectBtn)}) contents.append(new BorderPanel{add(goBtn, BorderPanel.Position.Center) }) border = Swing.EmptyBorder(5, 5, 5, 5) } } }
このようになった。
と、ここでふとNetBean6.1をつかってGUIのデザインを出来ないかと考えてみた。
で、やってみたら・・・
import java.io._ import swing._ import swing.event._ import javax.swing._ object SsConverterGUI2 extends SimpleGUIApplication { // ---------------------------------------------------- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName) val chooser = new FileChooser(new File(".")) // ---------------------------------------------------- object fileSelectBtn extends Button { text = "ファイル選択" } object goBtn extends Button { text = "実行" } // ---------------------------------------------------- object textfield extends TextField { columns = 30 text = DefaultFile listenTo(fileSelectBtn) reactions += { case ButtonClicked(button) if (button == fileSelectBtn) => chooser.showOpenDialog(new GridBagPanel) match { case FileChooser.Result.Approve => text = chooser.selectedFile.getPath case FileChooser.Result.Cancel => println("Canceled") case FileChooser.Result.Error => println("UNKNOWN Error") } } listenTo(goBtn) reactions += { case ButtonClicked(button) if (button == goBtn) => try { SsConverter.go(text) Dialog.showMessage(button, "完了しました。") } catch { case e:FileNotFoundException if e.getMessage.matches(".*Permission denied.*") => Dialog.showMessage(button,"ファイルへの書き込み権限がありません\n" + e.getMessage) case e:FileNotFoundException if e.getMessage.matches(".*No such file or directory.*") => Dialog.showMessage(button,"ファイルが見つかりません\n" + e.getMessage) case e => val st = e.getStackTrace Dialog.showMessage(button, e.getMessage) throw(e) } } } // ---------------------------------------------------- val DefaultFile = "input/input.xls" // ---------------------------------------------------- def top = new MainFrame { title = "SsConverter v1.0b" minimumSize = new java.awt.Dimension(400, 100) //----------------------------------------------------- // Map Objects val jTextField1 = textfield.peer val jButton1 = fileSelectBtn.peer val jButton2 = goBtn.peer //----------------------------------------------------- // Initialize import java.lang.Short val layout = new GroupLayout(peer.getContentPane); peer.getContentPane.setLayout(layout); //----------------------------------------------------- // Paste Generated Code // layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 305, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 101, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jButton2, javax.swing.GroupLayout.DEFAULT_SIZE, 413, Short.MAX_VALUE)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jButton1)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton2) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); //----------------------------------------------------- pack(); } }
と、こんな感じになった。
- 前半部分は一切手を入れなくて大丈夫だった、
- peerをつかって、Javaのオブジェクトを取り出すのがポイント
やっぱりScalaとJavaは相性がいい。(^^
こっちのほうは、リサイズしたときの挙動が美しくてうれしい。(^o^
しかも
- Paste Generated Codeの部分はNetBeanの生成したコードそのままなので修正があっても楽!
ただ、NetBean上のGUIエディタで現在のウィンドウのたてのサイズがうまく取得できなかった(というか取得の方法がわからなかった)ので、最小サイズは目分量なのが心残り・・・