2016-07-18 8 views
0

데이터베이스에서 이름을 가져 와서 JPopupMenu에 표시하는 자동 제안 기능을 갖춘 토너먼트를 실행하는 데 Java 응용 프로그램을 사용했습니다. 나는이 버그를 요구에 따라 복제 할 수 없었지만 JPopupMenus 중 하나는 화면에 그대로 남아 있고 다른 프로그램을 포함하여 모든 항목에 걸쳐 표시된다는 예외와 함께 보통처럼 사라질 것입니다 내 신청서가 최소화 된 경우. enter image description hereJPopupMenu가 사라지지 않아

당신은 그 아래에 "에스피 노자"는 JPopupMenu의 일부 잔해를 볼 수 있습니다가 계속 표시되고 : 여기

내가 무슨 말을하는지의 스크린 샷이다. 이것은 때로는 안에있는 텍스트를 포함하고 다른 시간은 빈 상자에만 배경색을가집니다. 이 잔여 물은 순수하게 화장품이며 물리적으로 또는 프로그래밍 방식으로 (핫 코딩) 상호 작용하는 방법을 찾지 못했습니다.
private void resetLastNamePopup() { 

    Thread t = new Thread() { 

     @Override 
     public void run() { 

      lnPopup.setVisible(false); 
      lnPopup.removeAll(); 

      if(DBHSDatabaseIntermediary.isConnected()) { 

       if(!(fnTextField.getText().equals("") && lnTextField.getText().equals(""))) { 

        JMenuItem item = null; 
        String[] names = DBHSDatabaseIntermediary.getLastNames(fnTextField.getText(), lnTextField.getText()); 
        for(int i=0; i < names.length; i++) { 

         if(!names[i].equals(lnTextField.getText().trim())) { 

          item = new JMenuItem(names[i]); 
          item.addActionListener(lnActionListener); 
          item.addMouseListener(NewPlayerPanel.this); 
          lnPopup.add(item); 

         } 

        } 

        if(names.length > 0 && !names[0].equals("")) { 

         lnPopup.setVisible(true); 

        } 
        lnPopup.grabFocus(); 

       } 

      } 

     }// ends run() 

    }; 

    t.start(); 

} 

사전에 감사 : 여기

내가 JPopupMenu를 표시하기 위해 사용하고 방법입니다.

답변

3

스윙 메서드 및 생성자는 AWT 이벤트 발송 스레드에서 호출해야합니다. 다른 스레드에서 이러한 메서드를 호출하고 있습니다. 결과는 "정의되지 않은 동작"입니다. 일반적으로 상황이 때때로 작동하지만 항상 그렇지는 않습니다.

private void resetLastNamePopup() { 

    lnPopup.setVisible(false); 
    lnPopup.removeAll(); 

    final String fn = fnTextField.getText(); 
    final String ln = lnTextField.getText(); 

    Thread t = new Thread() { 

     @Override 
     public void run() { 
      if(DBHSDatabaseIntermediary.isConnected() 
        && !fn.isEmpty() && !ln.isEmpty()) { 

       final String[] names = 
        DBHSDatabaseIntermediary.getLastNames(fn, ln); 

       // Rebuild JPopupMenu in AWT event thread. 
       EventQueue.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         for (String name : names) { 
          if (!name.equals(ln)) { 
           JMenuItem item = new JMenuItem(name); 
           item.addActionListener(lnActionListener); 
           lnPopup.add(item); 
          } 
         } 

         if (names.length > 0 && !names[0].isEmpty()) { 
          lnPopup.setVisible(true); 
          lnPopup.grabFocus(); 
         } 
        } 
       }); 
      } 
     }// ends run() 

    }; 
    t.start(); 
} 

자세한 내용은 javax.swing package contract을보고, 자바 튜토리얼에서 Concurrency in Swing :

당신은 EventQueue.invokeLater (또는 별명, SwingUtilities.invokeLater)를 사용하여 수행됩니다 데이터베이스 호출에서 스윙 호출을 분리해야합니다.