Tooltipに関するエトセトラ
ToolTipに設定した文字列って自動改行されずに困っていました。長い文字列を入れるとてろてろ〜んと画面をぶち抜いてどこへやら…。となるでしょう。でもデフォルトの実装に期待しちゃいけないのがEclipseWayだということに最近気づいてきました。
デフォルトで提供されるToolTipクラスはorg.eclipse.jface.window.DefaultToolTipクラスです。ToolTip#createToolTipContentArea(Event,Composite)というメソッドで内部のWidgetが作成されます。引数のCompositeはデフォルトではSWT.Toolがスタイルに指定されたShellが渡ってきます。このShellのLayoutはFillLayoutが指定されています。僕はFillLayoutが指定されている場合、内部Widgetのサイズを指定する術を知りません。*1なので大抵の場合はGridLayoutをLayoutに指定したCompositeでラップします。ラップしたCompositeを使ってWidgetにGridDataを指定してサイズのhintを与えるようにしてます。
デフォルト実装ではToolTipを表示するWidgetとしてorg.eclipse.swt.CLabelクラスを使用しています。CLabelクラスはLabelのカスタムクラスと思いきや、中を見てみるとCanvasクラスを継承したクラスで、Widgetと言うよりは特殊な警告などを表示するようの画面描画用のWidgetです。CLabelにGridDataを使ってhintを与えても画面描画用のWidgetなので途中で三点リーダ(…)が表示されるだけでうまく改行してくれません。
そんな感じなので、createToolTipContentArea(Event,Composite)をこんな風に実装しました。
@Override protected Composite createToolTipContentArea(Event event, Composite parent) { Image image = getImage(event); Image bgImage = getBackgroundImage(event); String text = getText(event); Color fgColor = getForegroundColor(event); Color bgColor = getBackgroundColor(event); Font font = getFont(event); Composite comp = new Composite(parent,SWT.NONE); GridLayoutFactory.fillDefaults().applyTo(comp); Label label = new Label(comp,SWT.WRAP); text = text != null ? text.trim() : null; label.setText(text); if(fgColor != null){ label.setForeground(fgColor); } if(bgColor != null){ label.setBackground(bgColor); } if(image != null){ label.setImage(image); } if(bgImage != null){ label.setBackgroundImage(bgImage); } int width = 400; int height = 80; if(font != null){ label.setFont(font); GC gc = new GC(Display.getDefault()); gc.setFont(font); height = gc.getFontMetrics().getHeight() * 8; gc.dispose(); } GridDataFactory.fillDefaults().hint(width,height).applyTo(label); return comp;
FontMetricsを使って、8行分表示させてます。幅の文字数を指定していないのは、等幅フォントを使っているとは限らないためです。
今日もニッチなネタでせめてみました。
*1:より良い方法が分かり次第またBlogを書きます