2017-04-25 58 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