0

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 アプリでのみ問題になるようです。

4

2 に答える 2

1

sambiの回答に基づいて、次の作業が行われました。多分これはJunoで動作します:

private static Font italic;

public static void main(String[] args) {
    final Display display = new Display();
    Shell shell = new Shell(display);
    shell.setLayout(new GridLayout(1,false));

    italic = new Font(Display.getCurrent(), "Verdana", 6, SWT.ITALIC);

    final Text text = new Text(shell, SWT.BORDER);

    text.addListener(SWT.Paint, new Listener() {

        @Override
        public void handleEvent(Event event) {

            if(text.getText().length() < 1 && !text.isFocusControl())
            {
                GC gc = event.gc;
                gc.setFont(italic);
                gc.setForeground(display.getSystemColor(SWT.COLOR_GRAY));

                Point size = text.computeSize(SWT.DEFAULT, SWT.DEFAULT);

                /* Strangely the y positioning doesn't work correctly */
                //gc.drawText("Please enter text", 1, (size.y / 2) - (italic.getFontData()[0].getHeight() / 2));
                gc.drawText("Please enter text", 1, 4);
            }
        }
    });

    text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true));

    Button button = new Button(shell, SWT.PUSH);
    button.setText("Dummy");

    button.forceFocus();

    shell.setSize(200, 100);
    shell.open();

    while (!shell.isDisposed()) {
        if (!display.readAndDispatch())
            display.sleep();
    }
    italic.dispose();
    display.dispose();
}

フォーカスと空のテキストなし:

ここに画像の説明を入力

フォーカスまたはテキストあり:

ここに画像の説明を入力

于 2012-10-04T14:29:50.930 に答える
1

を使用できますText.setMessage (String message)。これの問題は、フォントサイズや前景などをあまりカスタマイズできないことです。

それをカスタマイズするために、実際に の範囲内でメッセージを描画できますText

于 2012-10-04T16:42:23.490 に答える