質問
私はスイングGUIを持っていると言って、聞きたい MouseEvents
. 。誰がリスナーのクラスであるべきだと思いますか、誰が責任を負うべきですか?それを実装するための最良または好ましい方法は何ですか?意見はありますか?私は通常このように行きます:
public class MyPanel extends JPanel implements MouseListener{
private JTable table;
public void foo(){
table.addMouseListener(this);
}
/* MouseListener */
//Implement MouseListener here.
}
より良い方法はありますか?
編集: 知恵と助けをありがとうございました。それは有り難いです。
解決
イベントリスナーを行うには、いくつかの一般的な方法があります(以下のコードで中断したことを考えることができるのは、静的インナークラスだけです)。以下のコードでは、ActionListenerが最も簡単であるため、Listenerを使用できますが、リスナーにアイデアを適用できます。
「この」方法(クラスにリスナーを実装する)は、声明の膨大なセットにつながる可能性があることに注意してください。私はこれがそのために可能な限り最悪の方法だと思います。私は2つの理由で「ハウスをクリアする」方法を持っているのが嫌いです:
1)彼らは大きい2)それぞれが作品を行うためにメソッドを呼び出すのではなく、メソッド内で作業をするのは魅力的です(あなたが見ることができるように、これは私がここでやったことです...おっと: - ))
また、2つの理由で匿名の方法が好きではありません。
1)コードを簡単に再利用できないため、しばらくしてコードを複製していることがわかります2)コードの読み取りが分割されていることがわかります(他の人は同意しません...個人的な味)。匿名の内側のクラスは良い考えではないことを5〜10回以上している場合、誰もが同意すると思います(私は2つ以上が多すぎると言います)。
それは内側と外側の方法を残します。聞いているGUIにしっかりと結び付けられていないリスナーを書いているとき、私は外側の道を使用します。リスナーがクラスの一部である情報(メンバー変数/メソッド)を必要としない場合(この場合、テストフレーム)、外部クラスに行きます。以下の例では、外側のリスナーがGUIにアクセスできるように、「This」に渡りました...そのようなコードを書くと、GUIから何かを必要とするので、内側のクラスになります。
だから、私の好みの順序は次のとおりです。
- 内部クラス(可能であれば静的ですが、静的にしている場合は、外側のクラスに行く)
- 外側のクラス
- 匿名の内部クラス(まれ)
- クラスにそれ自体を実装してもらいます(私はこれをしないでください。決して!)
そして、これがコードです
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Main
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
final TestFrame frame;
frame = new TestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(new Rectangle(10, 10, 300, 300));
frame.init();
frame.setVisible(true);
}
}
class TestFrame
extends JFrame
implements ActionListener
{
private final JButton aBtn;
private final JButton bBtn;
public TestFrame()
{
super("Test");
aBtn = new JButton("A");
bBtn = new JButton("B");
}
public void init()
{
setLayout(new FlowLayout());
add(aBtn);
add(bBtn);
// the class, since it implements ActionListener
aBtn.addActionListener(this);
bBtn.addActionListener(this);
// outer classes
aBtn.addActionListener(new OuterAListener(this));
bBtn.addActionListener(new OuterBListener(this));
// inner class
aBtn.addActionListener(new InnerAListener());
bBtn.addActionListener(new InnerBListener());
// anonymous classes
aBtn.addActionListener(
new ActionListener()
{
public void actionPerformed(final ActionEvent e)
{
System.out.println ("Hi from Anonymous A");
}
});
bBtn.addActionListener(
new ActionListener()
{
public void actionPerformed(final ActionEvent e)
{
System.out.println ("Hi from Anonymous B");
}
});
}
public void actionPerformed(final ActionEvent evt)
{
final Object source;
source = evt.getSource();
if(source == aBtn)
{
System.out.println ("Hi from this A");
}
else if (source == bBtn)
{
System.out.println ("Hi from this B");
}
else
{
// ???
}
}
private class InnerAListener
implements ActionListener
{
public void actionPerformed(final ActionEvent e)
{
System.out.println ("Hi from Inner A");
}
}
private class InnerBListener
implements ActionListener
{
public void actionPerformed(final ActionEvent e)
{
System.out.println ("Hi from Inner B");
}
}
}
class OuterAListener
implements ActionListener
{
private final TestFrame frame;
public OuterAListener(final TestFrame f)
{
frame = f;
}
public void actionPerformed(final ActionEvent e)
{
System.out.println ("Hi from Outer A");
}
}
class OuterBListener
implements ActionListener
{
private final TestFrame frame;
public OuterBListener(final TestFrame f)
{
frame = f;
}
public void actionPerformed(final ActionEvent e)
{
System.out.println ("Hi from Outer B");
}
}
他のヒント
リスナーを自分のクラスに入れ、再利用できるようにし、懸念を明確に分離することをお勧めします
Javaのスイングコードを見てください。それは本当に良い基準を見るのに最適な場所です。
あなたの場合、私は次のようなものがあります:
public class MyPanel extends JTable {
public void foo() {
addMouseListener(new MouseHandler() );
}
private class MouseHandler implements MouseListener {
...
}
}
これにより、機能性の明確な分離があります。メインクラスが15の異なるインターフェイスの実装を開始すると、コードは完全に維持できなくなります。
匿名のクラスは、主にリスナーに使用されます。特定のリスナーが一度だけ登録されていて、かなり短いことがわかっている場合は、匿名クラスを使用できます。
個人的には、GUIをコントローラーから分離するのが好きです。そのため、コントローラークラスにリスナーを実装することをお勧めします(各機能GUIには独自のものがあります)。 if...else
また swich...case