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 でセットしているだけです。
実行すると...
テキストフィールドに入力して、ボタンをクリックします。
次回はまた違うコントロールを使ってみましょう。








