2

So, I try to add components to JScrollPane, but they appear only when I hover my mouse above them. This is my code:

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, 10, 40, 40);
        pane.add(add);
        
        
        frame.setSize(480, 860);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}

Do you have any idea why it doesn't work?

Frakcool
  • 10,915
  • 9
  • 50
  • 89

2 Answers2

2
pane.add(add);

Don't add components directly to the scrollpane.

Instead you need to add the component to the viewport of the scroll pane:

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

Read the section from the Swing tutorial on How to Use Scroll Panes to understand how a scroll pane works.

camickr
  • 321,443
  • 19
  • 166
  • 288
2

I see a couple of issues in your code:

  1. public class main {, classes should start with a capital letter, follow Java naming conventions, this will make your code easier to read and follow by you and others, also main is the name of the entry point method for all Java classes, so this might be confusing
  • FirstWordUpperCasedClass
  • firstWordLowerCasedVariable
  • firstWordLowerCasedMethod()
  • ALL_WORDS_UPPER_CASED_CONSTANT
  1. .setBounds(...), in your case you're using the default Layout Managers, so these calls are simply ignored, unless you have a good reason (and in this program you don't) for not using a layout manager, stick to those managers, combine them if needed.

  2. Don't call setSize(...) directly on your JFrame, this will take the window decorations into this size, rather, set a preferredSize for a JPanel and add that JPanel to your JFrame, then call pack() on your JFrame, see: Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? for a more in-depth explanation.

  3. Complementing @camickr in his answer in this same question, and the comment you made there:

But now the button occupies the whole pane.

You're trying to add a JTextField and a JButton, and from the setBounds(...) calls I see that you're trying to add the + button to the right of the JTextField, so in this case, simply add both the JTextField and the JButton to a brand new JPanel and then set the JScrollPane's viewport to this new JPanel.

What @camickr suggested was to set the viewport to the JButton, and that's why you had the JButton taking the whole space.

  1. Create the JTextField with a number param, which will tell Swing the number of columns (or characters) that you want to display on it, rather than an empty one.

  2. And last but not least, place your program on the Event Dispatch Thread (EDT), see point #2 in this answer for more of this.

And after following all those suggestions above, you'd have a better code like this one:

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);
    }
}

I made getPreferredSize(...) return a smaller size right now, because it was a window too big for this example, you can resize it to your own needs.

enter image description here

Frakcool
  • 10,915
  • 9
  • 50
  • 89