2

まず、タイトルは同じですが、これはこの質問の重複ではありません。その質問は、本質的に C 関数と同じメソッドを渡すことについて言及していました。特定のオブジェクトに属する必要はありませんでした。その場合、RunnableorCallableオブジェクトを渡すことができます。

代わりに、私は次のことを尋ねています: クラス内の特定のメソッドへの参照を渡し、そのメソッドを特定のオブジェクトに対して呼び出すことは可能ですか?

FlowLayout例として、 Swingの のコードを見ていて、preferredLayoutSizeとのminimumLayoutSize実装が 1 行を除いてまったく同じであることに気付きました。

public Dimension preferredLayoutSize(Container target) {
  synchronized (target.getTreeLock()) {
    Dimension dim = new Dimension(0, 0);
    int nmembers = target.getComponentCount();
    boolean firstVisibleComponent = true;
    boolean useBaseline = getAlignOnBaseline();
    int maxAscent = 0;
    int maxDescent = 0;

    for (int i = 0 ; i < nmembers ; i++) {
        Component m = target.getComponent(i);
        if (m.isVisible()) {
            Dimension d = m.getPreferredSize();
            dim.height = Math.max(dim.height, d.height);
            if (firstVisibleComponent) {
                firstVisibleComponent = false;
            } else {
                dim.width += hgap;
            }
            dim.width += d.width;
            if (useBaseline) {
                int baseline = m.getBaseline(d.width, d.height);
                if (baseline >= 0) {
                    maxAscent = Math.max(maxAscent, baseline);
                    maxDescent = Math.max(maxDescent, d.height - baseline);
                }
            }
        }
    }
    if (useBaseline) {
        dim.height = Math.max(maxAscent + maxDescent, dim.height);
    }
    Insets insets = target.getInsets();
    dim.width += insets.left + insets.right + hgap*2;
    dim.height += insets.top + insets.bottom + vgap*2;
    return dim;
  }
}

public Dimension minimumLayoutSize(Container target) {
  synchronized (target.getTreeLock()) {
    boolean useBaseline = getAlignOnBaseline();
    Dimension dim = new Dimension(0, 0);
    int nmembers = target.getComponentCount();
    int maxAscent = 0;
    int maxDescent = 0;
    boolean firstVisibleComponent = true;

    for (int i = 0 ; i < nmembers ; i++) {
        Component m = target.getComponent(i);
        if (m.visible) {
            Dimension d = m.getMinimumSize();
            dim.height = Math.max(dim.height, d.height);
            if (firstVisibleComponent) {
                firstVisibleComponent = false;
            } else {
                dim.width += hgap;
            }
            dim.width += d.width;
            if (useBaseline) {
                int baseline = m.getBaseline(d.width, d.height);
                if (baseline >= 0) {
                    maxAscent = Math.max(maxAscent, baseline);
                    maxDescent = Math.max(maxDescent,
                                          dim.height - baseline);
                }
            }
        }
    }

    if (useBaseline) {
        dim.height = Math.max(maxAscent + maxDescent, dim.height);
    }

    Insets insets = target.getInsets();
    dim.width += insets.left + insets.right + hgap*2;
    dim.height += insets.top + insets.bottom + vgap*2;
    return dim;
  }
}

メソッドは( -番目のコンポーネント)のメソッドをpreferredLayoutSize呼び出しますが、 のメソッドを呼び出します。私が見る限り、2 つの方法はそれ以外は同じです。 preferredLayoutSizemiminimumLayoutSizeminimumLayoutSizem

プログラマなら誰でも言うように、コードの重複は悪いことです。ただし、この場合、重複したコードを取り除く方法は明らかではありません。クラスのpreferredLayoutSizeおよびminimumLayoutSizeメソッドへの参照を渡し、両方のパブリック メソッドが呼び出すコードを含むプライベート メソッドが必要であることは明らかです。ComponentCI では、関数ポインターを使用してそれを行うことができるため、Java でそれを行う何らかの方法が必要であることは理にかなっています。Runnableorを渡すとCallableほとんど機能しますが、どちらも値を返しません。 編集:これは間違っています。のオーバーライドされたメソッドはCallable を返し、それが作用するオブジェクトはパラメーターとして渡すことができます。

すべてを入力したので、解決策が思い浮かびます。interfaceと呼ばれるメソッドを使用してDimension layoutSize(Component comp)を記述し、2 つの実装を記述することができます。一方は を返しcomp.preferredLayoutSize()、もう一方は を返しcomp.minimumLayoutSize()ます。次に、そのインターフェイスのインスタンスをパラメーターとして取るプライベート メソッドを記述し、それを使用して、コードの適切なポイントで個別のメソッドを実行できます。匿名の内部クラスを使用することもできるため、レイアウト サイズの種類ごとに新しいクラスを作成する必要はありません。ただし、かなり単純な問題の場合は、依然として非常に多くの問題のように思えます。もっと簡単な方法はありますか?

4

3 に答える 3

2

メソッドの 1 つをクラス (おそらくローカル クラス) でラップLayoutSizingし、計算用の抽象メソッドを onmで、mパラメーターとして使用してから、両方new LayoutSizing() { @Override ... }のメソッドで実装されたメソッドでインスタンス化できます。

Java 8 では、これが少し見栄えが良くなることを願っています。

于 2013-09-18T14:50:36.813 に答える