0

I encountered an issue when using a JTextField within a BoxLayout within a JScrollPane.

The desired result is a JTextField that scrolls within itself, as you see when you paste a URL that is longer than the width of your screen into the address bar on your web browser. The entire string shifts left or right when you try to move the caret past the boundaries of the text field.

However, when put in a JScrollPane, the text field fails to do this, instead expanding to fit the entire string.

Before the text:

Before entering text

After the text:

After entering text

The text box increases its width, causing a scroll bar to appear, rather than "internal scrolling" behavior I described before (where the text box remains the same size, but only shows part of the text).

This behavior even occurs when setting the scroll bar policy to JScrollPane.HORIZONTAL_SCROLLBAR_NEVER:

After entering text, without a scrollbar

I noticed that the text box performs the "internal scrolling" correctly until the window is resized, at which time the text field resizes itself off the screen.

I require a scroll pane because I need the vertical scroll bar in my application, but I would like the horizontal axis to be restricted to whatever size the window allows to the panel. How can I achieve this?

Code segment for the above examples:

import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

public class GUI {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JScrollPane scrollPane = new JScrollPane(panel);
        frame.add(scrollPane);
        JTextField textField = new JTextField();
        panel.add(textField);

        frame.setSize(500, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        // max width = Short.MAX_VALUE so it expands to fill the frame width
        // max height = preferred height so the text area height does not expand
        textField.setMaximumSize(new Dimension(Short.MAX_VALUE, textField.getPreferredSize().height));

        frame.setVisible(true);
    }
}

The best solution would still implement a horizontal scroll bar if the combined minimum size of the components in the panel (on the horizontal axis) was greater than the width of the window (say, if I added a button in there to the left of the text field).

snickers10m
  • 1,709
  • 12
  • 28
  • `JTextField` won't wrap. In this case, don't use a layout manager which allows the text field to grow, maybe something like `GridBagLayout`. You might also like to have a look at [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi) – MadProgrammer Dec 08 '15 at 03:22
  • @MadProgrammer I'm not talking about wrapping. I'm talking about when you type past the limit of a text field with a set size. As you type more, the text in front of the caret appears to move to the left within the field. – snickers10m Dec 08 '15 at 03:24

2 Answers2

2

Use a different layout manager, something like GridBagLayout, which will generally honor the preferred size of the component, for example

JFrame frame = new JFrame();
JPanel panel = new JPanel(new GridBagLayout());
JScrollPane scrollPane = new JScrollPane(panel);
frame.add(scrollPane);

GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.fill = gbc.HORIZONTAL;
JTextField textField = new JTextField(10);
panel.add(textField, gbc);

frame.setSize(500, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setVisible(true);
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

A simple solution is to set the preferred width of the text field to its minimum width.

textField.setPreferredSize(new Dimension(textField.getMinimumSize().width, textField.getPreferredSize().height));

The text field will perform the "internal scrolling" behavior, as well as cause a scroll bar to appear if the window shrinks below its minimum size (as described in the original question's final statement, below)

The best solution would still implement a horizontal scroll bar if the combined minimum size of the components in the panel (on the horizontal axis) was greater than the width of the window (say, if I added a button in there to the left of the text field).

snickers10m
  • 1,709
  • 12
  • 28
  • 1
    [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi) – MadProgrammer Dec 09 '15 at 05:02