2012-09-19 5 views
5

저는 Swing을 처음 접해 왔으며 상황이 있습니다. XML 파일 입력 (메타 데이터)을 기반으로 GUI 구성 요소를 동적으로 렌더링하는 응용 프로그램을 설계하고 있습니다. 이제 대부분의 JTextField에는 유효성 검사를 위해 InputVerifier가 설정되어 있습니다. 입력 검증자가 입력이 잘못 될 때마다 JOptionPane을 표시합니다.JOptionPane에 의해 포커스가 도난 당했을 때 JButton이 계속 눌러져 있습니다

사용자가 잘못된 데이터를 입력하고 패널의 버튼을 클릭하면 대화 상자가 팝업되고 사용자가 이에 응답해야합니다. 그러나 그 후에도 버튼은 상태를 풀기 위해 페인트하지 않습니다. 그것이 눌려지는 것처럼 그것은 아직도 보았다. 그러나 실제로 그렇지 않다. 전체 코드가 꽤 복잡해 지므로 아래 코드에 문제 시나리오를 넣겠습니다. -

JButton이 압축되지 않은 것처럼 보이게하려면 어떻게해야합니까? 논리가 또한 설명되는 경우에 나는 평가할 것입니다.

미리 감사드립니다.

package test; 

import java.awt.BorderLayout; 
import java.awt.Frame; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 

import javax.swing.InputVerifier; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JTextField; 

public class VerifierTest extends JFrame { 

    private static final long serialVersionUID = 1L; 

    public VerifierTest() { 
     JTextField tf; 
     tf = new JTextField("TextField1"); 

     getContentPane().add(tf, BorderLayout.NORTH); 
     tf.setInputVerifier(new PassVerifier()); 

     final JButton b = new JButton("Button"); 
     b.setVerifyInputWhenFocusTarget(true); 
     getContentPane().add(b, BorderLayout.EAST); 
     b.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       if (b.hasFocus()) 
        System.out.println("Button clicked"); 
      } 
     }); 

     addWindowListener(new MyWAdapter()); 
    } 

    public static void main(String[] args) { 
     Frame frame = new VerifierTest(); 
     frame.setSize(400, 200); 
     frame.setVisible(true); 
     //frame.pack(); 
    } 

    class MyWAdapter extends WindowAdapter { 

     public void windowClosing(WindowEvent event) { 
      System.exit(0); 
     } 
    } 

    class PassVerifier extends InputVerifier { 

     public boolean verify(JComponent input) { 
      JTextField tf = (JTextField) input; 
      String pass = tf.getText(); 
      if (pass.equals("Manish")) 
       return true; 
      else { 
       String message = "illegal value: " + tf.getText(); 
       JOptionPane.showMessageDialog(tf.getParent(), message, 
         "Illegal Value", JOptionPane.ERROR_MESSAGE); 

       return false; 
      } 
     } 
    } 
} 
+4

showMessageDialog 호출을 Runnable로 랩핑하여 SwingUtilities :: invokeLater (Runnable)에 전달하십시오. – gd1

+0

@ gd14 안녕하세요, 명시된 방식대로 시도했지만 작동하지 않는 것 같습니다. 수정 된 코드는 다음과 같습니다. - final String message = "잘못된 값 :"+ tf.getText(); \t javax.swing.SwingUtilities.invokeLater (새의 Runnable() { \t \t 공공 무효 실행() { \t \t \t JOptionPane.showMessageDialog (NULL, 메시지, \t \t \t \t \t "잘못된 값", JOptionPane.ERROR_MESSAGE); \t \t} \t}); \t false를 반환합니다. – dareurdream

+0

알겠습니다. OS 및 Java 버전은 무엇입니까? OSX에서 Java 1.6을 사용하고 있으며 정상적으로 작동합니다. – gd1

답변

3

방법 verify 실제로 JOptionPane의를 열 수있는 좋은 장소가 아니다.

  1. 당신이 JOptionPane에이 텍스트 필드에 포커스를 잃어 버릴 때마다를 표시 할 및 입력이 올바르지 않습니다 :

    당신이 당신의 문제를 해결하기 위해 고려할 수있는 몇 가지 방법이 있습니다 적절한시 JTextField의에서의 FocusListener 행동을 사용 이벤트

  2. 단추를 누를 때마다이 JOptionPane이 나타나기를 원합니다. 입력이 올바르지 않으면 ActionListener를 사용하십시오. 여기

는 후자의 작은 조각이다 :

import java.awt.BorderLayout; 
import java.awt.Frame; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.InputVerifier; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JTextField; 

public class VerifierTest extends JFrame { 

    private static final long serialVersionUID = 1L; 

    public VerifierTest() { 
     final JTextField tf = new JTextField("TextField1"); 

     getContentPane().add(tf, BorderLayout.NORTH); 
     tf.setInputVerifier(new PassVerifier()); 

     final JButton b = new JButton("Button"); 
     b.setVerifyInputWhenFocusTarget(true); 
     getContentPane().add(b, BorderLayout.EAST); 
     b.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (!tf.getInputVerifier().verify(tf)) { 
        JOptionPane.showMessageDialog(tf.getParent(), "illegal value: " + tf.getText(), "Illegal Value", 
          JOptionPane.ERROR_MESSAGE); 
       } 
       if (b.hasFocus()) { 
        System.out.println("Button clicked"); 
       } 
      } 
     }); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
    } 

    public static void main(String[] args) { 
     Frame frame = new VerifierTest(); 
     frame.setSize(400, 200); 
     frame.setVisible(true); 
    } 

    class PassVerifier extends InputVerifier { 

     @Override 
     public boolean verify(JComponent input) { 
      final JTextField tf = (JTextField) input; 
      String pass = tf.getText(); 
      return pass.equals("Manish"); 
     } 
    } 
} 

는 또한합니다 (JFrame의 기본 닫기 작업을 설정하는 대신 윈도우 청취자를 추가하는 것을 고려하지만이있는 WindowListener를 사용하는 좋은 방법입니다 사용자가 응용 프로그램을 종료 할 것인지 묻는 대화 상자가 나타납니다.

+0

감사합니다. 나는 이것을 염두에두고 필요한 chnages를 만들 것입니다 . 그 동안 나는 아래에서 자세히 설명 할 해결책을 찾았습니다. 그게 좋은 해결책인지 확인해 주시겠습니까? 감사합니다 – dareurdream

+0

감사 합니다이 솔루션은 완벽하게 작동합니다. 한 번만 더 질문합니다. 버튼 클릭 (Next라고 함)을 기반으로 카드 레이아웃에서 동적으로 결정되고 만들어진 패널을 전환하고 싶습니다. 이 경우 어떻게해야합니까? 감사합니다 – dareurdream

+0

@ dareurdream 당신의 cardlayout을 보지 못했지만 기본 아이디어는 CardLayout에서 next()와 previous()를 호출하는 것입니다. 특정 구성 요소를 표시하려면 String 제약 조건을 사용하여 컨테이너에 추가하고 원하는 구성 요소에 해당하는 String과 함께 show() 메서드를 사용합니다. 자세한 내용은 [여기]를 참조하십시오 (http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) –

1

SwingUtilities에 대한 호출을 추가하여 GUI가 이벤트 스레드에 있는지 확인하고 Frame에 대한 참조를 제거했습니다.

GUI가 Windows XP에서 작동합니다.

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 

import javax.swing.InputVerifier; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 

public class VerifierTest implements Runnable { 

    private static final long serialVersionUID = 1L; 

    public VerifierTest() { 

    } 

    @Override 
    public void run() { 
     JFrame frame = new JFrame(); 
     frame.setSize(400, 200); 

     JTextField tf; 
     tf = new JTextField("TextField1"); 
     tf.setInputVerifier(new PassVerifier()); 
     frame.getContentPane().add(tf, BorderLayout.NORTH); 

     final JButton b = new JButton("Button"); 
     b.setVerifyInputWhenFocusTarget(true); 
     frame.getContentPane().add(b, BorderLayout.EAST); 
     b.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       if (b.hasFocus()) 
        System.out.println("Button clicked"); 
      } 
     }); 

     frame.addWindowListener(new MyWAdapter()); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new VerifierTest()); 
    } 

    class MyWAdapter extends WindowAdapter { 
     @Override 
     public void windowClosing(WindowEvent event) { 
      System.exit(0); 
     } 
    } 

    class PassVerifier extends InputVerifier { 
     @Override 
     public boolean verify(JComponent input) { 
      JTextField tf = (JTextField) input; 
      String pass = tf.getText(); 
      if (pass.equals("Manish")) 
       return true; 
      else { 
       String message = "illegal value: " + tf.getText(); 
       JOptionPane.showMessageDialog(tf.getParent(), message, 
         "Illegal Value", JOptionPane.ERROR_MESSAGE); 

       return false; 
      } 
     } 
    } 
} 
+0

GUI도 나를 위해 일하고 있지만 진짜 문제는 단추 모양입니다. 우리가 콘솔을 관찰하면 "Button Clicked"라는 시스템이 표시되지 않는다는 것을 알 수 있습니다. 즉, 버튼이 절대로 클릭되지 않습니다. 하지만 여전히 버튼이 눌린 것처럼 보입니다 ... 어쨌든 해결책을 찾았고 그 의견을 듣고 싶습니다. 감사합니다 – dareurdream

+0

InputVerifier의 구현은 _invalid_ – kleopatra

1

나는 아래 버튼에 새 마우스 수신기를 추가하고 이제 나를 위해 잘 작동하는 것 같군하지만 버튼의 선택 상태를 정류의 좋은 방법입니다 있는지 확실하지 않다. 먼저

package test; 

import java.awt.BorderLayout; 
import java.awt.Frame; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 

import javax.swing.InputVerifier; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JTextField; 
import javax.swing.plaf.basic.BasicButtonListener; 

public class VerifierTest extends JFrame { 

    private static final long serialVersionUID = 1L; 

    public VerifierTest() { 
     JTextField tf; 
     tf = new JTextField("TextField1"); 

     getContentPane().add(tf, BorderLayout.NORTH); 
     tf.setInputVerifier(new PassVerifier()); 

     final JButton b = new JButton("Button"); 
     b.setVerifyInputWhenFocusTarget(true); 
     getContentPane().add(b, BorderLayout.EAST); 
     b.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       if (b.hasFocus()) 
        System.out.println("Button clicked"); 
      } 
     }); 

     b.addMouseListener(new BasicButtonListener(b) { 
      @Override 
      public void mouseExited(MouseEvent e) { 
       ((JButton)e.getSource()).getModel().setArmed(false); 
       ((JButton)e.getSource()).getModel().setPressed(false); 
      } 

     }); 

     addWindowListener(new MyWAdapter()); 
    } 

    public static void main(String[] args) { 
     Frame frame = new VerifierTest(); 
     frame.setSize(400, 200); 
     frame.setVisible(true); 
     // frame.pack(); 
    } 

    class MyWAdapter extends WindowAdapter { 

     public void windowClosing(WindowEvent event) { 
      System.exit(0); 
     } 
    } 

    class PassVerifier extends InputVerifier { 

     public boolean verify(JComponent input) { 
      JTextField tf = (JTextField) input; 
      String pass = tf.getText(); 
      if (pass.equals("Manish")) 
       return true; 
      else { 
       final String message = "illegal value: " + tf.getText(); 
         JOptionPane.showMessageDialog(null, message, 
           "Illegal Value", JOptionPane.ERROR_MESSAGE); 

       return false; 
      } 
     } 
    } 
} 
+0

입니다.이 솔루션이 작동하는 동안 실제로 [InputVerifier의 계약] (http://docs.oracle.com/javase/7/docs/api/javax/swing/InputVerifier.html#verify(javax.swing.JComponent)) : _이 메소드에는 부작용이 없어야하므로 _해야합니다. 구성 요소 입력을 검증하고 true 또는 false를 리턴하십시오. 또한, 버튼의 상태를 "수동으로"수정하지 않아야합니다. (실제로 원하는 효과가 아닌 한) –

+0

@GuillaumePolet - 내가 말한 모든 것에 동의하며 위의 제안에 따라 솔루션을 수정합니다. 이 하나에 대한 귀하의 생각을 알고 싶습니다. http://stackoverflow.com/questions/12541879/design-architecture-for-a-tool – dareurdream

+0

+1 - 수동으로 버튼을 이상한 버기에서 빠져 나오십시오. 상태가 여기에서 할 수있는 유일한 것입니다. mouseListener가 정상적으로 작동한다면 괜찮습니다. – kleopatra

1

: 확인의 대화()를 열어가 InputVerifier의 모든 구현 무효 있습니다. 그들은 그들의 계약을 위반했다. API :

이 방법은 부작용이 없어야한다.

"should"는 실제로 "~해야합니다"를 의미합니다. 부작용에 대한 올바른 위치는 shouldField입니다.

둘째, 제대로의 shouldYieldFocus에 (메시지 대화 상자를 표시) 부작용을 이동하는 것은 물론 작동하지 않습니다 ... bug (THEY call it feature request ;-)에, 그건 hack-되는 10 년 나이 in the top 10 RFEs

입니다 때문에 모든 가능한 해킹이 버그를 해결 해킹 다른 옵션이있는 비트를 연주 후

업데이트

:-) 얻을 수있는 버그 주위 @의 dareurdrem의의 MouseListener, 여기에 또 다른 해킹 좋은 - 그것은 취성의 모든 해킹 ar

    : 전자 기본적인 접근 방식은 UI에 의해 설치된 수신기에 후크하는 것입니다 마우스 동작을 해킹

    (그리고 LAF 토글 생존하지 않습니다, 동적 토글이 필요한 경우 다시 설치해야합니다)

  • 은 원래
  • 먼저 초점을 요청 직접 프레스 이벤트에 대한 원래의
  • 명까지 대부분의 이벤트를 사용자 정의 리스너를 구현 찾을 : 아무것도하지하지 않을 경우, 원래 대리자를 굴복 경우
,

포커스 이벤트가 비동기적일 수 있으므로 포커스가 맞는지 확인해야합니다. 차례로 호출하면 아무도 반대하지 않을 경우 릴리스를 보내야합니다.

또 다른 특징은 (defaultButton에 대한) rootPane의 눌려진 동작입니다. 무조건 doClick을 호출하여 inputVerifiers를 존중하지 않고 완료됩니다.

  • 을 찾을 수의 rootPane의 누르면 동작
  • 는 잠재적으로 vetoing가 InputVerifier를 확인하는 사용자 지정 작업을 구현한다 : 즉,이 액션에 후킹의 MouseListener 후킹과 같은 패턴을 따라 해킹 할 수있는 원래의 위임 그렇지 않으면, 아무것도하지 않고 다른

그 라인을 따라 수정 예제 : 사실

public class VerifierTest implements Runnable { 

    private static final long serialVersionUID = 1L; 

    @Override 
    public void run() { 
     InteractiveTestCase.setLAF("Win"); 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(400, 200); 

     JTextField tf = new JTextField("TextField1"); 
     tf.setInputVerifier(new PassVerifier()); 
     frame.add(tf, BorderLayout.NORTH); 

     final JButton b = new JButton("Button"); 
     frame.add(b); 
     b.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Button clicked"); 
      } 
     }); 
     // hook into the mouse listener 
     replaceBasicButtonListener(b); 
     frame.add(new JTextField("not validating, something else to focus"), 
       BorderLayout.SOUTH); 
     frame.getRootPane().setDefaultButton(b); 
     // hook into the default button action 
     Action pressDefault = frame.getRootPane().getActionMap().get("press"); 
     frame.getRootPane().getActionMap().put("press", new DefaultButtonAction(pressDefault)); 
     frame.setVisible(true); 
    } 

    protected void replaceBasicButtonListener(AbstractButton b) { 
     final BasicButtonListener original = getButtonListener(b); 
     if (original == null) return; 
     Hacker l = new Hacker(original); 
     b.removeMouseListener(original); 
     b.addMouseListener(l); 
    } 

    public static class Hacker implements MouseListener { 
     private BasicButtonListener original; 

     /** 
     * @param original the listener to delegate to. 
     */ 
     public Hacker(BasicButtonListener original) { 
      this.original = original; 
     } 

     /** 
     * Hook into the mousePressed: first request focus and 
     * check its success before handling it. 
     */ 
     @Override 
     public void mousePressed(final MouseEvent e) { 
      if (SwingUtilities.isLeftMouseButton(e)) { 
       if(e.getComponent().contains(e.getX(), e.getY())) { 
        // check if we can get the focus 
        e.getComponent().requestFocus(); 
        invokeHandleEvent(e); 
        return; 
       } 
      } 
      original.mousePressed(e); 
     } 

     /** 
     * Handle the pressed only if we are focusOwner. 
     */ 
     protected void handlePressed(final MouseEvent e) { 
      if (!e.getComponent().hasFocus()) { 
       // something vetoed the focus transfer 
       // do nothing 
       return; 
      } else { 
       original.mousePressed(e); 
       // need a fake released now: the one from the 
       // original cycle might never has reached us 
       MouseEvent released = new MouseEvent(e.getComponent(), MouseEvent.MOUSE_RELEASED, 
         e.getWhen(), e.getModifiers(), 
         e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger() 
         ); 
       original.mouseReleased(released); 
      } 
     } 


     /** 
     * focus requests might be handled 
     * asynchronously. So wrap the check 
     * wrap the block into an invokeLater. 
     */ 
     protected void invokeHandleEvent(final MouseEvent e) { 
      SwingUtilities.invokeLater(new Runnable() { 
       @Override 
       public void run() { 
        handlePressed(e); 
       } 
      }); 
     } 

     @Override 
     public void mouseClicked(MouseEvent e) { 
      original.mouseClicked(e); 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      original.mouseReleased(e); 
     } 

     @Override 
     public void mouseEntered(MouseEvent e) { 
      original.mouseEntered(e); 
     } 

     @Override 
     public void mouseExited(MouseEvent e) { 
      original.mouseExited(e); 
     } 
    } 
    public static class DefaultButtonAction extends AbstractAction { 

     private Action original; 

     /** 
     * @param original 
     */ 
     public DefaultButtonAction(Action original) { 
      this.original = original; 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      JRootPane root = (JRootPane) e.getSource(); 
      JButton owner = root.getDefaultButton(); 
      if (owner != null && owner.getVerifyInputWhenFocusTarget()) { 
       Component c = KeyboardFocusManager 
         .getCurrentKeyboardFocusManager() 
         .getFocusOwner(); 
       if (c instanceof JComponent && ((JComponent) c).getInputVerifier() != null) { 
        if (!((JComponent) c).getInputVerifier().shouldYieldFocus((JComponent) c)) return; 
       } 


      } 
      original.actionPerformed(e); 
     } 

    } 
    /** 
    * Returns the ButtonListener for the passed in Button, or null if one 
    * could not be found. 
    */ 
    private BasicButtonListener getButtonListener(AbstractButton b) { 
     MouseMotionListener[] listeners = b.getMouseMotionListeners(); 

     if (listeners != null) { 
      for (MouseMotionListener listener : listeners) { 
       if (listener instanceof BasicButtonListener) { 
        return (BasicButtonListener) listener; 
       } 
      } 
     } 
     return null; 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new VerifierTest()); 
    } 


    public static class PassVerifier extends InputVerifier { 
     /** 
     * Decide whether or not the input is valid without 
     * side-effects. 
     */ 
     @Override 
     public boolean verify(JComponent input) { 
      final JTextField tf = (JTextField) input; 
      String pass = tf.getText(); 
      if (pass.equals("Manish")) 
       return true; 
      return false; 
     } 

     /** 
     * Implemented to ask the user what to do if the input isn't valid. 
     * Note: not necessarily the best usability, it's mainly to 
     * demonstrate the different effects on not/agreeing with 
     * yielding focus transfer. 
     */ 
     @Override 
     public boolean shouldYieldFocus(final JComponent input) { 
      boolean valid = super.shouldYieldFocus(input); 
      if (!valid) { 
       String message = "illegal value: " + ((JTextField) input).getText(); 
       int goAnyWay = JOptionPane.showConfirmDialog(input, "invalid value: " + 
         message + " - go ahead anyway?"); 
       valid = goAnyWay == JOptionPane.OK_OPTION; 
      } 
      return valid; 
     } 
    } 
} 
0

진짜 probl em은 포커스 시스템과 awt 리스너가 상호 작용하는 방식입니다. Java에서 선언 된 몇 가지 버그가 있습니다. 개발자는 책임자를 앞뒤로 가고 있습니다.마우스 수신기는 processMouseEvent를 수행하고 해당 논리 내에서 현재 FocusOwner에 Focus를 요청합니다. 실패합니다. 그러나 이벤트의 절반이 이미 처리되었으므로 버튼이 활성화되고 초점은 필드와 함께 유지됩니다.

마지막으로 한 개발자의 의견을 보았습니다. 필드의 포커스를 잃을 수없는 경우 리스너가 계속 진행하지 못하게하십시오.

예 : 값이인 편집만으로 JTextfield를 정의하십시오. 포커스를 잃었을 때 메시지가 팝업됩니다. 나는 코드로 내 기초하는 JButton 클래스 '의 processMouseEvent (된 MouseEvent 전자) 를 오버라이드 :이 논리의 용기에

protected void processMouseEvent(MouseEvent e) { 
    if (e.getComponent() != null && e.getComponent().isEnabled()) { //should not be processing mouse events if it's disabled. 
      if (e.getID() == MouseEvent.MOUSE_RELEASED && e.getClickCount() == 1) { 
       // The mouse button is being released as per normal, and it's the first click. Process it as per normal. 
       super.processMouseEvent(e); 

       // If the release occured within the bounds of this component, we want to simulate a click as well 
       if (this.contains(e.getX(), e.getY())) { 
        super.processMouseEvent(new MouseEvent(e.getComponent(), 
                  MouseEvent.MOUSE_CLICKED, 
                  e.getWhen(), 
                  e.getModifiers(), 
                  e.getX(), 
                  e.getY(), 
                  e.getClickCount(), 
                  e.isPopupTrigger(), 
                  e.getButton())); 
       } 
      } 
      else if (e.getID() == MouseEvent.MOUSE_CLICKED && e.getClickCount() == 1) { 
       // Normal clicks are ignored to prevent duplicate events from normal, non-moved events 
      } 
      else if (e.getID() == MouseEvent.MOUSE_PRESSED && e.getComponent() != null && (e.getComponent().isFocusOwner() || e.getComponent().requestFocusInWindow())) {// if already focus owner process mouse event 
       super.processMouseEvent(e); 
      } 
      else { 
       // Otherwise, just process as per normal. 
       if (e.getID() != MouseEvent.MOUSE_PRESSED) { 
        super.processMouseEvent(e); 
       } 
      } 
     } 
} 

는 간단한 질문입니다. 버튼 : 이미 초점 소유자입니까? 그렇지 않은 경우 : 가능한 경우 GAIN 포커스 (requestFocusInWindow() 호출 내 현재 포커스 홀더에서 shouldYieldFocus()가 호출되고 유효하지 않은 경우 항상 false를 반환 할 수 있습니까)

이 또한 부작용이 있습니다. 오류 대화 상자가 나타납니다!

이 논리 Java 프로그램의 processMouseEvent 논리가 이벤트를 처리하지 못하게하여 포커스 시스템이 이벤트를 완료하지 못하게합니다.

분명히 당신은 클릭 할 때 액션을 수행하는 모든 다른 JComponents에이 논리 유형이 필요합니다.