プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

Graphicを設定したRadioButtonをSkinで使うと表示がおかしくなる

 ControlのSkinにRadioButtonを使う。RadioButtonには画像も表示させたい………。そんなに特別な場面ではないだろう。ところが、おそらくJavaFX8のバグと思われる妙な挙動をしたので、ここで報告しておく。すでにバグとして登録されているかはよく知らない。

 問題となるソースコードは次のようなもの。基本的には、TilePaneを拡張し、子要素に二つのRadioButtonを並べたSkin2というクラスを4つ表示しているだけだ。
 ただし、この二つのRadioButtonには、GraphicとしてAというラベルとBというラベルを設定している。

//import は略
public class Test extends Application{

  @Override
  public void start(final Stage stage) throws Exception{
    //-fx-skinでSkin2をskinに指定
    final Control2 c2 = new Control2();
    //createDefaultSkinでskinを指定
    final Control3 c3 = new Control3();
    //直接Skin2を表示
    final Skin2 s = new Skin2(null);
    //もう一回表示
    final Control2 c22 = new Control2();

    final VBox v = new VBox();
    v.setPadding(new Insets(50));
    v.getChildren().addAll(c2,c3,s,c22);
    stage.setScene(new Scene(v));
    stage.show();
  }

  public static class Control2 extends Control{
    public Control2(){
      setStyle("-fx-skin:'"+Skin2.class.getName()+"'");
    }
  }

  public static class Control3 extends Control{
    @Override
    protected Skin<?> createDefaultSkin(){
      return new Skin2(this);
    }
  }

  public static class Skin2 extends TilePane implements Skin<Control>{
    Control c ;
    public Skin2(final Control c){
      this.c = c;
      final RadioButton
      r1 = new RadioButton("a"),
      r2 = new RadioButton("b");
      r1.setGraphic(new Label("A"));
      r2.setGraphic(new Label("B"));
      getChildren().addAll(r1,r2);
      r1.setSelected(true);
    }

    @Override
    public Control getSkinnable(){return c;}
    @Override
    public Node getNode(){return this;}
    @Override
    public void dispose(){}
  }

  public static void main(final String[] args){launch(args);}
}

これを実行すると次のようになる。
f:id:nodamushi:20150302185844p:plain

最初と最後が明らかにおかしい。ボタンはないし、●は変なところに表示されているし、aと表示されていない。しかし、二つ目の「○B b」は正しく表示されている。

Skinで表示すると問題なのかと思ったが、createDefaultSkinを用いると、あら不思議、二列目のように正しく表示されている。ということは、リフレクション関連のバグ?

というわけで、どーいうことなんですかねぇ、これ。