Java 无法在 JPanel 中将 JTextField 集中在 JPanel 中作为 JScrollPane 中的视口

Java can't focus on JTextField inside JPanel inside JPanel as viewport in JScrollPane

不得不承认,可能这个问题怎么写的有点奇怪,但我会在这里解释一下:

我有一个 JScrollPane,我在其中正确添加了一个 JPanel,假设现在 JScrollPane 变量是 "JSP",JPanel 是 "JP"

在我的 JP 中,我有一个 JPanel 的 ArrayList(我们称之为 AJP),我可以从 JSP 外部控制可见性,我可以通过单击不同的按钮来控制这种可见性,每个按钮都是 "linked" 带有一个数字,所以如果我单击 button1,第一个 AJP 元素的可见性设置为 true,所有其他元素设置为 false。

这些 AJP 元素中的每一个都有不同的元素,例如,第一个位置的 AJP 有两个 JTextField 和 1 个 JButton,位置 2 的 AJP 只有一个 JTextField。

事实是,我似乎无法单击 JButton 或编辑 JTextField,就像鼠标无法聚焦它们一样,我会 post 在这里编写一些代码

这是包含 JP 的 class,它是 JScrollPane 的扩展

private int x, y, width, height;

private JPanel internalPanel = new JPanel();
private ArrayList<KPanel> kPanels = new ArrayList<KPanel>();

JViewport viewport = new JViewport();

public KScrollPanel(int x, int y, int width, int height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;


    this.internalPanel.setBorder(new LineBorder(Color.black, 1));
    this.internalPanel.setSize(new Dimension(this.width - 10, this.height - 10));
    this.internalPanel.setPreferredSize(new Dimension(this.width - 10, this.height - 10));

    this.setSize(new Dimension(this.internalPanel.getWidth() + 10, this.internalPanel.getHeight() + 10));
    this.setPreferredSize(this.internalPanel.getSize());

    this.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    this.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

    viewport.add(this.internalPanel);

}

另一个是 class,它实际上由 class KScrollPanel 中的 ArrayList 组成,我刚刚 posted,如您所见,方法初始化动态添加元素( KButton 和 KTextFields 是两个 classes extendind JButton and JTextField)

这个class当然是JPanel的扩展

private int x, y, width, height;

KTextField textfield_nodeName, textfield_relationshipName;
KButton button_saveNode, button_saveRelationship;

public KPanel(int x, int y, int width, int height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    initGUI();
}

public KPanel() {

}

public void initGUI() {
    this.setBounds(this.x, this.y, this.width, this.height);
    this.setBorder(new LineBorder(Color.gray, 1));
}

public void initialize(String type) {
    switch(type) {
        case "Node": 
            textfield_nodeName = new KTextField(5, 5, 200, 30);
            this.add(textfield_nodeName);
            button_saveNode = new KButton(5, 35, 200, 30, "Save Node");
            this.add(button_saveNode);
            break;
        case "Relationship": 
            textfield_relationshipName = new KTextField(5, 5, 250, 30);
            this.add(textfield_relationshipName);

            break;
    }
    this.revalidate();
    this.repaint();
}

为什么要扩展 JScrollPane?

为什么要创建 JViewport?

为什么要创建一个内部 JPanel 以添加到视口?

您不应该尝试调整任何组件的大小。布局管理器将确定每个组件的大小。

您要添加到滚动面板的组件应该与滚动面板分开创建。然后就可以在创建的时候设置这个组件的Border了。

JViewport viewport = new JViewport();

...

viewport.add(this.internalPanel);

所以在我看来,您创建了一个内部面板并将其添加到视口,但您从未将视口添加到滚动窗格,因此没有要显示的组件。

所以我的建议是摆脱自定义 JScrollPane class 然后就不需要扩展它了,因为您没有向 class 添加任何功能。只需按照设计使用的方式使用 JScrollPane:

JPanel internalPanel = new JPanel();
internalPanel.setBorder(...);
internalPanel.add(...);
JScrollPane scrollPane = new JScrollPane( internalPanel );
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);