2009-07-24 7 views
2

내 Java GUI 코드에 문제가있는 것처럼 보입니다. 왜 작동하지 않는지 전혀 알지 못합니다.스윙 구성 요소 및 awt 이벤트 문제

패널 또는 프레임 에서 마우스를 클릭하면 패널이 표시됩니다. 이것은 단지 테스트 일 뿐이므로 결국이 코드는 다른 GUI 구성 요소에 대해 구현되지만이 작업을 먼저 수행하고 싶습니다. - 팝업 메뉴이 표시되고 포커스가 텍스트 필드에 설정되어야합니다.. 그런 다음 사용자가 enter 키를 누르거나 텍스트 필드의 포커스를 잃어 버리면 팝업 메뉴가 숨겨져 텍스트가 비어 있거나 필요한대로 재설정됩니다.

public class Test { 
    private final JFrame frame = new JFrame(); 
    private final JPanel panel = new JPanel(); 
    private final JPopupMenu menu = new JPopupMenu(); 
    private final JTextField field = new JTextField(); 
    private final Obj obj; 

    //... constructor goes here 

    public void test(){ 
     frame.setSize(new Dimension(200,200)); 
     field.setColumns(10); 
     field.addActionListener(new ActionListener(){ 
      public void actionPerformed(ActionEvent arg0) { 
       obj.method(field.getText()); 
       menu.setVisible(false); 
       field.setText(""); 
      } 
     }); 
     field.addFocusListener(new FocusListener() { 
      public void focusLost(FocusEvent e) { 
       menu.setVisible(false); 
       field.setText(""); 
      } 

      //... focus gained event goes here 
     }); 
     panel.addMouseListener(new MouseListener() { 
      public void mouseClicked(MouseEvent e) { 
       menu.setLocation(e.getX(), e.getY()); 
       menu.setVisible(true); 
       field.requestFocusInWindow(); 
      } 

      //... other mouse events go here 
     }); 

     menu.add(field); 
     frame.getContentPane().add(panel); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 
} 

을 코드로 여기에 기록 된 메뉴가 자동으로 내가 클릭 한 후 바로 숨 깁니다대로 :

그래서이 내가 쓴 것입니다. 그냥 화면에 잠시 깜박 인 다음 나 외에는 아무것도하지 않고 숨 깁니다.

menu.setVisible(false)의 항목을 제외하도록 코드를 변경하면 텍스트 필드에 절대 포커스가 적용되지 않습니다.

JPopupMenu의 오용으로 인한 문제입니까? 내가 어디로 잘못 가고 있니?

주 또는 Obj를 생략했습니다. 그들은 다른 파일에 있으며이 문제에 대해 중요하지 않을 가능성이 큽니다. Obj.method()는 아무 일도하지 않고 main은 Test의 생성자와 test() 메소드 만 호출합니다.

+0

팝업 메뉴의 목적은 무엇입니까? – user101884

+0

팝업 메뉴에 텍스트 필드가 있다는 것이 이상하게 보입니다. 이 접근법의 동기는 무엇입니까? 아마 이것을 수행하는 다른 방법이 있습니다 ... – basszero

답변

2

이 코드는 희망 익명 클래스의 사용에 따라 당신은 (그것을 원하는 방식으로 작업해야됩니다

public class Test { 

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

private JFrame frame; 
private JPanel panel; 
private JPopupMenu menu; 
private JTextField field; 

public Test() { 
    frame = new JFrame(); 
    frame.setSize(new Dimension(200, 200)); 
    frame.getContentPane().add(getPanel()); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

private JPanel getPanel() { 
    if (panel == null) { 
     panel = new JPanel(); 
     panel.setComponentPopupMenu(getMenu()); 
     panel.addMouseListener(new MouseAdapter() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       menu.show(panel, e.getX(), e.getY()); 
      } 
     }); 
    } 
    return panel; 
} 

private JPopupMenu getMenu() { 
    if (menu == null) { 
     menu = new JPopupMenu() { 

      @Override 
      public void setVisible(boolean visible) { 
       super.setVisible(visible); 
       if (visible) { 
        getField().requestFocus(); 
       } 
      } 
     }; 
     menu.add(getField()); 
    } 
    return menu; 
} 

private JTextField getField() { 
    if (field == null) { 
     field = new JTextField(); 
     field.setColumns(10); 
     field.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       getMenu().setVisible(false); 
      } 
     }); 
    } 
    return field; 
} 

public void test() { 
    frame.setVisible(true); 
} 
} 

중요한 일들이 주목할을 때 설정 팝업 메뉴 :

panel.setComponentPopupMenu(getMenu()); 
panel.addMouseListener(new MouseAdapter() { 
    @Override 
    public void mouseClicked(MouseEvent event) { 
     getMenu().show(getPanel(), event.getX(), event.getY()); 
    } 
}); 

팝업 메뉴가 표시 될 때 텍스트 필드의 포커스를 요청하는 방법 (포커스를 요청하는 텍스트 필드를 통해 수행되지만 창에 포커스가 없으므로 메뉴에만 있음) :

menu = new JPopupMenu() { 
    @Override 
    public void setVisible(boolean visible) { 
     super.setVisible(visible); 
     if (visible) { 
      getField().requestFocus(); 
     } 
    } 
}; 

그리고 마지막으로 텍스트 필드 메뉴를 팝업을 일축 방법 :

field.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     getMenu().setVisible(false); 
    } 
}); 
1

getComponentPopupMenu를 오버라이드하여 JPopupMenu를 반환하여이 작업을 수행 할 수 있어야합니다. 원하는대로 정확하게 처리해야합니다. 포커스 등을 허용합니다.

EDIT : 상속을 위해 더 좋지만 꼭 필요한 것은 아닙니다.

Public JPopupMenu getComponentPopupMenu() { 
    return getMenu(); 
} 

아, 그리고 당신은, 마우스 클릭에 표시 PopupMenu로에 마우스 수신기 및 통화 쇼를 추가하려면 : 마우스 클릭에 표시됩니다

public void processMouseEvent(MouseEvent e) { 
    popup.show(this, e.getX(), e.getY()); 
} 

합니다.

public void processMouseEvent(MouseEvent e) { 
    if (e.isPopupTrigger()) { 
     popup.show(this, e.getX(), e.getY()); 
    } 
} 

마우스 리스너는 다음과 같이 보일 것이다 :

panel.addMouseListener(new MouseAdapter() { 
    mouseClicked(MouseEvent e) { 
     processMouseEvent(e); 
    } 
} 
당신이 마우스 수신기를 가지고 (의 processMouseEvent를 호출) 당신은 마우스 오른쪽 버튼으로 클릭에 전화를 걸 경우

또는 또 다른 옵션은

+0

내 질문을 업데이 트하지만 내가 한 모든 변경 setVisible 표시하고 포커스가 자동으로 텍스트 필드로 이동하지 않는 것을 제외하고 작동합니다. 더 이상 tho ... 감사를 숨기지 않습니다. – Victor

+0

오른쪽. getPopupMenu를 사용하거나 popup.show (...)를 사용하면 포커스가 Swing에 의해 처리되고 자유롭게 해당 동작을 가져옵니다. – aperkins

+0

좀 더 명확하게하기 위해 몇 가지를 추가했습니다. 마우스 수신기는 mouseEvent 메서드를 호출합니다. 다시, popup.show를 사용하면 기본 프레임 워크에서 포커스를 처리하도록 할 수 있습니다. – aperkins

0

팝업을 표시하면 포커스가 있어야하며 (아마도 잡을 것입니다) 다른 모든 것이별로 의미가 없습니다.

그래서 아마도 다음과 같습니다. 메뉴가 표시되고 포커스를받습니다.

다음 명령으로 포커스를 텍스트 필드로 이동합니다. 팝업에는 초점이없고 포커스가없는 팝업은 쓸모가 없으므로 다시 숨 깁니다.

+0

실제로 감각을하지 않습니다. 왜냐하면 내 코드에서 menu.setVisible (false)을 가질 때만 숨겨지기 때문입니다. 심지어 field.requestFocusInWindow()가있을 때에도 숨겨지지 않습니다. – Victor

1

내가 setComponentPopupMenu()가 자동으로 표시하는 MouseListener를 추가 제안 된 방법의 사용을 통해 발견 해요 점을 지적하고 싶습니다 지정된 PopupMenu는 오른쪽 클릭 이벤트를 소비합니다.
if(e.isPopupTrigger()) 구조 안에있는 것은 이벤트가 소비되어 오른쪽 클릭에 실행되지 않습니다.

기본적으로 panel.setComponentPopupMenu(getMenu())을 추가하여 본인의 질문에 명시된 동작을 얻지 만 mouseClicked가 아니라 모든 마우스 오른쪽 버튼 클릭 이벤트를 많이 사용한다는 사실은 극도로 제한적입니다.