對於我所處的情況,我有點困惑。我創建了一個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上的任何數據項列表中,它不會觸發所需的效果(即使它應該是,該點不在按鈕的範圍內)。
明天我會嘗試切換到JTable,我首先考慮使用它,但我不希望我的數據在列中分開,因爲在我的數據項類(WifiItem)中,該按鈕在標籤下方對齊顯示文字,用於設計目的(由團隊成員建議)。此外,如代碼中所示,當您點擊這些項目時,它將「最小化」(隱藏按鈕並調整大小,使其僅顯示標籤)或「最大化」(顯示按鈕並擴大其大小)。感謝您的建議,無論如何,我會明天嘗試,並帶來結果。 – g0dzax
@ g0dzax,'該按鈕在顯示文本的標籤下方對齊,' - JTable不適用於此。請參閱編輯以獲取其他評論 – camickr
將高度添加到計算中的想法非常出色。我會嘗試。 – g0dzax