JComboBox 确定项目是否在下拉列表中可见/不可见
- 作者: 弱水三千_只留一瓢
- 来源: 51数据库
- 2023-01-29
问题描述
我尝试从 JComboBox 下拉列表中确定每个项目在 JViewPort 中是否可见
I tried to determime for every Items if are or not visible in the JViewPort from JComboBox drop-down list
(我的星期五加班)
我不想为 System.out.print(...) 的重复事件实现 MouseListener
I don't want to implements MouseListener for Repeats events to System.out.print(...)
不可能将 JComboBox 与 JList 一起传递,由 JCombo#Model 使用 SwingUtilities http://www.51sjk.com/Upload/Articles/1/0/341/341573_20230129092401963.html ,但是这个 API 不在我的范围内......
isn't possible pass JComboBox with JList, declared by JCombo#Model by using SwingUtilities http://www.51sjk.com/Upload/Articles/1/0/341/341573_20230129092401963.html , but this APi is out of my...
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ItemVisibleRecCombo extends JFrame { private static final long serialVersionUID = 1L; private JComboBox fontsBox; public ItemVisibleRecCombo() { String[] numbers = {"one", "two", "three", "four", "five", "six", "seven"}; fontsBox = new JComboBox(numbers); fontsBox.setSelectedItem(0); fontsBox.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { manItemInCombo(); } } }); fontsBox.setModel(new DefaultComboBoxModel(numbers)); fontsBox.setMaximumRowCount(3); add(fontsBox, BorderLayout.CENTER); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setPreferredSize(new Dimension(400, 60)); setLocation(200, 105); pack(); setVisible(true); } private void manItemInCombo() { if (fontsBox.getItemCount() > 0) { final Object comp = fontsBox.getUI().getAccessibleChild(fontsBox, 0); if ((comp instanceof JPopupMenu)) { final JList list = new JList(fontsBox.getModel()); final JPopupMenu popup = (JPopupMenu) comp; final JScrollPane scrollPane = (JScrollPane) popup.getComponent(0); final JViewport viewport = scrollPane.getViewport(); final Rectangle rect = popup.getVisibleRect(); Point pt = viewport.getViewPosition(); for (int i = 0; i < list.getModel().getSize(); i++) { pt = list.indexToLocation(i); System.out.print(pt + " - "); rect.setLocation(rect.x - pt.x, rect.y - pt.y); System.out.println(new Rectangle(viewport.getExtentSize()).contains(rect)); } } } } public static void main(String arg[]) { java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { ItemVisibleRecCombo ivrc = new ItemVisibleRecCombo(); } }); } }
推荐答案
基本上,您正在寻找 list.locationToIndex (如果我理解正确的话),类似
Basically, you'r looking for list.locationToIndex (if I understood you correctly), something like
Accessible a = fontsBox.getUI().getAccessibleChild(fontsBox, 0); if (a instanceof javax.swing.plaf.basic.ComboPopup) { JList list = ((javax.swing.plaf.basic.ComboPopup)a).getList(); Rectangle rect = list.getVisibleRect(); int first = list.locationToIndex(rect.getLocation()); // similar for last, at the lower edge of the visible rect, left as exercise <g> // Edit: as of @Boro's comment, last is easier calculated with maxRowCount int last = first + fontsBox.getMaximumRowCount() - 1; ....
顺便说一句,另一个未传递到列表中的属性:本来可以预期
BTW, yet another property that's not passed on to the list: would have expected
list.getVisibleRowCount() == combo.getMaximumRowCount()
回答这个问题:第一个/最后一个之间的所有项目(包括在内)都是可见的,第一个上方和最后一个下方的所有项目都不可见;-)
To answer the question: all items between first/last, inclusively, are visible, all items above first and below last not visible ;-)