9

少し前に、私は小さな画像ビューアー/処理プログラムを Java (ミニ Photoshop) で書きました。

開いた画像のどれを「テーブル上」に置くかを選択できるドロップダウンメニューが必要でした。示され、メソッドが適用されます。イメージの名前を、メニューに表示される JMenuItem の名前にしたかったのです。また、新しい画像を追加するときに新しいボタンを表示したいと考えていました。

私はしばらくこれを疑問に思っていましたが、最終的にこのソリューションを作成しました。これは、画像が追加されたときに新しいボタンの作成を処理する新しいクラスです。コードは次のとおりです。

import java.awt.event.*;
import javax.swing.*;
import java.util.*;


public class ImageList{

    private ArrayList<JMenuItem> list;
    private ImageHandler main;
    private ImageLevel img;

    public ImageList() {}

    public void setHandler(ImageHandler hand) {
        main = hand;
        img = main.getImg1();
    }

    public void add(Buffer addi) {
        final String added = addi.getName();
        JMenuItem uusi = new JMenuItem(added);

        main.getMenu5().add(uusi);
        uusi.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                img.setBuffer(added);
                main.getScr().updateUI();
            }
        });
   }
}

これは正常に機能します。このサイトでは、元のフィンランド語の名前を英語に翻訳しました。なぜ最初にフィンランド語で書いたのだろうか...名前を付けるのが苦手です。

メソッド add は、プログラムの実行中に複数回呼び出されることになっています。

私が実際に理解できないのは、インターフェイス ActionListener の内部クラスの実装、つまりそのコンパイルとその動作です。

インターフェースに 2 つのボタンがあり、それらに異なることをさせたい場合、それぞれに 1 つずつ、2 つの内部クラスが必要で、それぞれがインターフェース ActionListener の独自の内部実装を持っています。しかし、私のコードには、多くの作業を行うように見える1つのクラスがあり、1つのコンパイルされた .class-file がありますが、最終結果は多くの場合のように機能します。

誰かがこの問題について教えてくれますか? このコードは 1 つのクラスであり、新しいボタンはそのインスタンスですか? それらは新しいクラスですか?新しいボタンごとに新しい .class-file が必要ですか? 等...

4

6 に答える 6

5

多くの場合、内部クラスは 1 回だけ呼び出されるコードでインスタンス化されます (たとえば、コンストラクターで sを拡張JPanelして追加ActionListenersする場合)。JButtonここでは、数回呼び出すメソッドで内部クラスをインスタンス化します(説明が正しく理解できれば)。を呼び出すたびadd()に、内部クラスの新しいインスタンスが作成されます。名前付きクラスと同様に、クラスは1 つだけですが、多くのインスタンスが存在する場合があります。

于 2012-11-16T16:10:15.613 に答える
3

このコードでは:

public void add(Buffer addi) {
    . . .
    uusi.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            img.setBuffer(added);
            main.getScr().updateUI();
        }
    });
}

new ActionListener() {...}コンストラクトは匿名の内部クラスです。通常の内部クラスとして個別に宣言されているかのように動作します。主な違いは、名前がコンパイラによって自動的に生成されることです。これは以下と同等です:

private class Anonymous implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        img.setBuffer(added);
        main.getScr().updateUI();
    }
}

public void add(Buffer addi) {
    . . .
    uusi.addActionListener(new Anonymous());
}

コードを実行するたびaddActionListenerに、このクラスの新しいインスタンスが作成されます。

匿名の内部クラスには、匿名であることの結果である他のいくつかの制限があります。たとえば、フィールドを宣言する場合、フィールドはクラス内からのみ (リフレクションを使用せずに) アクセスできます。

于 2012-11-16T16:15:57.453 に答える
0
  • main.getScr().updateUI();すでに表示されているSwingオブジェクトを更新するための適切な方法ではありません。この方法は、ルックアンドフィールに敏感です。

  • を使用して(それ以外の場合はJPanelオーバーライドすることを忘れないでください)、PreferredSizeDimension (0, 0)paintComponent

  • 削除したい場合は、画像を保持する新しいコンテナを追加してから、を呼び出しrevalidate()repaint()


  • JList代わりに画像で使用するJMenuItem

  • に追加ListSelectionListenerするとJList、画像を切り替えることができます


  • ホールドに他のJComponent(s)が追加されていない場合は、ContainerImageJLabelIcon / ImageIcon
于 2012-11-16T16:13:58.833 に答える
0

あなたがしていることは、インターフェイス ActionListener の匿名実装を作成することです。各匿名実装には独自のクラス ファイルがあります (ImageList$1.class、ImageList$2.class などと呼ばれます)。

同様の結果で、次のようなこともできます。

class MyActionListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      img.setBuffer(added);
      main.getScr().updateUI();
    }
};

menuItem.addActionListener(new MyActionListener());
于 2012-11-16T16:17:11.643 に答える
0

メニュー項目のアクション リスナー用に新しい匿名クラスを作成しています。

基本的に、あなたのコード

menuItem.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
      img.setBuffer(added);
      main.getScr().updateUI();
  }
});

ActionListener の新しいクラス実装を定義します

于 2012-11-16T16:10:34.287 に答える
0

クラス内の内部クラスは、「親」の .class ファイルにコンパイルされます。1 つのクラス内に複数の内部クラスを持つことができます。(コンパイル後に 1.class ファイルが生成されます) 内部クラス (ランタイム) への「呼び出し」ごとに、その内部クラスのオブジェクトが作成されます (「標準クラス」と同じ)。ただし、.class ファイルは変更されません。

したがって、同じタイプのボタンを 3 つ追加すると、そのたびにインナークラスの新しいオブジェクトが作成されます。ボタン自体と同じ原理。

于 2012-11-16T16:24:48.390 に答える