JScrollPane 组件是不可见的,直到我单击它们

问题描述

因此,我尝试将组件添加JScrollPane,但仅当我将鼠标悬停在它们上方时它们才会出现。 这是我的代码

package com.alex.apps;

import java.awt.cardlayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneLayout;

public class main {

    public static void main(String[] args) {
        // Todo Auto-generated method stub
        //GetPageInfo gpi=new GetPageInfo();
        JFrame frame=new JFrame("Bookmark");
        JScrollPane pane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        frame.setContentPane(pane);
        
        JTextField text=new JTextField();
        text.setBounds(0,10,400,40);
        pane.add(text);
        
        JButton add=new JButton("+");
        add.setBounds(403,40,40);
        pane.add(add);
        
        
        frame.setSize(480,860);
        frame.setResizable(false);
        frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}

你知道为什么它不起作用吗?

解决方法

pane.add(add);

不要直接向滚动窗格添加组件。

相反,您需要将组件添加到滚动窗格的视口:

//pane.add(add);
pane.setViewportView( add );

阅读有关 How to Use Scroll Panes 的 Swing 教程中的部分,了解滚动窗格的工作原理。

,

我发现您的代码中有几个问题:

  1. public class main {,类应该以大写字母开头,跟在Java naming conventions后面,这样会让你和其他人更容易阅读和理解你的代码,而且main是所有 Java 类的入口点方法,所以这可能会令人困惑
  • FirstWordUpperCasedClass
  • firstWordLowerCasedVariable
  • firstWordLowerCasedMethod()
  • ALL_WORDS_UPPER_CASED_CONSTANT
  1. .setBounds(...),在您的情况下,您使用的是默认的 Layout Managers,因此这些调用将被简单地忽略,除非您有充分的理由(在此程序中您没有)如果不使用布局管理器,请坚持使用这些管理器,并在需要时将它们组合起来。

  2. 不要直接在您的 setSize(...) 上调用 JFrame,这会将窗口装饰调整到这个大小,而是为 preferredSize 设置一个 JPanel并将该 JPanel 添加到您的 JFrame,然后在您的 pack() 上调用 JFrame,请参阅:Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? 以获得更深入的解释。

  3. 在同一个问题的 answer 中补充 @camickr,以及您在那里发表的评论:

但现在按钮占据了整个窗格。

您正在尝试添加 JTextFieldJButton,并且从 setBounds(...) 调用我看到您正在尝试添加 + JTextField 右侧的按钮,因此在这种情况下,只需添加 将 JTextFieldJButton 都设置为全新的 JPanel,然后将 JScrollPane 的视口设置为这个新的 JPanel

@camickr 建议将视口设置为 JButton,这就是您让 JButton 占据整个空间的原因。

  1. 创建带有数字参数的 JTextField,它将告诉 Swing 您想要在其上显示的列(或字符)数,而不是空的。

  2. 最后但并非最不重要的一点是,将您的程序放在 Event Dispatch Thread (EDT) 上,有关详细信息,请参阅 this answer 中的第 2 点。

在遵循上述所有建议之后,您将拥有一个更好的代码:

import java.awt.Dimension;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class ScrollPaneSample {
    private JFrame frame;
    private JPanel pane;
    private JScrollPane scrollPane;
    private JTextField text;
    private JButton add;
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ScrollPaneSample()::createAndShowGUI);
    }
    
    private void createAndShowGUI() {
        frame = new JFrame("Bookmark");
        pane = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200,100);
            }
        };
        scrollPane = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

        text = new JTextField(10);
        pane.add(text);

        add = new JButton("+");
        pane.add(add);

        scrollPane.setViewportView(pane);
        
        frame.add(scrollPane);
        
        frame.pack();
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

我现在让 getPreferredSize(...) 返回一个较小的尺寸,因为对于这个例子来说它是一个太大的窗口,你可以根据自己的需要调整它的大小。

enter image description here