JScrollPane setHorizontalScrollBarPolicy as_needed without resizing content

白昼怎懂夜的黑 提交于 2019-12-24 06:24:09

问题


I noticed an issue with the setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED) resizes the height content when the scrollbar gets added (due to the content going over the width).

The Code...

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;

public class TestGui extends JFrame {
    //**************************************************************************************
    //************************************* Constructor ************************************
    //**************************************************************************************
    private TestGui() {
        add(createTopScrollPane(), BorderLayout.NORTH);
        add(createCenterScrollPane(), BorderLayout.CENTER);

        setSize(800,600);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    //**************************************************************************************
    //*********************************** Support Method ***********************************
    //**************************************************************************************
    private static GridBagConstraints setGbc(int gridx, int gridy, int gridWidth, int gridHeight, int ipadx, int ipady, String anchorLocation, double weightx, double weighty, Insets insets, boolean fillCell){
        GridBagConstraints gbc = new GridBagConstraints();

        if (anchorLocation.toUpperCase().equals("NORTHWEST")){
            gbc.anchor = GridBagConstraints.NORTHWEST;
        } else if (anchorLocation.toUpperCase().equals("NORTH")){
            gbc.anchor = GridBagConstraints.NORTH;
        } else if (anchorLocation.toUpperCase().equals("NORTHEAST")){
            gbc.anchor = GridBagConstraints.NORTHEAST;
        } else if (anchorLocation.toUpperCase().equals("WEST")){
            gbc.anchor = GridBagConstraints.WEST;
        } else if (anchorLocation.toUpperCase().equals("EAST")){
            gbc.anchor = GridBagConstraints.EAST;
        } else if (anchorLocation.toUpperCase().equals("SOUTHWEST")){
            gbc.anchor = GridBagConstraints.SOUTHWEST;
        } else if (anchorLocation.toUpperCase().equals("SOUTH")){
            gbc.anchor = GridBagConstraints.SOUTH;
        } else if (anchorLocation.toUpperCase().equals("SOUTHEAST")){
            gbc.anchor = GridBagConstraints.SOUTHEAST;
        } else {
            gbc.anchor = GridBagConstraints.CENTER;
        }

        gbc.gridx = gridx; // column
        gbc.gridy = gridy; // row
        gbc.gridwidth = gridWidth; // number of columns
        gbc.gridheight = gridHeight; // number of rows
        gbc.ipadx = ipadx; // width of object
        gbc.ipady = ipady; // height of object
        gbc.weightx = weightx; // shifts columns to side of set anchor
        gbc.weighty = weighty; // shifts rows to side of set anchor
        gbc.insets = insets; // placement inside cell
        if (fillCell){
            gbc.fill = GridBagConstraints.BOTH;
        }

        return gbc;
    }

    //**************************************************************************************
    //************************************ Panel Methods ***********************************
    //**************************************************************************************
    private JPanel createTopFrame() {
        JPanel pnl = new JPanel();

        Border lineBorder = BorderFactory.createMatteBorder(0, 0, 0, 5, Color.BLUE);
        JLabel lineSplitter = new JLabel();
        lineSplitter.setBorder(lineBorder);

        pnl.setLayout(new GridBagLayout());
        pnl.add(new JLabel("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),setGbc(0,0, 1,1, 0,0,"CENTER", 0, 0, new Insets(10, 10, 10, 10), false));
        pnl.add(new JLabel("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),setGbc(0,1, 1,1, 0,0,"CENTER", 0, 0, new Insets(10, 10, 10, 10), false));
        pnl.add(lineSplitter, setGbc(1,0,1,2,0,0,"CENTER",0,0,new Insets(0,0,0,0),true));
        pnl.add(new JLabel("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),setGbc(2,0, 1,1, 0,0,"CENTER", 0, 0, new Insets(10, 10, 10, 10), false));
        pnl.add(new JLabel("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"),setGbc(2,1, 1,1, 0,0,"CENTER", 0, 0, new Insets(10, 10, 10, 10), false));

        return pnl;
    }

    private JScrollPane createTopScrollPane(){
        JScrollPane scrollPane = new JScrollPane();
        Border raisedBevel = BorderFactory.createRaisedBevelBorder();
        Border lineBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, new Color(224,224,224));
        Border loweredBevel = BorderFactory.createLoweredBevelBorder();
        Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder);
        Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel);

        //scrollPane.setPreferredSize(new Dimension(0, 160));
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
        scrollPane.setBorder(compoundFinal);
        scrollPane.getViewport().setView(createTopFrame());
        return scrollPane;
    }

    private JScrollPane createCenterScrollPane(){
        JScrollPane scrollPane = new JScrollPane();
        Border raisedBevel = BorderFactory.createRaisedBevelBorder();
        Border lineBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, new Color(224,224,224));
        Border loweredBevel = BorderFactory.createLoweredBevelBorder();
        Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder);
        Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel);

        scrollPane.setBorder(compoundFinal);
        return scrollPane;
    }

    //**************************************************************************************
    //************************************ Start Program ***********************************
    //**************************************************************************************
    public static void main(String[] args) {
        new TestGui();
    }
}

Note: If I use setPreferredSize, it adds spacing between borders when maximizing the window, and I don't want that.

As you can see, the 2nd row gets cut off, is there anyway to have it not resize (other than setting it to HORIZONTAL_SCROLLBAR_ALWAYS, which still shows the bar if you maximize the window)?


回答1:


You need to override the methothd getPreferredSize() of your scroll pane. Also you need provide revalidation when component changed.

private TestGui() {
    add(createTopScrollPane(), BorderLayout.NORTH);
    add(createCenterScrollPane(), BorderLayout.CENTER);
    addComponentListener(new ComponentAdapter() {
        @Override
        public void componentResized(ComponentEvent e) {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    revalidate();
                    repaint();
                }
            });
        }
    });

    setSize(800,600);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

// another stuff

private JScrollPane createTopScrollPane(){
    JScrollPane scrollPane = new JScrollPane() {
        @Override
        public Dimension getPreferredSize() {
            Dimension size = super.getPreferredSize();
            if (getHorizontalScrollBar() != null && getHorizontalScrollBar().isVisible()) {
                size.height += getHorizontalScrollBar().getHeight();
            }
            return size;
        }
    };
    Border raisedBevel = BorderFactory.createRaisedBevelBorder();
    Border lineBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, new Color(224,224,224));
    Border loweredBevel = BorderFactory.createLoweredBevelBorder();
    Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder);
    Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel);

    //scrollPane.setPreferredSize(new Dimension(0, 160));
    scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
    scrollPane.setBorder(compoundFinal);
    scrollPane.getViewport().setView(createTopFrame());
    return scrollPane;
}


来源:https://stackoverflow.com/questions/43915822/jscrollpane-sethorizontalscrollbarpolicy-as-needed-without-resizing-content

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!