2017-04-25 10 views
0

나는 상황에 대해 약간 혼란 스럽다. DefaultListModel과 ListRenderer를 확장 한 ListModel을 만들어 JList에 사용자 정의 셀을 표시하는 ListCellRenderer을 구현했습니다. 셀은 JLabel 및 JButton이 포함 된 JPanel을 확장하는 클래스에서 생성 된 일부 객체입니다.JList 객체 내의 MouseEvents

내 문제는 마우스 이벤트와 관련이 있습니다. JList의 셀 내부에서 JButton을 클릭 할 때 특정 이벤트를 트리거하려고하지만 마우스 소스 지점을 JButton의 셀 지점과 일치시키는 방법을 알 수 없습니다. 각 색인에서 좀 더 정확히 말하면, 마우스 리스너를리스트에 추가했지만 마우스 포인트가 JButton의 경계 안에 있다면 액션을, 데이터 아이템에 대해서는 액션을 추가합니다. 나는이의 원인을 찾기 위해 몇 가지 지문을 추가,하지만 그 전에 몇 가지 코드는 구조를 강조하기 위해 : 여기

public WifiGuiHandler(JButton reference) { 
    btnReference = reference; 
    wifiListener = new WifiListener(); 
    wifiPopupContainer = new JScrollPopupMenu("Connections."); 
    wifiPopupContainer.setMaximumVisibleRows(7); 
    connectionsHolder = new ArrayList<>(); 
    listOfConnections = new JList(); 
    listOfConnectionsModel = new ListModel(connectionsHolder); 
    listOfConnectionsRenderer = new ListRenderer(); 
    listOfConnections.setModel(listOfConnectionsModel); 
    listOfConnections.setCellRenderer(listOfConnectionsRenderer); 
    wifiPopupContainer.add(listOfConnections); 
    wifiPopupContainer.pack(); 
    initializeTestVariables(); 
    initializeListeners(); 
} 

, JButton의 소요 그것에 마우스 수신기를 추가하는 클래스의 생성자, 트리거 있음을 1 개의 컴퍼넌트만을 가지는 JPopupMenu의 외관. 전체의 데이터를 보관 유지하는 JList 또한 ArrayList를 데이터 항목과 ListModel에 연결합니다.

public void initializeTestVariables() { 
    for (int i = 0; i <= 10; i++) { 
     WifiItem item = new WifiItem("Connection number " + i + ".", i); 
     connectionsHolder.add(item); 
    } 
} 

데이터 항목 설정.

public void initializeListeners() { 

    listOfConnections.addMouseListener(new MouseAdapter() { 
     public void mouseClicked(MouseEvent e) { 
      int index = listOfConnections.locationToIndex(e.getPoint()); 
      if (index >= 0) { 
       WifiItem item = (WifiItem) ((ListModel) listOfConnections.getModel()).getElementAt(index); 
       System.out.println("Button of " + item.getConnectionName() + " is at location :" + item.getButton().getLocation()); 
       System.out.println("Button has the bounds : " + item.getButton().getBounds()); 
       System.out.println("MouseEvent detected on : " + e.getPoint().getLocation()); 
       if (item.getButton().getBounds().contains(e.getPoint())) { 
        item.connectHere(); 
       } 
       if (item.getButton().isVisible()) { 
        System.out.println("Set expanded on : " + item.getConnectionName()); 
        item.setExpandedState(false); 
        listOfConnectionsModel.fireContentsChanged(item, index, index); 
        updateGui(false); 
       } else { 
        System.out.println("Set expanded on : " + item.getConnectionName()); 
        listOfConnectionsModel.fireContentsChanged(item, index, index); 
        item.setExpandedState(true); 
        updateGui(false); 
       } 
      } 
     } 

    }); 
    btnReference.addMouseListener(new MouseAdapter() { 
     public void mouseClicked(MouseEvent e) { 
      updateGui(true); 
     } 
    }); 

} 

여기는 혼동이 생기는 곳입니다. 마우스 이벤트 위치/포인트에서 데이터 항목 (WifiItem)을 올바르게 가져옵니다. 그러나 WifiItem의 JButton을 클릭하면 해당 메소드가 트리거되지 않습니다. 실제로 JButton이 있다는 것을 감지하지 못하는 것처럼 보입니다. . 또한 인쇄물을 설정하고 이상한 점이 있다면 JButton의 점은 실제로 다르지만 실제로 문제는있는 것처럼 보입니다. 더 정확하게 프로그램의 출력으로부터 :

연결 번호 2의

버튼 위치이다 java.awt.Point의

버튼 경계를 갖는다 X = 137, Y는 33 =] : 자바 연결 java.awt.Point의 [Y = 172, X = 125]

버튼 : .awt.Rectangle

검출 된 MouseEvent [X = 137, Y 33, 폭 = 90, 26 = 높이 =] 3. 위치에 있습니다 : java.awt.Point [x = 137, y = 33]

버튼이 있습니다. 그 경계 : java.awt.Point의 [Y = 172, X = 125]

: java.awt.Rectangle의

검출 된 MouseEvent [X = 137, Y 33, 폭 = 90, 26 = 높이 =]

위의 마우스 이벤트 포인트는 JButton 자체에 실제로 위치했지만 실제로는 나타나지 않았습니다. 다른 이상한 사실로서, 목록의 첫 번째 요소의 JButton을 클릭 할 때만 필요한 마우스 동작이 트리거됩니다.

다른 인쇄물은 모든 JButton이 동일한 Point와 Rectangle을 가지고 있음을 보여주었습니다. JList에는 10 개의 항목이 있는데, 각 항목이 올바르게 표시됩니다. JButton의 모든 위치가 같은 위치에 있습니까? 여기에 핵심 요소가 빠져 있어야합니다. 다른 게시물을보고 SwingUtilities로 요점을 변환하고 JList에서 모든 마우스 리스너를 제거한 다음 데이터 항목에 추가했습니다.

요약하면 문제는 목록에 올바른 데이터 항목의 이벤트가 트리거된다는 것입니다. 즉, 해당 항목에 대한 올바른 색인을 가져옵니다. 그러나 마우스 이벤트가 JButton에서 발생하면 목록 내의 모든 데이터 항목 중 하나라도 필요한 효과를 트리거하지는 않습니다 (요점은 단추의 범위를 벗어나지 않아도됩니다).

답변

0

더 정확히 말해서 마우스 수신기를 추가했지만 마우스 포인트가 JButton의 경계 안에 있으면 트리거를 실행하고 데이터 항목에있는 경우 다른 동작을 수행하려고합니다.

더 쉬운 해결책은 JTable을 사용하는 것입니다. 데이터는 열로 구분되며 JTable에는 선택한 행/열을 알 수있는 API가 있습니다.

버튼의 렌더러/편집기로 Table Button Column을 사용할 수 있습니다.

편집 :

단지 내가 마우스 포인트의 전환이 꺼져처럼

는 소리 필요한 마우스 액션을 트리거 않는 목록의 첫 번째 요소의하는 JButton을 클릭합니다.

어떻게 JButton이 모두 같은 위치에 있습니까?

다시 버튼 위치는 렌더러 패널과 관련이 있습니다. 패널 자체는 JList의 행을 기준으로합니다. 그래서 당신은 행 인덱스가 필요하고 이전 행의 높이를 계산에 추가해야한다고 생각합니다.

+0

내일 JTable로 전환하려고합니다. 먼저 데이터 항목을 사용하는 것으로 간주했지만 데이터 항목 클래스 (WifiItem)에서 버튼이 라벨 아래에 정렬되어 있기 때문에 데이터가 열에서 분리되기를 원하지 않습니다. 디자인을 위해 텍스트를 표시합니다 (팀원이 제안한대로). 또한 코드에서 볼 수 있듯이 항목을 클릭하면 '최소화'(단추를 숨기고 레이블 만 표시되도록 크기가 조정 됨) 또는 '최대화'(단추가 표시되고 크기가 확장 됨)됩니다. 어쨌든, 제안 해 주셔서 고맙습니다. 내일 다시 시도하고 결과로 돌아올 것입니다. – g0dzax

+0

@ g0dzax,'버튼이 텍스트를 표시하는 레이블 아래에 정렬됩니다.'- JTable이 작동하지 않습니다. 추가 의견은 편집을 참조하십시오. – camickr

+0

계산에 높이가 추가 된 아이디어는 훌륭합니다. 나는 그것을 시도 할 것이다. – g0dzax