Home > Back-end >  Horizontal JScrollPane inside vertical JScrollPane
Horizontal JScrollPane inside vertical JScrollPane

Time:09-12

Good afternoon! It is necessary to make a list (vertical) from lists of events (horizontal). There are at least 2 problems:

  1. the area of the list of events (horizontal scrolling) expands beyond the borders of the panel. Apparently, the problem is with Layout, but I can not find the right combination;
  2. horizontal scrolling does not work (probably due to the problem described above) and the scrollbar must be different for each group of events.
import ivank.components.EventAdd;
 
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
 
public class WindowAddCameras extends JFrame {
    public static final List<JPanel> labels = new ArrayList<JPanel>();
 
    public WindowAddCameras() {
        super("Добавить камеру");
 
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        JPanel panelButton = new JPanel();
 
        JButton addButton = new JButton(" ");
        addButton.setFocusable(false);
        panelButton.add(addButton);
 
        JButton remButton = new JButton("-");
        remButton.setFocusable(false);
        panelButton.add(remButton);
 
        JPanel externalPanel = new JPanel();
        externalPanel.setLayout(new BorderLayout(0, 0));
        JScrollPane scrollPaneGroupEvent = new JScrollPane(
                externalPanel,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
        );
 
        JPanel internalPanel = new JPanel();
        internalPanel.setLayout(new GridLayout(0, 1, 0, 0));
 
        JScrollPane scrollPaneEvent = new JScrollPane(internalPanel);
        scrollPaneEvent.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
        scrollPaneEvent.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
 
        externalPanel.add(scrollPaneEvent, BorderLayout.NORTH);
        addButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int number = labels.size()   1;
                EventAdd eventAdd = new EventAdd();
                Dimension labelSize = new Dimension(80, 80);
 
                //add event to group event
                Random rand = new Random();
                for(int a = 0; a < 20; a  ) {
                    //random color border event for TEST
                    Color randomColor = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat());
                    eventAdd.createEventLabel("Камера "   number, labelSize, randomColor);
                }
 
                labels.add(eventAdd);
                internalPanel.add(eventAdd, BorderLayout.NORTH);
                scrollPaneGroupEvent.revalidate();
            }
        });
 
        remButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(labels.size() > 0) {
                    int index = labels.size() - 1;
                    JPanel panel = labels.remove(index);
                    internalPanel.remove(panel);
                    internalPanel.repaint();
                    scrollPaneGroupEvent.revalidate();
                }
            }
        });
 
        this.getContentPane().setLayout(new BorderLayout());
        this.getContentPane().add(panelButton, BorderLayout.NORTH);
        this.getContentPane().add(scrollPaneGroupEvent, BorderLayout.CENTER);
 
        this.setPreferredSize(new Dimension(600, 400));
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }
}
package ivank.components;
 
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
 
public class EventAdd extends JPanel {
    public EventAdd() {
        super(new FlowLayout(FlowLayout.LEFT));
    }
 
    public JComponent createEventLabel(String name, Dimension labelSize, Color randomColor) {
        this.setBorder(BorderFactory.createTitledBorder(name));
        JLabel label = new JLabel();
        label.setPreferredSize(labelSize);
        label.setHorizontalAlignment(JLabel.CENTER);
 
        label.setBorder(BorderFactory.createLineBorder(randomColor, 5));
        this.add(label);
 
        return label;
    }
}

What I have: enter image description here What I want to get: enter image description here

CodePudding user response:

You can do the horizontal and vertical scrolling with only one JScrollPane. But what you need is an underlying JComponent that renders your content. This however can be a JPanel that stretches as far as you need.

Have a look at How to use ScrollPanes.

CodePudding user response:

A JScrollPane must have a JViewport assigned using the jscrollpane method setViewportView. You should also give it a scrollbar policy setVerticalScrollBarPolicy setHorizontalScrollBarPolicy The policy int is part of the class for the two previous methods and are called "constant field values" , see the API doc for JScrollPane. To expand the JScrollPane out, put it in a JPanel with a BorderLayout and NO OTHER elements in that particular panel with the JScrollPane. Use on the JPanel, the methods setMinimumSize and setPreferredSize and setSize or a BoxLayout in the main window(although i think main windows have a special layout so a boxlayout would not be required if so) or higher level panel in the stack, or just setPreferredSize for the JScrollPane. A jscrollpane has a view set by its "setView" method , its view is a java.awt.Component note: a JComponent is a java.awt.Component, any javax swing J panel or J viewport is a java.awt.Component by hierarchy. NOTE a jviewport is a java.awt.Component so get a jscrollpane.setViewportView add the jviewport reference jviewport.setView as the JPanel with the BorderLayout , add another panel to start adding other components, but remember to give all Jcomponents a .preferredSize method use. If you are after javax.swing.JList<E> and javax.swing.DefaultListModel<E> The JList must be placed in a JPanel with a BorderLayout , or much more difficult system a java.awt.GridBagLayout then in a jscrollpane.

  • Related