Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java JScrollpane not visible

Tags:

java

swing

I'm trying to display a series of buttons in a JScrollpane. Reading around, I managed to exit with this code, but nothing is displayed. I do not understand a possible mistake. Thank you for help

As suggested I made some changes, I edited but not works

EDITED or I'm stupid, or here is some other problem. Here is my complete code with the output image

public class Main extends javax.swing.JFrame {
    private final JPanel gridPanel;

    public Main() {
        initComponents();
        // EXISTING PANEL
        gridPanel = new JPanel();
        JScrollPane scrollPane = new JScrollPane(gridPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        JPanel borderLayoutPanel = new JPanel(new BorderLayout());
        borderLayoutPanel.add(scrollPane, BorderLayout.CENTER);

        this.Avvio();
    }

    private void Avvio() {
        JPanel pane = new JPanel(new GridBagLayout());
        pane.setBorder(BorderFactory.createLineBorder(Color.BLUE));
        pane.setLayout(new GridBagLayout());

        for (int i = 0; i < 10; i++) {
            JButton button;
            GridBagConstraints c = new GridBagConstraints();
            c.fill = GridBagConstraints.HORIZONTAL;
            c.anchor = GridBagConstraints.PAGE_START;

            button = new JButton("Button 1");
            c.weightx = 0.5;
            c.gridx = 0;
            c.gridy = i;
            pane.add(button, c);

            button = new JButton("Button 2");
            c.gridx = 1;
            c.gridy = i;
            pane.add(button, c);

            button = new JButton("Button 3");
            c.gridx = 2;
            c.gridy = i;
            pane.add(button, c);

        }
        gridPanel.add(pane);
        gridPanel.revalidate();
        gridPanel.repaint();

    }
}

enter image description here

like image 629
user2847219 Avatar asked Dec 12 '17 14:12

user2847219


2 Answers

Alright, from your comments in another answer:

No problem for compile , simply the Jpanel is empty. The buttons does not appear.

After calling this.Avvio(); you must call:

this.add(scrollPane);
this.pack();

This will produce the following outputs (before and after resizing it):

enter image description hereenter image description here

But there's still no JScrollPanel

This at least solves the first problem, however you have more errors in your code, some of which have already been commented in other answers:

  1. You're extending JFrame, this isn't needed as you can create a JFrame instance / object and use it later. You're never changing the JFrame's behavior and that's why it's not needed to extend it. See Extends JFrame vs. creating it inside the program for more information about this.

  2. You're not calling pack() nor setSize(...) this creates a tiny window, which you need to manually resize. Call pack() recommended before making your JFrame visible. (As suggested at the beginning of this answer).

  3. You're calling .invokeLater() method twice. You need to call it just once, I prefer this way:

     SwingUtilities.invokeLater(() -> new Main()); //Note there is no call to .setVisible(true); as per point #1. It should go later in the program like:  frame.setVisible(true);
    
  4. You're calling gridPanel.revalidate(); and gridPanel.repaint() while it doesn't affect your program, it's not needed as your GUI is still not visible, and thus those calls have no effect on your program, you can safely remove them.

  5. You're creating a new GridBagConstraints object on each iteration of the for loop, you can just change its properties inside it and declaring it outside the for loop, which will make your program better.

After following the above recommendations, you can end up with a code like this one:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class Main {
    private final JPanel gridPanel;
    private JFrame frame;

    public Main() {
        // EXISTING PANEL
        gridPanel = new JPanel();
        JScrollPane scrollPane = new JScrollPane(gridPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        JPanel borderLayoutPanel = new JPanel(new BorderLayout());
        borderLayoutPanel.add(scrollPane, BorderLayout.CENTER);

        this.Avvio();
        
        frame.add(scrollPane);
        frame.pack();
        frame.setVisible(true);
    }

    private void Avvio() {
        JPanel pane = new JPanel(new GridBagLayout());
        pane.setBorder(BorderFactory.createLineBorder(Color.BLUE));
        pane.setLayout(new GridBagLayout());

        for (int i = 0; i < 10; i++) {
            JButton button;
            GridBagConstraints c = new GridBagConstraints();
            c.fill = GridBagConstraints.HORIZONTAL;
            c.anchor = GridBagConstraints.PAGE_START;

            button = new JButton("Button 1");
            c.weightx = 0.5;
            c.gridx = 0;
            c.gridy = i;
            pane.add(button, c);

            button = new JButton("Button 2");
            c.gridx = 1;
            c.gridy = i;
            pane.add(button, c);

            button = new JButton("Button 3");
            c.gridx = 2;
            c.gridy = i;
            pane.add(button, c);

        }
        gridPanel.add(pane);
    }

    public static void main(String args[]) {
        /* Create and display the form */
        SwingUtilities.invokeLater(() -> {
            new Main();
        });
    }
}

Which still produces this output:

enter image description here

BUT... We still can improve it a little more!

We may have two nested for loops, for the GridBagConstraints properties as well as the generation of the buttons:

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;

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

public class ScrollablePaneWithButtons {
    private static final int ROWS = 10;
    private static final int COLS = 3;

    private JFrame frame;
    private JPanel pane;
    private JButton[][] buttons;
    private GridBagConstraints gbc;
    private JScrollPane scroll;
    private JButton[] menuButtons;
    private JPanel menuPane;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ScrollablePaneWithButtons()::createAndShowGui);
    }

    private void createAndShowGui() {
        frame = new JFrame(this.getClass().getSimpleName());

        pane = new JPanel();
        pane.setLayout(new GridBagLayout());
        
        menuPane = new JPanel();
        menuPane.setLayout(new GridLayout(1, 3));

        buttons = new JButton[ROWS][COLS];
        
        menuButtons = new JButton[] {new JButton("Edit"), new JButton("Delete"), new JButton("Sort Fields")};

        gbc = new GridBagConstraints();

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.PAGE_START;
        gbc.weightx = 0.5;

        for (int i = 0; i < ROWS; i++) {
            for (int j = 0; j < COLS; j++) {
                buttons[i][j] = new JButton("Button " + (j + 1));

                gbc.gridx = j;
                gbc.gridy = i;

                pane.add(buttons[i][j], gbc);
            }
        }

        scroll = new JScrollPane(pane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        
        for (JButton b : menuButtons) {
            menuPane.add(b);
        }
        frame.add(scroll);
        frame.add(menuPane, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

And this example is (in my opinion) easier to read and follow up. And this is the output the above code is generating:

enter image description here

You can still choose which code to use, either doing the modifications at the first part of this answer, the second one following the recommendations above or the last one which is shorter.

like image 56
Frakcool Avatar answered Oct 19 '22 15:10

Frakcool


Problems noted:

  • Avvio - the pane layout was reset during each loop. Set it once before the loop.
  • Avvio - the pane was added to the grid pane in each loop. Add it once after the loop.
  • Avvio - the constraints place the buttons in the same grid locations. With the previous two issues fixed, only the last three buttons placed appear.

I'm assuming you want three buttons in a row, so I changed the loop to use the counter as a row counter. The code below will create ten rows of three buttons.

What appears: enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.WindowConstants;


public class Main extends javax.swing.JFrame {
    private JPanel gridPanel;

    public Main() {

        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setSize(600,400);

        //EXISTING PANEL
        gridPanel = new JPanel();
        JScrollPane scrollPane = new JScrollPane(gridPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        JPanel borderLayoutPanel = new JPanel(new BorderLayout());
        borderLayoutPanel.add(scrollPane, BorderLayout.CENTER);

        this.Avvio();
        this.add(borderLayoutPanel, BorderLayout.CENTER);
        this.setVisible(true);
    }

    private void Avvio() {
        JPanel pane = new JPanel(new GridBagLayout());
        pane.setBorder(BorderFactory.createLineBorder(Color.BLUE));
        pane.setLayout(new GridBagLayout());

           for (int i = 0; i < 10; i++) {
               JButton button;
               GridBagConstraints c = new GridBagConstraints();
               c.fill = GridBagConstraints.HORIZONTAL;
               c.anchor = GridBagConstraints.PAGE_START;

               button = new JButton("Button 1");
               c.weightx = 0.5;
               c.gridx = 0;
               c.gridy = i;
               pane.add(button, c);

               button = new JButton("Button 2");
               c.gridx = 1;
               c.gridy = i;
               pane.add(button, c);

               button = new JButton("Button 3");
               c.gridx = 2;
               c.gridy = i;
               pane.add(button, c);

           }
           gridPanel.add(pane);
           gridPanel.revalidate();
           gridPanel.repaint();

    }

    public static void main(String args[]) {
       new Main();
    }      
}
like image 2
Michael McKay Avatar answered Oct 19 '22 15:10

Michael McKay