简体   繁体   中英

Java swing JScrollPane not scrollable

This is the add(main) version

This is the add(scroll) version

Im trying to get a window full of lables and make it scrollable, this is my code for that purpose:

public class JobHistoryListScreen extends JFrame implements View
{

    @Override
    public void showScreen()
    {
        setSize(800, 800);
        setLayout(new BorderLayout());
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JPanel main = new JPanel();
        main.setSize(500,500);
        JScrollPane scroll = new JScrollPane(main,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scroll.setSize(500,500);

        //Font
        //Font david50 = new Font("David", Font.BOLD, 50);

        for(int i=0; i<1000; i++)
        {
            JLabel empty = new JLabel("No jobs to display!");
            empty.setBounds(0,i+250,400,100);
            empty.setFont(david50);
            main.add(empty);
        }
        add(main);
        setVisible(true);
    }

    public static void main(String[] args) {
        JobHistoryListScreen v = new JobHistoryListScreen();
        v.showScreen();
    }
}

For some reason the window gets filled with the labels but is not scrollable at all.

Learn about layout managers. Refer to Laying Out Components Within a Container . Default for JPanel is FlowLayout and because the JPanel is inside a JScrollPanel , the labels will not wrap. And since you set the horizontal scroll bar policy to NEVER, there is no horizontal scroll bar and hence you cannot scroll horizontally. Try using BoxLayout to display all the labels one under the other. Alternatively you could use a GridLayout with 0 (zero) rows and 1 (one) column. Refer to the tutorial for more details.

EDIT

Here is my modified version of your code. Explanatory notes appear after the code.

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;

public class JobHistoryListScreen implements Runnable {
    private JFrame  frame;

    @Override // java.lang.Runnable
    public void run() {
        showScreen();
    }

    public void showScreen() {
        frame = new JFrame("Jobs");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        JPanel main = new JPanel(new GridLayout(0, 1));
        JScrollPane scroll = new JScrollPane(main,
                                             JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                             JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scroll.setPreferredSize(new Dimension(500, 500));
        Font david50 = new Font("David", Font.BOLD, 50);
        for(int i=0; i<1000; i++) {
            JLabel empty = new JLabel("No jobs to display!");
            empty.setFont(david50);
            main.add(empty);
        }
        frame.add(scroll);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        JobHistoryListScreen v = new JobHistoryListScreen();

        // Launch Event Dispatch Thread (EDT)
        EventQueue.invokeLater(v);
    }
}
  • I don't know what interface View is so I removed that part.
  • No need to extend class JFrame .
  • No need to explicitly call setSize() on JFrame . Better to call pack() .
  • Default content pane for JFrame is JPanel and default layout manager for that JPanel is BorderLayout so no need to explicitly set.
  • No need to call setSize() on JPanel .
  • Call setPreferredSize() rather than setSize() on JScrollPane .
  • Add the JScrollPane to the JFrame and not the JPanel .
  • No need to call setBounds() because GridLayout handles this.
  • Explicitly launch EDT (Event Dispatch Thread) by calling invokeLater() .

Here is a screen capture of the running app. Note the vertical scroll bar.

工作清单.png

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM