第4章 JavaFX による GUI プログラミング : 問題 7 : CSS
問題
CSS を使用しないで、コントロールの境界を設定する方法を調べよ
境界について
“境界” というのは、下の図(CSS Box Model)の Border だよね
CSS はNode
クラスに適用できるが、Border プロパティを持っているのはNode
の派生クラスのRegion
である
Border のプロパティは、基本的に四辺独立に指定できる
- プロパティ値をひとつだけ書いたときは、全ての辺にセットされる
- プロパティ値を四つ並べて書くと top, right, bottom, left の順にセットされる
- プロパティ値を二個または三個並べたとき、値は循環し top, right, bottom, left の順にセットされる
Border は、直線の境界(Stroke Border)と画像境界(Image Border)に分かれる
■ 直線の境界(Stroke Border)
プロパティ | キーワード | 値 | 備考 |
---|---|---|---|
色 | -fx-border-color |
色 線形グラデーション 円形グラデーション 画像 |
|
スタイル | -fx-border-style |
※ 下記参照 | |
太さ | -fx-border-width |
絶対サイズ(point, cm など) 相対サイズ(pixel, em など) ノード相対 |
|
角の半径 | -fx-border-radius |
同上 | X/Y方向個別に指定可 |
マージン | -fx-border-insets |
同上 |
※ 直線スタイル
属性 | 必須 | キーワード | 値 | 備考 |
---|---|---|---|---|
線種 | ○ | solid(実線) dotted(点線) dashed(破線) none(なし) segments 数値... |
segments はいわゆるユーザー定義 | |
フェーズ | × | phase | 数値 | 意味不明 |
線の位置 | × | centered(中央) inside(内側) outside(外側) |
||
角の形状 | × | line-join | miter 数値 bevel(直角) round(丸め) |
miter はある値を境に直角になる |
端の形状 | × | line-cap | square(突出) butt round(丸め) |
butt は四角だが突出しない |
■ 画像境界(Image Border)
プロパティ | キーワード | 値 | 備考 |
---|---|---|---|
画像ファイル | -fx-border-image-source |
URL | Jar ファイル相対も可 |
画像の繰り返し | -fx-border-image-repeat |
repeat(拡大なし) space(整数倍、拡大なし) round(整数倍、拡大) no-repeat(拡大) |
X/Y方向個別に指定可 repeat no-repeat は repeat-x と no-repeat repeat は repeat-y と 記述できる |
角のサイズ | -fx-border-image-slice |
絶対サイズ(point, cm など) 相対サイズ(pixel, em など) ノード相対 |
|
太さ | -fx-border-image-width |
同上 | |
マージン | -fx-border-image-insets |
同上 |
なんと、これだけのプロパティが指定できるんですな~
解答
Region
クラスのsetBorder(Border)
メソッドを呼び出す
Border
クラスのコンストラクタにはBorderStroke
オブジェクトを引数にするものとBorderImage
オブジェクトを引数にするものがあり、CSS の Stroke Border と Image Border に相当する
ただし、setBorder(Border)
メソッドでは CSS と同等のスタイルは指定できない
では、実際に境界を描いてみよう
ちなみに画像境界で使用する画像はこれ
■ CSS バージョン
public void start(Stage stage) throws Exception { // デフォルトの外観のテキストフィールド TextField defaultField = new TextField("デフォルトの外観"); // 直線の枠線を持つテキストフィールド TextField strokeField = new TextField("Stroke Border"); // 画像枠線を持つテキストフィールド TextField imageField = new TextField("Image Border"); strokeField.setStyle( "-fx-pref-height: 4.0em;" + "-fx-border-color: blue green red darkOliveGreen;" + "-fx-border-style: solid dotted dashed solid;" + "-fx-border-radius: 0.5em 2.0em 0.5em 2.5em;" + "-fx-border-width: 1.0px 2.0px 3.0px 4.0px;" + "-fx-border-insets: 0.5em;" ); imageField.setStyle( "-fx-pref-width: 12.0em;" + "-fx-pref-height: 5.0em;" + "-fx-border-image-source: url(border.png);" + "-fx-border-image-repeat: round no-repeat;" + "-fx-border-image-slice: 27.0px;" + "-fx-border-image-width: 9.0px;" + "-fx-border-image-insets: 0.5em;" ); VBox root = new VBox(); root.getChildren().addAll(defaultField, strokeField, imageField); stage.setScene(new Scene(root)); stage.show(); }
■ setBorder
バージョン
public void start(Stage stage) throws Exception { // デフォルトの外観のテキストフィールド TextField defaultField = new TextField("デフォルトの外観"); // 直線の枠線を持つテキストフィールド TextField strokeField = new TextField("Stroke Border"); // 画像枠線を持つテキストフィールド TextField imageField = new TextField("Image Border"); final double em = new Text("").getLayoutBounds().getHeight(); strokeField.setPrefHeight(4.0*em); strokeField.setBorder( new Border( new BorderStroke( // top, right, bottom, left Color.BLUE, Color.GREEN, Color.RED, Color.DARKOLIVEGREEN, BorderStrokeStyle.SOLID, BorderStrokeStyle.DOTTED, BorderStrokeStyle.DASHED, BorderStrokeStyle.SOLID, new CornerRadii(0.5*em, 2.0*em, 0.5*em, 2.5*em, false), new BorderWidths(1.0, 2.0, 3.0, 4.0), new Insets(0.5*em) ) ) ); imageField.setPrefWidth(12.0*em); imageField.setPrefHeight(5.0*em); imageField.setBorder( new Border( new BorderImage( new Image("border.png"), new BorderWidths(9.0), new Insets(0.5*em), new BorderWidths(27.0), true, BorderRepeat.ROUND, BorderRepeat.STRETCH ) ) ); VBox root = new VBox(); root.getChildren().addAll(defaultField, strokeField, imageField); stage.setScene(new Scene(root)); stage.show(); }