0

我正在尝试在自定义弹出菜单中上下移动时自动更新滚动窗格上的滚动条。但它不起作用。看看下面我的完全可运行的示例,我添加了基于 JPopupMenu 的自定义组件和一个 JComboBox 进行比较。如您所见,在 JComboBox 中,滚动窗格会更新其位置,因此当前选定的项目始终可见。但这不适用于我的组件,我不知道如何设置。

我的SSCCE:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.ScrollPane;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;


public class ScrollFocus extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ScrollFocus();

            }
        });
    }

    public ScrollFocus() {
        this.setLayout(new BorderLayout());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Vector<String> values = new Vector<>();
        values.add("a");
        values.add("b");
        values.add("c");
        values.add("d");
        values.add("e");
        values.add("f");
        values.add("g");
        values.add("h");
        values.add("i");
        values.add("j");
        JComboBox<String> comboBox = new JComboBox<>(values);
        JScrollPane scrollPane = new JScrollPane(comboBox);
        this.add(scrollPane, BorderLayout.NORTH);

        CustomTextField customTextField = new CustomTextField();
        this.add(customTextField, BorderLayout.CENTER);
        pack();
        setVisible(true);
    }

    class CustomTextField extends JTextField implements FocusListener {

        private CustomPopup customPopup = new CustomPopup();

        public CustomTextField() {
            this.addFocusListener(this);
            this.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    System.out.println("printing...");
                    setPopupSize();
                    setPosition();
                    customPopup.setVisible(true);

                    if(e.getKeyCode() == KeyEvent.VK_UP) {
                        if(customPopup.index < customPopup.getListSize())
                            customPopup.setSelectedIndex(customPopup.index--);
                    }
                    else if(e.getKeyCode() == KeyEvent.VK_DOWN){
                        if(customPopup.index >= 0)
                            customPopup.setSelectedIndex(customPopup.index++);
                    }
                }
            });
        }

        public void setPopupSize() {
            customPopup.setPopupSize(new Dimension(this.getWidth(), 110));
        }

        public void setPosition() {
            customPopup.setLocation(this.getLocation().x, this.getLocation().y);
        }

        @Override
        public void focusGained(FocusEvent e) {

        }

        @Override
        public void focusLost(FocusEvent e) {
            customPopup.setVisible(false);
        }


        class CustomPopup extends JPopupMenu {
            String[] values = new String[]{"Value1", "Value2", "Value3", "Value4", "Value5", "Value6", "Value7",
                    "Value8","Value9", "Value10", "Value11", "Value12", "Value13", "Value14", "Value15", "Value16",};
            JList<String> list = new JList<>(values);
            JScrollPane scrollPane = new JScrollPane(list);
            public int index = 0;

            public CustomPopup() {
                this.setLayout(new GridLayout(0,1));
                this.add(scrollPane);
                pack();
            }

            public void setSelectedIndex(int index) {
                list.setSelectedIndex(index);
            }

            public int getListSize() {
                return values.length;
            }
        }
    }
}
4

1 回答 1

2

在 JComboBox 中,滚动窗格会更新其位置,因此当前选定的项目始终可见。但这不适用于我的组件,我不知道如何设置。

list.setSelectedIndex(index);
list.ensureIndexIsVisible(index); // added

另外,不要使用 KeyListener。Swing 被设计为与键绑定一起使用。阅读 Swing 教程中有关如何使用键绑定的部分以获取更多信息。

于 2013-05-31T16:19:44.440 回答