我尝试从JComboBox下拉列表中查看JViewPort中是否显示每个项目
(我的星期五加时赛)
编辑:我不想为重复事件实现MouseListener到System.out.print(...)
是不可能通过JList传递JComboBox,由JCombo#Model使用SwingUtilities http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html声明,但是这个APi不在我的...
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();
}
});
}
}
答案 0 :(得分:3)
基本上,你正在寻找list.locationToIndex(如果我理解你的话),就像
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;
....
顺便说一句,还有另一个未传递给列表的属性:预期
list.getVisibleRowCount() == combo.getMaximumRowCount()
回答这个问题:第一个/最后一个,包括在内的所有项目都是可见的,所有上面和下面的项目都不可见; - )
答案 1 :(得分:2)
如果要获得组合框中可见的元素,我在这里有一个算法你可以使用
Point pt = viewport.getViewPosition();
int rowCount = fontsBox.getMaximumRowCount();
int rowsize = viewport.getSize().height / rowCount;
System.out.println("viewport.getHeight()="+ viewport.getHeight()
+"; viewport.getViewSize().getHeight()="+ viewport.getViewSize().getHeight()
+"; rowsize=" + rowsize+"; pt="+pt);
int firstVisibleElementIndex = pt.y/rowsize;
int lastVisibleElementIndex = firstVisibleElementIndex + (rowCount-1);
System.out.println("firstVisibleElementIndex="+ firstVisibleElementIndex
+"; lastVisibleElementIndex="+lastVisibleElementIndex);
检查出来它会返回您的第一个和最后一个可见元素,然后由您决定使用它们。
编辑:这只是一个基于给定示例的快速(和讨厌)解决方案。有关更好的解决方案,请参阅@kleopatra的解决方案。
答案 2 :(得分:1)
将侦听器从ItemListener
更改为ActionListener
似乎可以为箭头键和单击提供预期的结果:
fontsBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
manItemInCombo();
}
});
答案 3 :(得分:0)
谢谢,但是你的假设不正确,这里是输出,仍然我无法测试ViewPort是否包含Item或者没有正确,没办法,我必须返回我的原始声明,因为那显示第一个可见项正确phaaaa
编辑感谢@Anthio Accioly正确消化Changing the listener from ItemListener to ActionListener
来自ItemListener
的错误输出
1stIndex = 0, LastIndex = 2, SelectedItem1 = two, Value = one, two, three//ok
1stIndex = 0, LastIndex = 2, SelectedItem1 = three, Value = one, two, three//ok
1stIndex = 0, LastIndex = 2, SelectedItem1 = four, Value = one, two, three//wrong
1stIndex = 1, LastIndex = 3, SelectedItem1 = five, Value = two, three, four//wrong
1stIndex = 2, LastIndex = 4, SelectedItem1 = six, Value = three, four, five//wrong
1stIndex = 3, LastIndex = 5, SelectedItem1 = seven, Value = four, five, six//wrong
1stIndex = 4, LastIndex = 6, SelectedItem1 = six, Value = five, six, seven//ok
1stIndex = 4, LastIndex = 6, SelectedItem1 = five, Value = five, six, seven//ok
1stIndex = 4, LastIndex = 6, SelectedItem1 = four, Value = five, six, seven//wrong
1stIndex = 3, LastIndex = 5, SelectedItem1 = three, Value = four, five, six//wrong
1stIndex = 2, LastIndex = 4, SelectedItem1 = two, Value = three, four, five//wrong
1stIndex = 1, LastIndex = 3, SelectedItem1 = one, Value = two, three, four//wrong
和ActionListener
1stIndex = 0, LastIndex = 2, SelectedItem1 = two, Value = one, two, three
1stIndex = 0, LastIndex = 2, SelectedItem1 = three, Value = one, two, three
1stIndex = 1, LastIndex = 3, SelectedItem1 = four, Value = two, three, four
1stIndex = 2, LastIndex = 4, SelectedItem1 = five, Value = three, four, five
1stIndex = 3, LastIndex = 5, SelectedItem1 = six, Value = four, five, six
1stIndex = 4, LastIndex = 6, SelectedItem1 = seven, Value = five, six, seven
1stIndex = 4, LastIndex = 6, SelectedItem1 = six, Value = five, six, seven
1stIndex = 4, LastIndex = 6, SelectedItem1 = five, Value = five, six, seven
1stIndex = 3, LastIndex = 5, SelectedItem1 = four, Value = four, five, six
1stIndex = 2, LastIndex = 4, SelectedItem1 = three, Value = three, four, five
1stIndex = 1, LastIndex = 3, SelectedItem1 = two, Value = two, three, four
1stIndex = 0, LastIndex = 2, SelectedItem1 = one, Value = one, two, three
已编辑的代码
import java.awt.*;
import java.awt.event.*;
import javax.accessibility.Accessible;
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.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
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 Accessible a = fontsBox.getUI().getAccessibleChild(fontsBox, 0);
if (a instanceof javax.swing.plaf.basic.ComboPopup) {
final JList list = ((javax.swing.plaf.basic.ComboPopup) a).getList();
final Rectangle rect = list.getVisibleRect();
final int first = list.locationToIndex(rect.getLocation());
final int last = first + fontsBox.getMaximumRowCount() - 1;
String selectedItem = fontsBox.getSelectedItem().toString();
System.out.println("1stIndex = " + first + ", LastIndex = "
+ last + ", SelectedItem1 = " + selectedItem
+ ", Value = " + fontsBox.getItemAt(first).toString()
+ ", " + fontsBox.getItemAt(first + 1).toString()
+ ", " + fontsBox.getItemAt(first + 2).toString());
}
}
}
public static void main(String arg[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
ItemVisibleRecCombo ivrc = new ItemVisibleRecCombo();
}
});
}
}