tags:

views:

534

answers:

3

Hi all, I have a complex question I cant find an answer anywhere.

here is a example :

public static void main(final String[] args) {
    final JFrame frame = new JFrame("test");
    final JPanel bigPane = new JPanel(new GridLayout(0, 1));
    frame.setContentPane(new JScrollPane(bigPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
            ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER));
    bigPane.add(new JTextField("reterterter ertertrert erterter ert"));
    bigPane.add(new JTextField(" ertertrert erterter ert"));
    bigPane.add(new JTextField("reterterter ertertrert  ert"));
    bigPane.add(new JTextField("reterterter ertertrert erterter "));
    frame.pack();
    frame.setSize(frame.getSize().width/2, frame.getSize().height);
    frame.setVisible(true);
}

Here, clearly the textfields are cut. More precisely, bigPane is cut. But I would like the textfields to be resized instead of cut, so we can still use them.

Since the horizontal scrollbar is forbidden to appear, I would like the layout to forget the view's (bigPane) preferred width and always force the view's width to match the viewport's width. Like there would be no virtual viewport for the horizontal direction, only in the vertical.

I can't find a solution to that, and not even a hack, thaks if you can help.

Nico.

PS: looks like the code for ViewportLayout doesn't contain any code for that

PS2 : here is a cap of the result of the above code http://www.nraynaud.com/kilombo/testLayout.png see the right side.

+1  A: 

Use the JTextField constructor which takes an int as a parameter. This is the number of visible characters in the text field. You can then use setText to initialize the contents of the field (if required).

Alternatively, set the maximum and preferred sizes (setMaximumSize, setMinimumSize) of the text fields appropriately.

oxbow_lakes
none of those solutions address my problem I think. I want the current behaviour unaltered for the vertical part, so this rules out touching any size by hand. Setting the column number doesn't at all change the layout behaviour, it just indirectly changes the preferredSize.
nraynaud
I can't say that I understand what you want then. What exactly is the problem and what do you mean by "cut"? Is the frame appearing too wide? Not wide enough? What is the issue?
oxbow_lakes
when resizing down the frame, the fields are cut instead of resized.here is what I get : http://www.nraynaud.com/kilombo/textfieldcut.pnghere is what I want : http://www.nraynaud.com/kilombo/textcut.png
nraynaud
I'm sorry to say I'm still not sure what you mean! What is the difference between a "cut" field and a resized one? The only difference I can see between your 2 pictures is the vertical size of your text fields... Perhaps you are saying you want the whole fields to be smaller (including font-size etc)? If that's the case, you'll need to, um, change the font-size. This is not typical behaviour - if I make my browser smaller I don't end up with a miniature thumbnail of the web page!
oxbow_lakes
look at the right side of the pictures. Maybe you'll see the difference. It's complicated to show you the behaviour with a picture.
nraynaud
Ah yes, now I see it. What you mean is that you cannot see the full extent of the fields. I must say, I wouldn't normally use a scroll pane for anything other than displaying tables/lists. Do you *have* to use a scroll pane in this case?
oxbow_lakes
+1  A: 
banjollity
I think I already answered that. This will destroy the preferred size purpose, and as an example destroy the JFrame.pack() intent.I don't want to change the preferred size (by hand), I would like the preferred width to be ignored in the computation of the view width in this particular case.
nraynaud
+2  A: 

I think the "correct" way to do this is to use the Scrollable interface:

public class ScrollPaneWidthTrackingPanel extends JPanel implements Scrollable {
    private static final long serialVersionUID = 1L;

    public ScrollPaneWidthTrackingPanel(LayoutManager layoutManager) {
        super(layoutManager);
    }

    public Dimension getPreferredScrollableViewportSize() {
        return getPreferredSize();
    }

    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
        return Math.max(visibleRect.height * 9 / 10, 1);
    }

    public boolean getScrollableTracksViewportHeight() {
        return false;
    }

    public boolean getScrollableTracksViewportWidth() {
        return true;
    }

    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
        return Math.max(visibleRect.height / 10, 1);
    }
}

Two lines of your code then have to change to:

final ScrollPaneWidthTrackingPanel bigPane = new ScrollPaneWidthTrackingPanel(new GridLayout(0, 1));
frame.setContentPane(new JScrollPane(bigPane));

And the components should always fill the entire width of the JScrollPane, whatever the size of the frame. This change has a side effect that the components will now not fill the height of the JScrollPane. To solve that add the following code to the top of the getScrollableTracksViewportHeight method:

if (getParent() instanceof JViewport) {
    JViewport viewport = (JViewport) getParent();
    return component.getPreferredSize().height < viewport.getHeight();
}
Russ Hayward
I really read the Scrollable javadoc too fast. Clearly, what I want is in public boolean getScrollableTracksViewportWidth() { return true; }Thank you, very much.
nraynaud
Technically I have swingx already used in my project, I will use a JXPanel and call panel.setScrollableTracksViewportHeight(false); on it. That will avoid the rest of the custom code.
nraynaud