시간이 지남에 따라 Swing 구성요소 세트로 끌어서 놓기 기능이 많이 변경되었습니다. 이전 버전에서는 java.awt.dnd 패키지에 기본 API가 있었지만(java.awt.datatransfer의 지원) 초기 사용자 클릭에서 놓기 조작까지 끌기 작업의 모든 측면을 정의해야 했습니다. J2SE 1.4는 기능 세트에 따라 향상되고 이전 팁 Dragging Text and Images with Swing에 설명된 API를 업데이트합니다.

이전 API의 변경으로 끌어서 놓기 작업이 훨씬 쉬워졌습니다. 수많은 구성요소가 끌어서 놓기 작업을 내장 지원하기 때문입니다. 예를 들어, JTextField에서 끌기 작업을 사용 가능하게 설정하려면 텍스트 구성요소에서 setDragEnabled(true)를 호출하기만 하면 됩니다. 그러면 사용자는 텍스트 구성요소의 텍스트를 끌어서, 놓기 지역 역할을 하는 다른 애플리케이션이나 텍스트 필드 자체 내에 놓을 수 있습니다.

텍스트 구성요소는 JColorChooser 구성요소와 같이 내장된 놓기 지원을 제공하지만 JList, JTable 또는 JTree와 같은 다른 Swing 구성요소에 놓기 지원을 추가하려면 약간의 추가 작업을 수행해야 합니다. 작업이 복잡하게 들릴 수 있겠지만 TransferHandler의 1.6 내부 DropLocation 클래스의 새로운 기능 덕분에 이 작업은 비교적 쉬워졌습니다. 놓기 가능한 데이터 종류 및 일단 놓은 후에 수행해야 하는 작업에 대해 정의하는 JTree에 대한 TransferHandler를 생성하기만 하면 됩니다. 이러한 작업은 각각 canImportimportData 메소드로 제공됩니다. TransferSupport 내부 클래스는 1.6의 새로운 기능으로, 전송 처리기를 정의하는 보다 간단한 방법을 제공해 줍니다.

이미지나 텍스트를 나뭇잎에 놓도록 허용하는 멋진 JTree를 작성할 수 있지만 다음 예제는 문자열만 수락합니다. 이미지도 수락하도록 예제를 활용해 보십시오. 문자열을 지원하려면 TransferHandler.TransferSupport 인수로 canImport 메소드를 정의해서 지원되는 데이터 유형(문자열) 및 작업 유형을 확인해야 합니다. TransferSupport에는 작업의 TransferHandler.DropLocation을 가져오는 getDropLocation 메소드도 있습니다. 위치가 유효한 지점이면 canImport 메소드는 참을 반환해야 합니다. 다음은 널이 아닌 트리 경로에서 문자열 유형의 놓기 전송에 대해 참을 반환하는 메소드입니다.

  public boolean canImport(TransferHandler.TransferSupport support) {
    if (!support.isDataFlavorSupported(DataFlavor.stringFlavor) ||
        !support.isDrop()) {
      return false;
    }

    JTree.DropLocation dropLocation =
      (JTree.DropLocation)support.getDropLocation();

    return dropLocation.getPath() != null;
  }

JTree.DropLocationJTree 구성요소에 대한 TransferHandler.DropLocation의 사전 정의된 구현입니다. JList로 작업하기 위한 JList.DropLocationJTree.DropLocation이 있는 JTree에 대한 다른 것도 있습니다. 기본 텍스트 구성요소 놓기 처리 동작을 원하지 않을 경우 JTextComponent.DropLocation에 네 번째 구현이 있습니다.

JTree에 놓기 지원을 추가하는 나머지 역할은 importData 메소드가 수행합니다. importData 메소드의 이전 버전인 importData(JComponent comp, Transferable t)는 직접 호출되지 않지만 여전히 지원됩니다. 새로운 처리기는 실제로 importData(TransferHandler.TransferSupport support) 버전을 대신 구현해야 합니다. 이 메소드에서 전송된 데이터를 얻어 TreePath의 올바른 위치에 배치해야 합니다.

전송된 데이터를 얻어도 이전 importData 메소드에서 새 메소드로 이동하는 데는 실제로 영향을 주지 않습니다. 메소드에 Transferable 인수를 가지는 대신 support.getTransferable 메소드로 TransferSupport에서 가져옵니다. 그런 다음 적절한 유형의 데이터를 가져오기만 하면 됩니다.

  Transferable transferable = support.getTransferable();

  String transferData;
  try {
    transferData = (String)transferable.getTransferData(
      DataFlavor.stringFlavor);
  } catch (IOException e) {
    return false;
  } catch (UnsupportedFlavorException e) {
    return false;
  }

놓기 작업의 위치를 결정하려면 JTree.DropLocation 클래스를 사용하십시오. DropLocationgetChildIndex 메소드를 호출하면 트리에 새 노드를 추가할 위치가 제공됩니다. -1의 하위 인덱스 값은 사용자가 트리의 빈 부분에 노드를 놓았다는 의미입니다. 이 예제에서는 노드가 끝에 추가됩니다. DropLocationgetPath 메소드를 호출하면 놓기 위치에 대해 TreePath를 반환합니다. 그런 다음 놓기 위치와 연관된 상위 노드를 찾으려면 경로의 getLastPathComponent 메소드를 호출하십시오.

  JTree.DropLocation dropLocation =
    (JTree.DropLocation)support.getDropLocation();

  TreePath path = dropLocation.getPath();

  int childIndex = dropLocation.getChildIndex();
  if (childIndex == -1) {
    childIndex = model.getChildCount(path.getLastPathComponent());
  }

  DefaultMutableTreeNode newNode =
    new DefaultMutableTreeNode(transferData);
  DefaultMutableTreeNode parentNode =
    (DefaultMutableTreeNode)path.getLastPathComponent();
  model.insertNodeInto(newNode, parentNode, childIndex);

새 경로 요소가 표시되는지 확인하는 것도 도움이 됩니다. 전체 importData 메소드는 다음과 같습니다.

  public boolean importData(TransferHandler.TransferSupport support) {
    if (!canImport(support)) {
      return false;
    }

    JTree.DropLocation dropLocation =
      (JTree.DropLocation)support.getDropLocation();

    TreePath path = dropLocation.getPath();

    Transferable transferable = support.getTransferable();

    String transferData;
    try {
      transferData = (String)transferable.getTransferData(
        DataFlavor.stringFlavor);
    } catch (IOException e) {
      return false;
    } catch (UnsupportedFlavorException e) {
      return false;
    }

    int childIndex = dropLocation.getChildIndex();
    if (childIndex == -1) {
      childIndex = model.getChildCount(path.getLastPathComponent());
    }

    DefaultMutableTreeNode newNode =
      new DefaultMutableTreeNode(transferData);
    DefaultMutableTreeNode parentNode =
      (DefaultMutableTreeNode)path.getLastPathComponent();
    model.insertNodeInto(newNode, parentNode, childIndex);

    TreePath newPath = path.pathByAddingChild(newNode);
    tree.makeVisible(newPath);
    tree.scrollRectToVisible(tree.getPathBounds(newPath));

    return true;
  }

완전히 작동하는 놓기 가능한 JTree를 가지도록 충분한 정보를 자세히 보여 드렸습니다. 여기서 놓기 지원에 관련된 중요한 정보인 DropMode에 대해 알려드리겠습니다. DropMode는 구성요소에서 놓기 작업이 발생되는 위치를 표시하는 방식에 관한 모드를 열거한 것입니다. JTree에 대해 다음 네 가지 모드가 지원됩니다.

  • DropMode.USE_SELECTION
  • DropMode.ON
  • DropMode.INSERT
  • DropMode.ON_OR_INSERT

그러나 열거는 다른 구성요소의 특정 모드에 대해 더 커집니다(JTable로 작업할 경우 INSERT_COLS 또는 INSERT_ROWS).

놓기 모드는 어떻게 처리할까요? 기본적으로 이 모드는 USE_SELECTION입니다. 이것은 JTree에서 선택된 항목을 더 이상 강조 표시하지 않음을 의미합니다. 대신 선택 메커니즘을 사용하여 놓기 위치를 강조 표시하십시오. JTree가 놓기를 지원하면 기본값을 변경하는 것이 좋습니다. 더 나은 모드는 ON입니다. 이 모드를 사용하여 JTree 및 잠재적 놓기 위치에서 현재 선택을 모두 확인할 수 있습니다. INSERT 모드를 사용하여 현재 선택 사항을 보면서 기존 노드 사이에 새 노드를 삽입할 수 있습니다. ON_OR_INSERT는 후자 두 개를 결합한 것입니다. 다음 그림 4개는 네 가지 옵션을 보여 줍니다. 완료된 프로그램은 다른 동작을 시도하도록 모드 콤보 상자를 제공합니다.

Use Selection
그림 1. Use Selection


On 
그림 2. On


Insert 
그림 3. Insert


 On or Insert
그림 4. On or Insert

다음은 놓기 가능한 전체 트리 프로그램입니다. 프로그램에는 중간에 선택하여 JTree에 놓을 수 있는 텍스트 항목의 맨 위에 텍스트 영역이 있습니다. 놓기 모드는 맨 아래의 콤보 상자에서 설정할 수 있습니다. 트리에 대한 데이터 모델은 JTree를 작성할 때 지정되지 않은 경우 작성된 기본 모델에서 나옵니다.

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.tree.*;

public class DndTree {
  public static void main(String args[]) {
    Runnable runner = new Runnable() {
      public void run() {
        JFrame f = new JFrame("D-n-D JTree");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel top = new JPanel(new BorderLayout());
        JLabel dragLabel = new JLabel("Drag me:");
        JTextField text = new JTextField();
        text.setDragEnabled(true);
        top.add(dragLabel, BorderLayout.WEST);
        top.add(text, BorderLayout.CENTER);
        f.add(top, BorderLayout.NORTH);

        final JTree tree = new JTree();
        final DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
        tree.setTransferHandler(new TransferHandler() {
          public boolean canImport(TransferHandler.TransferSupport support) {
            if (!support.isDataFlavorSupported(DataFlavor.stringFlavor) ||
                !support.isDrop()) {
              return false;
            }

            JTree.DropLocation dropLocation =
              (JTree.DropLocation)support.getDropLocation();

            return dropLocation.getPath() != null;

          }

          public boolean importData(TransferHandler.TransferSupport support) {
            if (!canImport(support)) {
              return false;
            }

            JTree.DropLocation dropLocation =
              (JTree.DropLocation)support.getDropLocation();

            TreePath path = dropLocation.getPath();

            Transferable transferable = support.getTransferable();

            String transferData;
            try {
              transferData = (String)transferable.getTransferData(
                DataFlavor.stringFlavor);
            } catch (IOException e) {
              return false;
            } catch (UnsupportedFlavorException e) {
              return false;
            }

            int childIndex = dropLocation.getChildIndex();
            if (childIndex == -1) {
              childIndex = model.getChildCount(path.getLastPathComponent());
            }

            DefaultMutableTreeNode newNode =
              new DefaultMutableTreeNode(transferData);
            DefaultMutableTreeNode parentNode =
              (DefaultMutableTreeNode)path.getLastPathComponent();
            model.insertNodeInto(newNode, parentNode, childIndex);

            TreePath newPath = path.pathByAddingChild(newNode);
            tree.makeVisible(newPath);
            tree.scrollRectToVisible(tree.getPathBounds(newPath));

            return true;
          }
        });

        JScrollPane pane = new JScrollPane(tree);
        f.add(pane, BorderLayout.CENTER);

        JPanel bottom = new JPanel();
        JLabel comboLabel = new JLabel("DropMode");
        String options[] = {"USE_SELECTION",
                "ON", "INSERT", "ON_OR_INSERT"
        };
        final DropMode mode[] = {DropMode.USE_SELECTION,
                DropMode.ON, DropMode.INSERT, DropMode.ON_OR_INSERT};
        final JComboBox combo = new JComboBox(options);
        combo.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            int selectedIndex = combo.getSelectedIndex();
            tree.setDropMode(mode[selectedIndex]);
          }
        });
        bottom.add(comboLabel);
        bottom.add(combo);
        f.add(bottom, BorderLayout.SOUTH);
        f.setSize(300, 400);
        f.setVisible(true);
      }
    };
    EventQueue.invokeLater(runner);
  }
}

끌어서 놓기 지원 및 데이터 전송 API에 대한 자세한 내용은 자바 온라인 자습서의 Introduction to Drag and Drop and Data Transfer 내역을 참조하십시오.

"Java SE" 카테고리의 다른 글

2007/07/23 11:06 2007/07/23 11:06

TRACKBACK :: http://blog.sdnkorea.com/blog/trackback/413

  1. JTree로 드래그-앤-드롭(Adding Drop Support with JTree) 추가

    Tracked from 나나나  삭제

    원본 : http://sdnkorea.com/blog/category/Java%20SE/%EC%B4%88%EA%B8%89시간이 지남에 따라 Swing 구성요소 세트로 끌어서 놓기 기능이 많이 변경되었습니다. 이전 버전에서는 java.awt.dnd 패키지에 기본 API가 있었지만(java.awt.datatransfer의 지원) 초기 사용자 클릭에서 놓기 조작

    2007/09/05 10:38
  2. JTree로 드래그-앤-드롭(Adding Drop Support with JTree) 추가

    Tracked from ★ dingpong의 조그만 휴식 공간 ★  삭제

    JTree로 드래그-앤-드롭(Adding Drop Support with JTree) 추가에 대한 강좌 내용입니다. Java 로 Tree 를 구현 할 수 있습니다. 드래그앤 드롭도 되고 이미도 삽입 가능하도록 응용해서 구현을 할 수 있습니다. 자바에서 트리 구조 구현에 대해서 궁금하시다면 해당 강좌를 봐주시길 바랍니다. http://w

    2007/09/20 01:15
  3. Adding Drop Support wih Jtree

    Tracked from 男 兒 當 自 强  삭제

    JTree에 대한 좋은 강좌 입니다.

    2007/09/22 14:10
  4. JTree로 드래그-앤-드롭(Adding Drop Support with JTree) 추가

    Tracked from jinsoolife.  삭제

    시간이 지남에 따라 Swing 구성요소 세트로 끌어서 놓기 기능이 많이 변경되었습니다. 이전 버전에서는 java.awt.dnd 패키지에 기본 API가 있었지만(java.awt.datatransfer의 지원) 초기 사용자 클릭에서 놓기 조작까지 끌기 작업의 모든 측면을 정의해야 했습니다. J2SE 1.4는 기능 세트에 따라 향상되고 이전 팁 Dragging Text and Images with Swing에 설명된 API를 업데이트합니다. 이전 A...

    2008/06/24 01:46

댓글을 달아 주세요

  1. 손성엽  수정/삭제  댓글쓰기

    sdnkorea.com엔 유용한 정보가 많은것 같습니다.^^

    2007/09/03 19:03
  2. 신명  수정/삭제  댓글쓰기

    생각보다 정리가 잘 되어 있네요.
    시간내서 천천히 읽어 보아야겠네요.
    아~~ 시간의 압박.. ㅜ.ㅜ'

    2007/09/04 16:41
  3. 장진희  수정/삭제  댓글쓰기

    좋은 팁 감사합니다

    2007/09/05 11:12
  4. 유필성  수정/삭제  댓글쓰기

    자바의 세상으로 우리 함께 여행해요
    좋은정보 감사드려요!!!

    2007/09/06 10:02
  5. 김태형  수정/삭제  댓글쓰기

    이런거 좋습니다.

    2007/09/06 11:53
  6. 김성호  수정/삭제  댓글쓰기

    흠 좋은 팁이군요. 이런것 찾고 있었는 데..
    감사합니다.

    2007/09/06 13:51
  7. 오성모  수정/삭제  댓글쓰기

    좋은 정보 유용하게 활용하도록 할게요

    2007/09/06 18:26
  8. 김광현  수정/삭제  댓글쓰기

    어렵네요.배우려고 하는데...
    차근차근 배우려고 합니다.
    정보 감사합니다.

    2007/09/07 11:26
  9. 이민성  수정/삭제  댓글쓰기

    역시나 어려우..

    2007/09/09 00:17
  10. 이상수  수정/삭제  댓글쓰기

    알기 쉽게 잘 정리되었지만..아직 저한테는 어려운듯 ^^;;

    2007/09/10 14:02
  11. 조강래  수정/삭제  댓글쓰기

    좋은정보 유용하여 긁어갑니다.

    2007/09/10 15:37
  12. 조강래  수정/삭제  댓글쓰기

    좋은정보 유용하여 긁어갑니다.

    2007/09/10 15:37
  13. 고진구  수정/삭제  댓글쓰기

    쉬운 설명으로 읽으면 바로 쏫쏙 이해가 됩니다만.....
    시간이 너무 없어요.
    휴일에 시간내서 잘 읽어 보려구요.

    2007/09/10 22:36
  14. 정호영  수정/삭제  댓글쓰기

    호~ 이벤트 때문에 왔는데, 딱 필요한 내용이 있네요 ^^.
    좋은 정보에 감사드립니다. ^^

    2007/09/11 12:58
  15. 김형국  수정/삭제  댓글쓰기

    해보고 싶었지만 GUI 관련 개발은 자바를 잘 사용할 일이 없었는데..
    음...현재는 사용할 일은 없을꺼같지만 좋은 참고 자료가 된거같네요~

    2007/09/11 14:21
  16. 정성준  수정/삭제  댓글쓰기

    좋은 정보 공유 감사드립니다.
    테스트 해보러 가야겠네요..큭

    2007/09/12 10:39
  17. 고병원  수정/삭제  댓글쓰기

    그저께 수업 때 배운? JTree네요..

    선생님께서 항상 수업 때 예제가 부족하시다고 하셨는데..

    여기에 좋은 게 많은거 같네요.. 햐~

    2007/09/13 09:09
  18. 정백구  수정/삭제  댓글쓰기

    초보인 저도 이해가 잘되네요..

    2007/09/13 14:09
  19. 김문경  수정/삭제  댓글쓰기

    잘 정리된 정보 감사합니다^^

    2007/09/13 21:44
  20. 최선정  수정/삭제  댓글쓰기

    전 초보라서 이해하는데 많이시간이...
    더많은 내공을 싸아야할것같습니다..ㅠㅠ

    2007/09/14 18:04
  21. 김영호  수정/삭제  댓글쓰기

    초보인 제가 인식 하는대 40분 걸렷습니다.
    공부하는 초보에게 큰 도움 입니다. 감사 합니다.

    2007/09/15 07:09
  22. 권미자  수정/삭제  댓글쓰기

    하나하나 알아가는재미가 점점 생기네요..

    2007/09/15 19:06
  23. 이재성  수정/삭제  댓글쓰기

    ^^GUI에 관련해서 자바를 잘 사용할 일이 없었는데..
    좋은 참고가 되었습니다. 앞으로 자주 와서 좋은 글도
    얻고 기회가 된다면 글도 올렸으면 좋겠네요

    2007/09/17 08:54
  24. 차진국  수정/삭제  댓글쓰기

    문과 출신이라 그런가...초급 카테고리인데도 어렵네요. tt;;

    2007/09/18 13:24
  25. 박정숙  수정/삭제  댓글쓰기

    좋은 정보 감사해요~

    2007/09/19 03:23
  26. 김덕경  수정/삭제  댓글쓰기

    좋은자료 많이 많이 올려주세요..감사

    2007/09/19 06:45
  27. 성덕경  수정/삭제  댓글쓰기

    제가 찾던 정보네요. 감사합니다.

    2007/09/19 13:12
  28. 김갑연  수정/삭제  댓글쓰기

    정보의 소중함을 다시한번 느끼네요. 감사 합니다^^

    2007/09/19 19:21
  29. 이종민  수정/삭제  댓글쓰기

    직접적인 개발자가 아니라서 정확한 세부사항까지 이해하기는 어려웠지만 나름 좋은 지식공유가 된것 같아서 기쁘네요... 앞으로도 좋은 지식발견이 되었으면 좋겠습니다. 감사합니다...!

    2007/09/19 21:09
  30. 나선미  수정/삭제  댓글쓰기

    자바에 대해서 좀더 잘 알게 됬고 쉽게 정리되어 있는거 같아요~
    유용한 정보 도움 많이 되었습ㄴ ㅣ다^.,^♡

    2007/09/19 22:12
  31. 진유라  수정/삭제  댓글쓰기

    어렵지만 좋은 정보 감사드립니다.

    2007/09/19 22:40
  32. 최인균  수정/삭제  댓글쓰기

    gui 중에 tree 쪽 구현하는게 역시 가장 복잡하지 않나 싶네요^^; 퍼갑니다~!

    2007/09/20 01:16
  33. 임재욱  수정/삭제  댓글쓰기

    정말 유용한 팁입니다...^^

    2007/09/25 22:53
[로그인][오픈아이디란?]

◀ Prev 1  ... 232 233 234 235 236 237 238 239 240  ... 626  Next ▶