コントロール その 1
JavaFX シリーズ目次
- JavaFX 2.1のインストール (Windows 編)
- NetBeans で JavaFX (Windows 編)
- JavaFX 2.1 のインストール (Linux 編)
- JavaFX で Hello, World!
- シーングラフ
- コントロール その 1
Swing では GUI で表示するオブジェクトをコンポーネントと呼びますが、JavaFX ではコントロール (正確には UI Controls) と呼びます。
Flex や VB でもコントロールと呼ぶので、違和感はないかもしれません。
どうでもいいですけど、この UI Controls はもともと Caspian というプロジェクトで作られていました。もうほとんど残っていないですが、たまーに caspian という記述が残っていることがあります。
さて、このコントロール、Swing のコンポーネントと同じように使うことができます。
とりあえず、Swing コンポーネントとの対応を見てみましょう。
Swing | JavaFX |
---|---|
JApplet | × |
JButton | Button |
JCheckBox | CheckBox |
JCheckMenuItem | CheckMenuItem |
JColorChooser | × |
JComboBox | ChoiceBox |
JDesktopPane | × |
JDialog | × |
JEditorPane | HTMLEditor |
JFileChooser | FileChooser |
JFormattedTextEditor | × |
JFrame | Stage |
JInternalFrame | × |
JLabel | Label |
JLayer | × (必要なし) |
JLayeredPane | StackPane |
JList | ListView |
JMenu | Menu |
JMenuBar | MenuBar |
JMenuItem | MenuItem |
JOptionPane | × |
JPanel | Pane |
JPasswordField | PasswordField |
JPopupMenu | ContextMenu |
JProgressBar | ProgressBar |
JRadioButton | RadioButton |
JRadioButtonMenuItem | RadioMenuItem |
JRootPane | Scene |
JScrollPane | ScrollPane |
JSeparator | Separator |
JSlider | Slider |
JSpinner | × |
JSplitPane | SplitPane |
JTabbedPane | TabPane |
JTable | TableView |
JTextArea | TextArea |
JTextField | TextField |
JTextPane | × (HTMLEditor) |
JToggleButton | ToggleButton |
JToolBar | ToolBar |
JToolTip | Tooltip |
JTree | TreeView |
JViewport | × |
JWindow | Window |
× | Accordion |
× | CustomMenu |
× | Hyperlink |
× | MenuButton |
× | ProgressIndicator |
× | SplitMenuButton |
× | TitledPane |
ほとんどの Swing コンポーネントに対応したコントロールがあるのですが、ダイアログ系がないのがイタイですね。
いちおう、Stage をダイアログの代わりにすることができるのですが...
ちなみに FileChooser はありますが、厳密にいうとコントロールではなく、Stage と同列になっています。
Swing にはないコントロールとして、Accordion や Hyperlink、ProgressIndicator などがあります。
Accordion は Flex などでよく使われる上下に開くタイプのコンテナ (?) です。ProgressIndicator は処理待ちの時に円形にグルグル回るコントロールです。
では、実際に主なコントロールを使ってみましょう。
その前に、以下で使用するコードはすべて次のテンプレートで書いてます。
import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.FlowPane; import javafx.stage.Stage; public class Test extends Application { @Override public void start(Stage stage) { stage.setTitle("Control Demo"); FlowPane root = new FlowPane(); root.setHgap(10); root.setLayoutX(20); root.setLayoutY(20); Scene scene = new Scene(root, 400, 200); stage.setScene(scene); /* ここにコントロールのコードを記入します */ stage.show(); } public static void main(String[] args) { launch(args); } }
コメントのところに、コードを書いてみてください。
コントロールの大きさによってステージのサイズも変化させているので、そこら辺は適当にやってくださいww
Label
ラベルは使用頻度では一番多いかもしれないですね。文字列を表示するコントロールです。
javafx.scene.text.Text というクラスもあるのですが、こちらは本当に文字列だけです。それに対し、Label クラスはアイコンも使用することができます。
まずは単純な文字列。
Label label = new Label("Label"); root.getChildren().add(label);
ラベルで表示している文字列の取得は getText メソッド、文字列の設定は setText メソッドでできます。
では、次にアイコンをつけてみましょう。
Swing ではアイコンは Icon クラスで表していましたが、JavaFX では Node クラスです。なので、何でもありです。
Label label1 = new Label("Label 1", new Rectangle(2, 2, 6, 6)); root.getChildren().add(label1); Label label2 = new Label("Label 2", new ImageView(new Image("src/bullet.png"))); root.getChildren().add(label2);
アイコンはコンストラクタの第 2 引数で指定します。後から指定するには、setGraphic メソッドを使用します。ここでは、アイコンとして四角と、イメージをロードして使用しました。
Button
使用頻度ではボタンも多いですね。Button クラスは JButton クラスとほとんど使い方は同じです。
まずは、テキストだけのボタンです。
Button button = new Button("Button"); button.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { System.out.println("Button is clicked."); } }); root.getChildren().add(button);
ボタンに表示するテキストは setText メソッドでも設定できます。
イベントについては、また別の機会に詳しく書こうと思っていますが、Swing のようにイベントの種類ごとにリスナがあるのではなく、すべて EventHandler クラスで扱います。イベントの種類はジェネリクスで指定します。
これを実行すると、下図のようになります。
次にアイコンつきのボタンです。
Button クラスのアイコンも Node クラスです。なので、何でもありです。
Button button1 = new Button("Button1", new Rectangle(2, 2, 6, 6)); root.getChildren().add(button1); Button button2 = new Button("Button2", new ImageView(new Image("src/bullet.png"))); root.getChildren().add(button2); Button button3 = new Button("Button3", new RadioButton("RadioButton")); root.getChildren().add(button3);
ここでは、ボタンを 3 つ並べています。四角とイメージは Label の時と同じです。最後は、ボタンの中にラジオボタンが入ります。
こんなんでもありなのです。
実行すると、こうなります。
なんか不思議な感じですよね。でも、ちゃんと動作します。ラジオボタンもちゃんとチェックできます。
TextField
続いて、TextField です。
Swing の JTextField クラスだとコンストラクタにはカラム数を指定しますが、TextField クラスでは setPrefColumnCount メソッドで指定します。
TextField field = new TextField("TextField"); field.setPrefColumnCount(20); root.getChildren().add(field);
実行してみましょう。
TextField に入力された文字列を取得するには、getText メソッドを使用します。
ちなみに、JavaFX はまだフォント周りのバグが結構残っていて、JavaFX 2.0 だと日本語を入力するとカーソルがずれるというバグがあります。
Windows 版の JavaFX 2.1 だと直っているのですが、Linux 版はまだバグったままです。
Linux 版で日本語を入力するとこうなります。
Linux 版の品質はまだまだといったところでしょう。
さて、3 つのコントロールができたので、3 つを組み合わせてみましょう。
ボタンをクリックしたら、テキストフィールドに入力した文字列をラベルにセットするというサンプルです。
import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.TextField; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class ControlsDemo extends Application { private TextField field; private Label label; @Override public void start(Stage stage) { stage.setTitle("Control Demo"); VBox root = new VBox(10); root.setAlignment(Pos.CENTER); Scene scene = new Scene(root, 340, 120); stage.setScene(scene); HBox hbox = new HBox(10); hbox.setAlignment(Pos.CENTER); root.getChildren().add(hbox); field = new TextField(); field.setPrefColumnCount(20); hbox.getChildren().add(field); Button button = new Button("Update"); button.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { // テキストフィールドの文字列をラベルにセットする String text = field.getText(); label.setText(text); } }); hbox.getChildren().add(button); label = new Label(); root.getChildren().add(label); // ステージの表示 stage.show(); } public static void main(String[] args) { launch(args); } }
レイアウトの部分はあまり見ないでおいて、コントロールの部分だけ見てください。
ボタンがクリックされたら、TextField.getText メソッドで文字列を取得し、Label.setText でセットしているだけです。
実行すると...
テキストフィールドに入力して、ボタンをクリックします。
次回はまた違うコントロールを使ってみましょう。