4

私には 2 種類の編集者がいます。1 つは のサブクラスでJTextAreaあり、もう 1 つはJTable(のサブクラスでJTextAreaありJTable、両方とも ) のサブクラスですJComponent。2 つのクラスが必要でTextAreaEditor、メソッドだけを持つTableEditorinterface を実装します。Editorpublic String getText()

クライアント コードで単純にEditorインターフェイスを使用するようにします。問題は、私のすべてがのようなEditorメソッドを使用していることです。私のエディタはインターフェースであり、JComponent を拡張することはできないため、これらのメソッドを呼び出すときは、インターフェースの代わりに実装を使用する必要があります。そこで、インターフェイスを使用する代わりに、単にサブクラスを作成し、それをクラスに拡張させることができると考えました。問題は、のようなクラスがすでに のようなクラスを拡張しているため、別のクラスを拡張させることはできません。JComponentsetEnabled(bool)EditorJComponentTextAreaEditorJTextArea

Editorクラスが JComponent であること、および具象エディタ クラスがEditorの およびサブクラスであることを確認する方法はありJComponentますか?

4

6 に答える 6

4

関心のある JComponent メソッドをエディタ インターフェイスのサブクラスで公開すると、クラスによって「さかのぼって」実装されます。

アイデアを示すコードを次に示します。

interface Editor { 
  String getText(); 
}

interface SwingEditor extends Editor { 
  void setEnabled(bool); // has to match *exactly* the signature from JComponent
}

class TableEditor extends JTable implements SwingEditor {
   // implement your getText(), and anything else you need 
   // no need to implement setEnabled, as it is provided by JTable
}

SwingEditor te = new TableEditor();
te.setEnabled(true); // will call JComponent's method

ここでは継承が本当に必要だと思います。一般に、多くの場合、Swing UI コードにはコンポジションの方が適しています。

于 2012-07-23T03:24:02.343 に答える
3

継承よりも構成を使用します。ほとんどの場合、継承は実際には適切な解決策ではありません。あなたの場合、継承によってかなりのコードを書く必要がなくなります。

あなたTextAreaEditorTableEditor両方にJComponent彼らが必要とするインスタンスを持ってもらいます。必要なすべてのメソッドをインターフェースに追加してから、それらの呼び出しをに委任しますJComponet

例えば:

public class TextAreaEditor implements Editor {
     private final JTextArea textArea = new JTextArea();

     public void setEnabled(bool isEnabled) {
          return textArea.setEnabled(isEnabled);
     }

     //... your own methods plus other methods from JComponent
}

もう少し凝ったものを取得し、ある種の依存性注入を使用してインスタンス化することもできますがJComponent、それは実際には必要ありません。ただし、すべての変更が特定のJComponent注入に必要な場合は、クラスを作成する必要があるという問題を解決できます。

さらに明確にする必要がある場合はお知らせください。

于 2012-07-23T03:17:41.940 に答える
2

Editor本当にクラスを にする必要がある場合はJComponent、単にこれを文書化し、コードでキャストを実行することを選択できます。最もきちんとした解決策ではありませんが、はるかに簡単です。

Editor別のアプローチは、インターフェースに追加のメソッドを追加することです。

public JComponent getComponent();

Editorを返すだけでインスタンスがこのメソッドを実装できますthis

後者のアプローチの利点は、すべてのメソッドを使用でき、インターフェイスでそれらを複製する必要がなく、メソッドの 1 つをインターフェイスJComponentに追加するのを忘れていたという結論に 2 か月以内に達することです。JComponent

于 2012-07-23T07:51:26.837 に答える
1

次の設計がそれを処理します。

public class TextAreaEditor extends JTextArea implements Editor {
//provide your implementation of getText()
//setEnabled(bool) doesn't have be implemented as JComponent will provide
}

TextAreaEditor te = new TextAreaEditor();
te.setEnabled(true); // will call JComponent's impl

上記のコードによると、独自の Editor の具体的な実装 (TextAreaEditor) は、JComponent の Editor およびサブクラスです。

于 2012-07-23T04:09:01.330 に答える
0

私はあなたの議論が単に間違っていると思います:インターフェース(エディター)の場合、実装がどのように実装されているかを気にする必要はありません。Editorの実装はすべてJComponentである必要があるとおっしゃいました。それが今起こっていることですが、「編集者」であるための「要件」である必要はありません。Editorの設計は、実装がEditorが要求するもの(getText())に準拠している限り、それに課す理由はありません。

あなたが話しているのは、ほとんどが「通常の」エディタ実装のデフォルトの基本クラスです。繰り返しになりますが、エディターインターフェイスに準拠している限り、実装がこの基本クラスの使用を選択するかどうかが選択されることに注意してください。

public interface Editor {
    String getText();
}

public abstract class JComponentEditor extends JComponent 
        implements Editor {
    //.....
}

public TextAreaEditor extends JComponentEditor {
    public String getText() {
        // implements TextAreaEditor's version of getText
    }
}

編集:私はOPの質問について少し誤解したと思います。とにかく、私の答えの主な議論はまだ成り立っています:「...私のEditorクラスがJComponentであり、私の具体的なeditorクラスがEditorsとJComponentのサブクラスであること」を強制することは意味がありません。これは、Editorの実装の詳細にすぎません。

于 2012-07-23T03:35:19.997 に答える
0

おそらく、それぞれのスーパークラスを拡張する新しいテーブルとテキストエリアクラスを作成し、そのようなエディターインターフェイスを実装します

public class JTextAreaEditor extends JTextArea implements Editor {
...
}

次に、コンポジションを使用して Editor インターフェイスのメソッドを公開します

    public class JTextAreaEditor extends JTextArea implements Editor {
       private Editor editor;

       public String getValue() {
          return editor.getValue();
       }
       ...
    }
于 2012-07-23T03:22:48.490 に答える