How to make the horizontal scroll bar appear in a

2019-08-07 12:21发布

问题:

I can't make the horizontal scrollbar appear. I've tried using JTextPane.setSize(), JTextPane.setPreferredSize() and no size method for JTextPane. I'm also using JScrollPane.setPreferredSize().

The vertical scroll bar appears, but the horizontal one doesn't.

Here is an example:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test {

    private int         textPaneWidth    = 500;
    private int         textPaneHeigth   = 200;
    private int         scrollPaneWidth  = 100;
    private int         scrollPaneHeigth = 100;
    private JTextPane   textPane;
    private JButton     button;
    private JFrame      frame;
    private JScrollPane scrollPane;

    public static void main(String[] args) {

        Test gui = new Test();
        gui.go();

    }

    private void go() {

        frame       = new JFrame("Test");
        button      = new JButton("button");
        textPane    = new JTextPane();
        scrollPane  = new JScrollPane(textPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        button.addActionListener(new ButtonListener());
        textPane.setFont(new Font("Courier", Font.PLAIN, 12));

        // Sizes:
//        textPane.setSize(textPaneWidth, textPaneHeigth);                             // ???
//        textPane.setPreferredSize(new Dimension(textPaneWidth, textPaneHeigth));     // ???
        scrollPane.setPreferredSize(new Dimension(scrollPaneWidth, scrollPaneHeigth));

        frame.add(button);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);

    }

    private class ButtonListener implements ActionListener {

        public void actionPerformed(ActionEvent event) {
             textPane.setText("==================================================================== \n" + 
                         "==================================================================== \n" +
                         "==================================================================== \n" +
                         "==================================================================== \n" +
                         "==================================================================== \n");
        }

    }
}

When the button is pressed, the string is added to the JTextPane. There is vertical scrolling, but no horizontal scrolling.

This is what I'm seeing after pressing the button:

What am I doing wrong?

回答1:

seems like you need to extend JTextPane to avoid wrapping

https://forums.oracle.com/thread/1210688

class JTextWrapPane extends JTextPane {

    boolean wrapState = true;
    JTextArea j = new JTextArea();

    JTextWrapPane() {
        super();
    }

    public JTextWrapPane(StyledDocument p_oSdLog) {
        super(p_oSdLog);
    }


    public boolean getScrollableTracksViewportWidth() {
        return wrapState;
    }


    public void setLineWrap(boolean wrap) {
        wrapState = wrap;
    }


    public boolean getLineWrap(boolean wrap) {
        return wrapState;
    }
}  

EDIT:

//  instead of  private JTextPane jtp = new JTextPane( sdLog );
    private JTextWrapPane jtp = new JTextWrapPane( sdLog );
//and set LineWrap = (false):
        jtp.setLineWrap(false);


回答2:

After a bit of digging, I figured out the issue.

JTextPane does not just display a document, rather, it displays a styled document. To quote from the java tutorials: "One JTextComponent subclass, JTextPane, requires that its document be a StyledDocument rather than merely a Document."

When you create a JTextPane with a default constructor, as you did, you automatically create a DefaultStyledDocument. From the documentation for DefaultStyledDocument:

These style runs are mapped into a paragraph element structure (which may reside in some other structure). The style runs break at paragraph boundaries since logical styles are assigned to paragraph boundaries.

This means that the JTextPane is actually doing the word wrap for you. One solution would be to try using a JTextArea instead.

EDIT, per comments: Another solution could be to create your own StyledDocument (possibly by extending from AbstractDocument), set it up how you want, and pass this to the JTextPane constructor.



回答3:

Only vertical scrolling without scrollbars

progressTextArea = new JTextPane();

JScrollPane scroller = new JScrollPane()
{
    public Dimension getPreferredSize()
    {
        return new Dimension(300, 100);
    }

    public float getAlignmentX()
    {
        return LEFT_ALIGNMENT;
    }
};

scroller.getViewport().add(progressTextArea);