6

私は SWT/JFace テクノロジーにかなり慣れていないので、頭がおかしくなるという問題を発見しました。Eclipse RCP アプリケーションには、ラベル プロバイダーによってラベルとアイコンを提供する JFace TreeViewer を使用して SWT ツリーを配置したビューがあります。顧客の要求により、ツリーの背景色は濃い青、フォントの色は白です。この色の組み合わせにより、ノードが選択されたときにノードのテキストがうまく表示されず、テキストがツリー領域に収まらず、ノード上にマウス ポインターを置いたときに表示されなくなります。どういうわけか「ネイティブのハイライト」が表示されます。これは、次の図に示すことができます。

ここに画像の説明を入力

一方、マウスを置いたノードが選択されていない場合、この問題は発生しません。強調表示すると、フォントの色が変わり、見やすくなります。これは、次の図に示すことができます。

ここに画像の説明を入力

いくつかの調査を行った後、イベントのリスナーを追加することで、選択したノードの背景色を変更してから選択を無効にできることがわかりました。SWT.EraseItemこれにより、独自の選択背景スタイルを定義し、ノードが選択されていないときに OS を強制的に強調表示するためにのSWT.SELECTEDフラグを無効にすることもできます。event.detail

private final class EraseItemListener implements Listener {

    public void handleEvent(Event event) {
        // Only perform the node highlight when it is selected.
        if ((event.detail & SWT.SELECTED) == SWT.SELECTED) {
            // Modify background, emulate Windows highlighting.

            ...

            // Set Windows that we do not want to draw this item as a selection (we have already highlighted the item in our way).
            event.detail &= ~SWT.SELECTED;
        }
    }
}

この「解決策」は合理的です。主な欠点は、私の選択スタイルが Windows 7 の既定のビジュアル テーマにしか適合しないことです。これらの「Windows クラシック」または「ハイ コントラスト」では、視覚化の問題が発生します。さらに (そしてこれが最も厄介な問題です)、SWT.EraseItem(イベントを処理するコードがなくても) のリスナーを追加すると、2 つの新しい問題が発生します。

  1. これにより、次の図に示すように、SWT または JFace のいずれかがツリー ノードのアイコンを間違った場所に描画します。

    ここに画像の説明を入力

  2. ツリーのルート ノードのハイライトは完全に間違っています。次の画像でわかるように、ノードは 2 つの異なる方法で強調表示され、アイコンが繰り返されているように見えます。

    ここに画像の説明を入力

私の質問は基本的に2つです。

  1. 主な問題に対するより簡単な解決策があると思いますか? 私が望むのは、選択したノード(最初の画像のノード)を2番目の画像と同じ方法で表示することです。選択したノードの前景色を変更して見やすくしたいと考えています。

  2. このアプローチを使用する場合SWT.EraseItem、アイコンを正しい場所に表示する方法はありますか? この動作は既知のバグですか?

前もって感謝します。

4

2 に答える 2

2

に基づくラベル プロバイダStyledCellLabelProvider(おそらく に基づくもの) を使用する場合、選択時に通常の色を保持するようにDelegatingStyledCellLabelProvider指定できます。COLORS_ON_SELECTION

それが十分でない場合 (テストする Windows がここにない場合)、paintメソッドをオーバーライドできます -event.detail &= ~SWT.SELECTED通常の選択処理を抑制したり、自分でペイントを処理したりするために使用することもできます。

于 2014-01-22T10:04:52.940 に答える
0

この古い投稿に偶然出くわし、最近 eclipse で開いたバグと一致することに気付きました。

テキストを正しい色にするための私の回避策は、PaintListener(ツリーに登録されているSWT.PaintItem)を使用して、テキストを別の色でペイントすることでした:

private static class TreePaintListener implements Listener {
    @Override
    public void handleEvent(Event event) {
        boolean isSelected = (event.detail & SWT.SELECTED) != 0;
        if (isSelected && event.item instanceof TreeItem) {         
            TreeItem treeItem = (TreeItem) event.item;
            Tree parent = treeItem.getParent();


            GC gc = event.gc;
            Color foreground = null/* Some Color */;
            gc.setForeground(foreground);

            Rectangle imageBounds = treeItem.getImageBounds(0);
            Rectangle textBounds = treeItem.getTextBounds(0);
            Point stringExtent = gc.stringExtent(treeItem.getText());

            int offsetX = imageBounds.width != 0 ? imageBounds.height - imageBounds.width : 0;
            int offsetY = (textBounds.height - stringExtent.y) / 2;

            int x = textBounds.x + offsetX;
            int y = textBounds.y + offsetY;

            if (gc.getClipping().contains(x, y)) {
                gc.drawString(treeItem.getText(), x, y);
            }
        }
    }
}

ただし、複数の列が定義されている場合 (最初の列のみが塗りつぶされている場合) は依然として誤動作し、オペレーティング システムと DPI によっては、計算が少しずれている可能性があります。

于 2019-05-31T08:46:28.270 に答える