2016-05-10 3 views
0

Возможно ли иметь прослушиватель движения в глобальной сети, который имеет разные эффекты в зависимости от того, какой щелчок JPanel нажат (только с помощью одного прослушивателя движения мыши)?Событие для прослушивания мыши для разных JPanels

Например: у меня есть JFrame с двумя добавленными JPanels и прослушивателем движения мыши, добавленным в JFrame. Я хочу, чтобы экран изменялся, когда я нажимаю на один JPanel, но я хочу, чтобы JFrame перетаскивался, когда я нажимаю на другой. Я думаю, что это можно сделать с помощью JLabels, используя текст JLabel для проверки, аналогичный JButton.

EDIT: да, это определенно не правильный способ делать что-то, а просто интересно, возможно ли, если да, то как?

EDIT: Для того, чтобы сделать вещи более понятными, у меня есть один класс, который расширяет ActionListener, MouseMotionListener, MouseListener. возможно ли, чтобы этот один класс обрабатывал все события JFrame с множеством разных JPanels, связанных с ним, и делал что-то другое, основанное на том, от чего была нажата JPanel? (например, с идентификатором, прикрепленным к JPanels, что я могу сравнить event.getSource() с)

+0

' MouseEvent # getSource'? – MadProgrammer

+0

getSource получает JPanel, который его назвал, он будет работать для управления JPanel. но для вызова другого события, основанного на том, что был нажат JPanel, не будет жаль. –

+0

, если невозможно определить JPanel, я могу проверить событие на –

ответ

1

Прежде всего, «глобальный» слушатель, который делает разные вещи для разных компонентов, является плохой идеей, он вводит слишком много логики в один, соединяет код и становится кошмаром обслуживания.

Сказав это, вы можете использовать один MouseListener добавить к каждому компоненту, например ...

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JPanel left = new TestPane(); 
       JPanel right = new TestPane(); 

       left.setBackground(Color.RED); 
       right.setBackground(Color.BLUE); 

       left.setName("left"); 
       right.setName("right"); 

       MouseListener listener = new MouseAdapter() { 
        @Override 
        public void mouseClicked(MouseEvent e) { 
         System.out.println(((JPanel)e.getSource()).getName()); 
        } 
       }; 

       left.addMouseListener(listener); 
       right.addMouseListener(listener); 

       JFrame frame = new JFrame("Testing"); 
       frame.setLayout(new GridLayout(0, 2)); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(left); 
       frame.add(right); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

} 

Тогда вы могли бы просто использовать MouseEvent#getSource, чтобы определить, какой компонент вызвал событие. Для простоты я предоставил name для каждой панели и показал, что я бы использовал другой способ идентифицировать компонент, прежде чем принимать решение о том, что делать.

Лучшее решение было бы обеспечить определенную MouseListener, который сделал конкретное задание на каждой панели по мере необходимости, это становится гораздо легче управлять, изолирует ответственность, разъединяет код и становится легче поддерживать и управлять

+0

Спасибо, это то, что я искал, я знаю, что это плохо, но интересно, можно ли это сделать. принято. –

+0

Я отчасти ненавижу предлагать это, но вы также можете взглянуть на что-то вроде этого [http://stackoverflow.com/questions/14330079/make-a-jpopupmenu-actually-popup/14330224 # 14330224), который использует 'AWTEventListener' – MadProgrammer

0

Я не уверен, что это лучший способ это сделать, но я только что протестировал его, и он действительно работает, по крайней мере, насколько мой код проверяет его. Найдите, в какой строке мышь закончилась, когда она нажата, и выполните необходимые действия.

public static void main(String[] args) { 
    JFrame main = new JFrame("test"); 
    JPanel first = new JPanel(); 
    JPanel second = new JPanel(); 
    first.setSize(400, 500); 
    first.setBackground(Color.BLUE); 
    second.setBackground(Color.RED); 
    second.setSize(400,500); 
    main.setSize(800, 500); 
    main.add(first); 
    first.setLocation(0,0); 
    second.setLocation(400, 500); 
    main.add(second); 
    main.pack(); 
    main.setVisible(true); 
    main.setSize(800, 500); 
    main.addMouseListener(new MouseListener() { 

     @Override 
     public void mousePressed(MouseEvent e) { 
      if(first.getBounds().contains(new Point(e.getX(), e.getY()))) 
      { 
       System.out.println("first box"); 
      }else if(second.getBounds().contains(new Point(e.getX(), e.getY()))) 
      { 
       System.out.println("Second box"); 
      } 
     } 
    }); 
} 
+0

делает это, если я не указал местоположение? и он работает с Mouse Motion Listener? im используя BorderLayouts для него. –

+0

@RoryThoman это должно. Оценки должны оставаться обновленными. –

+0

Добавьте 'MouseListener' к панелям, посмотрите, что произойдет. Добавление того же 'MouseListener' к каждому компоненту позволит вам использовать' MouseEvent # getSource', но, откровенно говоря, было бы разумнее использовать один слушатель для каждого – MadProgrammer

0

EDIT 2

Это должно быть ваш ответ, я заметил на отладку, что, когда я нажимаю на пустом месте на раме я получаю компонент с именем "null.contentPane", так что я положил его в состояние, и это сработало !, надеюсь, я помог.

public class PanelsListener extends JFrame { 

public static void main(String[] args) { 
    PanelsListener pl = new PanelsListener(); 
    pl.setSize(700, 700); 
    pl.setLayout(new FlowLayout()); 
    JPanel fp = new JPanel(); 

    fp.setName("First"); 
    fp.setSize(200, 200); 
    fp.setBorder(new LineBorder(Color.red)); 
    JPanel sp = new JPanel(); 
    sp.setName("Second"); 
    sp.setSize(200, 200); 
    sp.setBorder(new LineBorder(Color.blue)); 
    pl.add(fp); 
    pl.add(sp); 

    pl.addMouseListener(new MouseListener() { 
     @Override 
     public void mouseClicked(MouseEvent e) { 
      JPanel pnl = (JPanel) javax.swing.SwingUtilities 
        .getDeepestComponentAt((PanelsListener) e.getSource(), 
          e.getX(), e.getY()); 
      if (pnl != null && (!pnl.getName().equals("null.contentPane"))) { 
       String name = pnl.getName(); 
       if (name != null) { 
        if (name.equals("First")) { 
         pl.setSize(500, 500); 
        } else if (name.equals("Second")) { 
         pl.setSize(800, 800); 
        } 
        pl.repaint(); 
       } 
      } 

     } 

     @Override 
     public void mouseEntered(MouseEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void mouseExited(MouseEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void mousePressed(MouseEvent e) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      // TODO Auto-generated method stub 

     } 
    }); 

    pl.setVisible(true); 
} 

} 

EDIT 1

Как я понял из вашего комментария, попробуйте вместо следующее:

public class PanelsListener extends JFrame{ 

public static int panel_identifier=0; 

public static void main(String[] args) { 
    PanelsListener pl = new PanelsListener(); 
    pl.setSize(700, 700); 
    pl.setLayout(new FlowLayout()); 
    JPanel fp=new JPanel(); 
    fp.setSize(200,200); 
    fp.setBorder(new LineBorder(Color.red)); 
    JPanel sp=new JPanel(); 
    sp.setSize(200,200); 
    sp.setBorder(new LineBorder(Color.blue)); 

    pl.add(fp); 
    pl.add(sp); 

    //panel_identifier is used to specify which panel has been clicked. 

    fp.addMouseListener(new MouseAdapter() { 
     @Override 
     public void mouseClicked(MouseEvent me) { 
      pl.panel_identifier=1; 
      pl.mouseClicked(me); 
     } 
    }); 
    sp.addMouseListener(new MouseAdapter() { 
     @Override 
     public void mouseClicked(MouseEvent me) { 
      pl.panel_identifier=2; 
      pl.mouseClicked(me); 
     } 
    }); 

    pl.setVisible(true); 
} 
protected void mouseClicked(MouseEvent me) { 
    if(panel_identifier==1) 
    { 
     this.setSize(500, 500); 
     panel_identifier=0; 
    } 
    else if(panel_identifier==2) 
    { 
     this.setSize(800, 800); 
     panel_identifier=0; 
    } 

} 
} 

нормальное решение

общественного класса PanelsListener расширяет JFrame {

public static void main(String[] args) { 
    PanelsListener pl = new PanelsListener(); 
    pl.setSize(700, 700); 
    pl.setLayout(new FlowLayout()); 
    pl.add(new FirstPanel(pl)); 
    pl.add(new SecondPanel(pl)); 
    pl.setVisible(true); 
} 
} 

class FirstPanel extends JPanel { 

public FirstPanel(Frame frm) { 
    setBorder(new LineBorder(Color.red)); 
    setSize(200, 200); 
    addMouseListener(new MouseAdapter() { 
     @Override 
     public void mouseClicked(MouseEvent e) { 
      frm.setSize(500, 500); 
      frm.repaint(); 
     } 
    }); 
    addMouseMotionListener(new MouseAdapter() { 
     @Override 
     public void mouseDragged(MouseEvent e) { 
      // do some action when mouse dragged over this panel 
     } 
    }); 
} 
} 

class SecondPanel extends JPanel { 

public SecondPanel(Frame frm) { 
    setBorder(new LineBorder(Color.blue)); 
    setSize(200, 200); 
    addMouseListener(new MouseAdapter() { 
    @Override 
    public void mouseClicked(MouseEvent e) { 
    frm.setSize(800,800); 
    frm.repaint(); 
    } 
    }); 

    addMouseMotionListener(new MouseAdapter() { 
     @Override 
     public void mouseDragged(MouseEvent e) { 
      // do some action when mouse dragged over this panel 
     } 
    }); 
} 
} 
+0

, это использует два отдельных прослушивателя. Я пытаюсь найти способ изменить эффект прослушивания движения мыши на основе того, на какой JPanel он был нажат. –

+1

@RoryThoman, да, и это правильный способ решить проблему. Вы НЕ должны пытаться использовать один прослушиватель с логикой if/else. – camickr

+0

@RoryThoman, я изменил соответствующим образом. – TiMr