2017-04-25 27 views
0

對於我所處的情況,我有點困惑。我創建了一個ListModel,擴展了DefaultListModel和ListRenderer,實現了ListCellRenderer,用於在JList中顯示自定義單元格。這些單元格是從擴展JPanel的類創建的一些對象,它們包含JLabel和JButton。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,並增加了一個鼠標偵聽器,它的類,即觸發一個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的Point始終是相同的,即使它實際上是不同的,這似乎是問題所在。更確切地說,從該程序的輸出:

的連接號碼2.

按鈕在位置:java.awt.Point中[X = 137,Y = 33]

按鈕具有界限:JAVA .awt.Rectangle [X = 137,Y = 33,寬度= 90,高度= 26]

的MouseEvent檢測到:連接的java.awt.Point中[X = 172,Y = 125]

按鈕number is 3. is at location:java.awt.Point [x = 137,y = 33]

Button has t他界定:java.awt.Rectangle中[X = 137,Y = 33,寬度= 90,高度= 26]

的MouseEvent檢測到:java.awt.Point中[X = 172,Y = 125]

上面的鼠標事件點實際上位於JButton本身,只是它沒有得到。另一個奇怪的事實是,只有當我點擊列表的FIRST元素的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