Text
ユーザーがまだフィールドに値を入力していないときにメッセージを表示できるウィジェットが必要でした。コンポジットを拡張し、基本的にテキスト フィールドをその中にラップしました。フォーカスされたメッセージを削除し、フィールドが空の場合にフォーカスが失われたときにメッセージを置き換えるフォーカス リスナーを追加しました。それはすべて期待どおりに機能します。
私が抱えている問題は、プロンプトをテキスト フィールドに配置するときに、プロンプトのスタイルを変更したかったことです。フォントは最初は使用されていないようです。フィールドにフォーカスがあり、フォーカスを失うと、正しく見えます。
たとえば、最初にロードしたときは次のようになります。
そして、これは最初のロードでどのように見えるべきか、そしてフォーカスを持った後と失った後にどのように見えるかです:
単純なシェル内でこれを実行すると、本来の方法で動作するため、少し奇妙になります。Eclipse アプリケーションとして実行すると、スタイルが正しく設定されません。
これが私のコンポジットのコードです:
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
/**
* The <code>PromptingTextInput</code> component is a small enhancement to
* standard <code>Text</code>. It adds the ability to specify a prompt value
* that displays when the text is empty and the field does not have focus.
*/
public class PromptingTextInput extends Composite {
private String prompt;
private Text input;
private boolean textEmpty;
Font emptyFont;
Font inputFont;
public PromptingTextInput(String prompt, Composite parent, int style, boolean passwordField) {
super(parent, style);
this.prompt = prompt;
setLayout(new FillLayout());
this.textEmpty = true;
this.input = new Text(this, (passwordField ? SWT.PASSWORD : SWT.NONE));
setEmptyInputStyle();
this.input.setText(this.prompt);
this.input.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
PromptingTextInput.this.focusGained();
}
public void focusLost(FocusEvent e) {
PromptingTextInput.this.focusLost();
}
});
addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
disposeFonts();
}
});
}
protected void focusGained() {
if (this.textEmpty) {
this.input.setText("");
setInputStyle();
}
}
protected void focusLost() {
if (input.getText() == null || input.getText().trim().length() == 0) {
this.input.setText(this.prompt);
setEmptyInputStyle();
this.textEmpty = true;
} else {
this.textEmpty = false;
}
}
protected void setInputStyle() {
if (this.inputFont == null){
this.inputFont = new Font(Display.getCurrent(), "Verdana", 8, SWT.DEFAULT);
}
this.input.setFont(this.inputFont);
this.input.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
}
protected void setEmptyInputStyle() {
if (this.emptyFont == null){
this.emptyFont = new Font(Display.getCurrent(), "Verdana", 6, SWT.ITALIC);
}
this.input.setFont(this.emptyFont);
this.input.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_GRAY));
}
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
if(!this.input.isFocusControl()){
this.input.setText(this.prompt);
setEmptyInputStyle();
}
}
public Text getInput() {
return input;
}
public boolean isTextEmpty() {
return textEmpty;
}
public String getText() {
return this.input.getText();
}
public void addModifyListener (ModifyListener listener) {
this.input.addModifyListener(listener);
}
public void disposeFonts(){
if (this.inputFont != null){
this.inputFont.dispose();
}
if (this.emptyFont != null){
this.emptyFont.dispose();
}
}
}
更新: Baz が示したように、これは Indigo では問題ではなく、Juno の E4 アプリでのみ問題になるようです。