2

viewportViewをさまざまなパネルにJScrollPane設定できる があります。ビューポート内の他のコンポーネントがクリックされるたびに JScrollPane コンポーネントを取得したいと考えています。JScrollPane にa を追加すると、ペインの境界線を直接クリックしたときにマウス イベントを受け取りますが、コンポーネントをクリックしたときは受け取りません。MouseListener

リスナーを追加し、最終的に囲んでいる scrollPane を見つける正しい方法は何ですか? ビューポートに表示するパネル上のすべてのコンポーネントを事前に知っているとは限りません。それらが JPanel のサブクラスにあるということだけです。

import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.MouseInputAdapter;

import net.miginfocom.swing.MigLayout;

public class TestScrollPane extends MouseInputAdapter{
    public void mouseEntered(MouseEvent arg0) {System.out.println("Entered " + arg0.getComponent());}
    public void mouseExited(MouseEvent arg0) {System.out.println("Exited " + arg0.getComponent());}
    public void mousePressed(MouseEvent arg0) {System.out.println("Pressed " + arg0.getComponent());}
    public void mouseReleased(MouseEvent arg0) {System.out.println("Released " + arg0.getComponent());}

    public static void main(String[] args){
        JFrame frame = new JFrame();
        frame.setLayout(new MigLayout());
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        TestPane pane1 = new TestPane("Scroll Pane 1");
        TestPane pane2 = new TestPane("Scroll Pane 2");
        frame.add(pane1, "push,grow");
        frame.add(pane2, "push, grow");
        TestMouseListener listener = new TestMouseListener();
        pane1.addMouseListener(listener);
        pane1.addMouseMotionListener(listener);
        pane2.addMouseListener(listener);
        pane2.addMouseMotionListener(listener);
        frame.setVisible(true);
    }
}

class TestPanel2 extends JPanel {
    String name;
    TestPanel2(String name){ 
        this.name = name;
        setLayout(new MigLayout());
        JTextArea area = new JTextArea();
        area.append(name);
        add(area, "push, grow");
    }
    public String toString(){ return name; }
}
class TestPane extends JScrollPane {
    String name;
    TestPane(String name){ 
        this.name = name; 
        TestPanel2 panel = new TestPanel2(name + " panel");
        setViewportView(panel);
    }
    public String toString(){ return name; }
}

この例では、マウスの開始イベントと終了イベントを取得しますが、マウス クリック イベントは、テキスト領域の周囲の境界をクリックすることによってのみ取得できます。TestPane クラスを変更してリスナーをその viewportView パネルに追加しても、textArea で何が起こっているのかわかりません。

class TestPane extends JScrollPane {
    String name;
    TestPane(String name){ 
        this.name = name; 
        TestPanel2 panel = new TestPanel2(name + " panel");
        TestMouseListener listener = new TestMouseListener();
        panel.addMouseListener(listener);
        panel.addMouseMotionListener(listener);
        setViewportView(panel);
    }
    public String toString(){ return name; }
}

ただし、JPanel に何があるかを知る方法がないため、リスナーを手動で追加することはできません。

4

3 に答える 3

4

もう 1 つの方法は、AWTEventListener を使用し、親ツリーをバブルアップして、対象のコンポーネントが押されているかどうか、または押されている子を保持しているかどうかを確認することです。例えば:

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.MouseInputAdapter;

// import net.miginfocom.swing.MigLayout;

public class TestScrollPane extends MouseInputAdapter {
   public void mouseEntered(MouseEvent arg0) {
      System.out.println("Entered " + arg0.getComponent());
   }

   public void mouseExited(MouseEvent arg0) {
      System.out.println("Exited " + arg0.getComponent());
   }

   public void mousePressed(MouseEvent arg0) {
      System.out.println("Pressed " + arg0.getComponent());
   }

   public void mouseReleased(MouseEvent arg0) {
      System.out.println("Released " + arg0.getComponent());
   }

   public static void main(String[] args) {
      JFrame frame = new JFrame();
      // frame.setLayout(new MigLayout());
      frame.getContentPane().setLayout(new FlowLayout());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      TestPane pane1 = new TestPane("Scroll Pane 1");
      TestPane pane2 = new TestPane("Scroll Pane 2");
      frame.add(pane1, "push,grow");
      frame.add(pane2, "push, grow");
      // !! TestMouseListener listener = new TestMouseListener();
      TestScrollPane listener = new TestScrollPane();
      pane1.addMouseListener(listener);
      pane1.addMouseMotionListener(listener);
      pane2.addMouseListener(listener);
      pane2.addMouseMotionListener(listener);
      frame.pack();
      frame.setVisible(true);

      Toolkit.getDefaultToolkit().addAWTEventListener(
            listener.createAWTWindowListener(), AWTEvent.MOUSE_EVENT_MASK);

   }

   private AWTEventListener createAWTWindowListener() {
      AWTEventListener awt1 = new AWTEventListener() {

         @Override
         public void eventDispatched(AWTEvent e) {
            if (MouseEvent.MOUSE_PRESSED == e.getID()) {
               MouseEvent event = (MouseEvent) e;
               Component comp = event.getComponent();

               if (comp != null) {
                  String scrollPanelName = recursivelyCheckForScrollPanel(comp);
                  if (scrollPanelName != null) {
                     System.out.println("TestPane pressed. Name: " + scrollPanelName);
                  } else {
                     System.out.println("TestPane not pressed");
                  }
               }
            }
         }

         private String recursivelyCheckForScrollPanel(Component comp) {
            if (comp instanceof TestPane) {
               return comp.toString();
            } else {
               comp = comp.getParent();
               if (comp != null) {
                  return recursivelyCheckForScrollPanel(comp);
               }
            }
            return null;
         }
      };
      return awt1;
   }
}

class TestPanel2 extends JPanel {
   String name;

   TestPanel2(String name) {
      this.name = name;
      // setLayout(new MigLayout());
      JTextArea area = new JTextArea(5, 20);
      area.append(name);
      add(area, "push, grow");
   }

   public String toString() {
      return name;
   }
}

class TestPane extends JScrollPane {
   String name;

   TestPane(String name) {
      this.name = name;
      TestPanel2 panel = new TestPanel2(name + " panel");
      setViewportView(panel);
   }

   public String toString() {
      return name;
   }
}

注: 詳細については、この質問と、StanislovL と mkorbel の回答を参照してください。

于 2012-07-13T21:43:31.357 に答える
1

スクロール ペインはコーナーとスクロール バーのみで構成されているため、スクロール ペイン自体ではなく JScrollPane のビューにマウス リスナを追加する必要があります。

yourJScrollPane.getViewport().getView().addMouseListener(yourMouseListener);

このコード セグメントは、マウス リスナを JScrollPane の 1 つのビューポート コンポーネントに追加します。

于 2012-07-13T21:33:34.657 に答える
0

パネルにコンテンツが含まれ、マウスリスナーも含まれている場合、これらのイベントが通知されることはありません(マウスイベントは、チェーンの上位にあるユーザーによって消費される傾向があります)。

JTableの動作と同様に、addNotifyを使用できます。次に、必要なコンポーネントができるまで親チェーンをウォークします。

もちろん、これは、マウスリスナーを使用することに心を決めていないことを前提としています...

于 2012-07-13T21:34:57.433 に答える