2014-07-27 5 views
0

나는 끌어서 놓기로 작업하고 있습니다. 사용자는 목록에서 다른 곳으로 드래그해야합니다. 그러나 ListSelectionEvent을받을 때 목록이 이동하므로 사용자가 선택을 변경하면 이 표시되면 예기치 않게 끌어서 놓기을 수행 할 수 있습니다.이동 목록으로 끌어서 놓기 처리

내 코드 :

import java.awt.*; 
import javax.swing.*; 

class Main { 
    public static void createGUI() { 
     JFrame f = new JFrame(); 

     JList<String> list = new JList<>(new String[] { "Text A", "Text B" }); 
     list.setFont(list.getFont().deriveFont(24f)); 
     list.setDragEnabled(true); 
     // list.setTransferHandler(new TransferHandler() { /* ... */ }); 
     list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     list.addListSelectionListener(e -> f.setLocation(f.getX(), 
       f.getY() + f.getHeight())); 
     list.setSelectedIndex(0); 

     f.add(list, BorderLayout.CENTER); 
     f.pack(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLocationByPlatform(true); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(Main::createGUI); 
    } 
} 

가 드롭 (예를 들어, 이클립스, 메모장 ++) 받아 일부 응용 프로그램 위에 넣어,이 응용 프로그램을 실행, 복제 및 선택을 여러 번 전환합니다.

Windows 7 및 JDK 1.8.0_5를 사용하고 있습니다.

시도했지만 해결 방법을 찾을 수 없습니다. 어떻게이 문제를 해결할 수 있습니까?


이 내 실제 응용 프로그램입니다 [별로 관련] :

Screenshot (Empty)Screenshot (TopCoder)

+1

그냥 최종 사용자의 생각을 충족 : 1) 난 정말 그런 식으로 동작하는 응용 프로그램을 싫어. 선택 이벤트에서 목록을 옮기는 요지는 무엇입니까? DnD를 사용하면 구성 요소가 조용한 상태로 유지되므로 시각적으로 이중 체크를하면 오른쪽 목록 항목을 드래그 할 수 있습니다. 2) 목록을 이동하면 예기치 않게 떨어지는 경향이 있습니다. 3) 그것은 단지 예일 뿐이지 만 두 가지 선택을 한 후에 프레임이 더 이상 내 화면에 표시되지 않는다는 것을 알고 있습니다. – dic19

+0

@ dic19 힘내세요! 첫 번째와 세 번째 사항에 관한 업데이트를했습니다. – johnchen902

+0

그래서 드래그 앤 드롭 효과를 원하지 않거나 어디에서 드롭을 수정 하시겠습니까? (또한, 나는 DnD 사용법의 이상한 구석을 발견했다고 생각합니다.) –

답변

1

나는 당신의 문제를 이해하고 있다고 생각합니다. 사용자가 자신의 선택을 변경할 때가 아니라 DnD를 활성화하고 싶습니다. 이은 (자바 7에서, 나는 아직 람다 표현식 너무 편안하지, 그래서 난 아직도하지만 그것은 자바 8 일 것이다 자바 8. 사용하지 않는) 시도해야합니다 :

class Main { 
    private static boolean listChanging = false; 

    public static void createGUI() { 
     final JFrame f = new JFrame(); 
     JList<String> list = new JList<String>(new String[] { "Text A", "Text B" }); 
     list.setFont(list.getFont().deriveFont(24f)); 
     list.setDragEnabled(true); 
     list.setTransferHandler(new TransferHandler() { 
      private static final long serialVersionUID = 1L; 

      @Override 
      public int getSourceActions(JComponent c) { 
       if (listChanging) { 
        listChanging = false; 
        return NONE; 
       } else { 
        return COPY; 
       } 
      } 

      @Override 
      @SuppressWarnings("unchecked") 
      public Transferable createTransferable(JComponent c) { 
       return new StringSelection(((JList<String>) c).getSelectedValue()); 
      } 
     }); 
     list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     list.addListSelectionListener(new ListSelectionListener() { 
      @Override 
      public void valueChanged(ListSelectionEvent e) { 
       f.setLocation(f.getX(), f.getY() + f.getHeight()); 
       listChanging = true; 
      } 
     }); 
     list.setSelectedIndex(0); 
     f.add(list, BorderLayout.CENTER); 
     f.pack(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLocationByPlatform(true); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       Main.createGUI(); 
      } 
     }); 
    } 
} 

어떤 코드를 사용자가 선택을 변경할 때 listChangingtrue으로 설정하면됩니다. 사용자가 (실수로 또는 의도적으로) 드래그하면 listChangingtrue인지 여부를 확인합니다. 이는 예기치 않은 드래그 일 가능성이 있음을 의미합니다. 목록이 변경되지 않으면 COPY 끌기가 허용됩니다.

기본적으로 드래그가 목록 변경 중에 발생하면 DnD가 비활성화됩니다. 목록이 변경되지 않고 사용자가 의도적으로 드래그하면 DnD가 활성화됩니다.

희망이 모든 요구 사항 : 당신의 코드를 테스트 한 후

+0

합리적인 것 같습니다. 응용 프로그램을 작업 할 때 시도해 보겠습니다. – johnchen902

+0

@ johnchen902 좋아, 어떻게 작동하는지 알려주면 업데이트/변경할 수 있습니다. –

+0

예, 작동합니다! 목록이 항상 움직이는 것은 아니지만 시간을 확인하여 해결했습니다. 당신이 더 좋은 제안을 가지고 있다면, 나는 인정 될 것이다! – johnchen902

0

아직도 그것은 당신이 당신의 응용 프로그램과 함께 수행 할 작업을 분명하지 않다 (녹색 십자가 아이콘 포함) .. 드래그 앤 드롭은 마우스/키 이벤트로 수행되거나 다른 이벤트를 통해 트리거 할 수 있습니다. 여기서 알 수 있듯이 List에서 일부 구성 요소를 선택하고 DnD를 실행하여 해당 구성 요소를 다른 컨테이너로 전송할 수 있습니다.

질문을 자세히 작성하고 샘플 응용 프로그램으로 정확히 수행하려는 내용을 구체적으로 질문하십시오.

+2

제 질문은 충분히 명확하다고 생각합니다 : 버그를 수정하십시오. 그리고 대답을 자세히 설명해주십시오. 현재 상태에서는 주석이어야합니다. – johnchen902