Take the 2-minute tour ×

See the title. I've tried to change component orientation to RIGHT_TO_LEFT, but that had a unexpected side effect - it behaves strangely with components with specified preferred size.

(JDK 1.6.0_23, Eclipse VE)


Here is the example of this:

We have JFrame with jMainScrollPane on it. Inside jMainScrollPane we place a jMainPanel. Now set jMainPanel's preferred size to be narrower than jMainScrollPane's. jMainPanel will still take all the space on jMainScrollPane. Now changejMainScrollPane's orientation to RIGHT_TO_LEFT and see what happen.

Sample code (change jMainScrollPane's orientation to see the difference):

import java.awt.BorderLayout;
import java.awt.ComponentOrientation;
import java.awt.Dimension;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class TestFrame extends JFrame {
    private JPanel      jContentPane    = null;
    private JScrollPane jMainScrollPane = null;
    private JPanel      jMainPanel      = null;

    public TestFrame(){

    private void initialize(){
        this.setSize(480, 339);

    private JPanel getJContentPane(){
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(new BorderLayout());
            jContentPane.add(getJMainScrollPane(), BorderLayout.CENTER);
        return jContentPane;

    private JScrollPane getJMainScrollPane(){
        if (jMainScrollPane == null) {
            jMainScrollPane = new JScrollPane();
        return jMainScrollPane;

    private JPanel getJMainPanel(){
        if (jMainPanel == null) {
            jMainPanel = new JPanel();
            jMainPanel.setLayout(new BorderLayout());
            jMainPanel.setPreferredSize(new Dimension(30, 30));
        return jMainPanel;


Due to the strange nature of this, I've submitted a bug to Oracle. They mailed me a bug link


At the moment there is no such bug yet - I suppose, it's being checked.

But still, question is open - is there a workaround or another way?

share|improve this question
Duplicate of JScrollPane with scroll bar to left –  Manoj Apr 20 '11 at 8:06
@Manoj seems like @Frozen_Spider already tried the answer of mentionned question, but was not satisfied with result. –  Riduidel Apr 20 '11 at 8:10
@Frozen_Spider when you write "ruined layout inside of it.", can you tell us what you mean ? Or send a screenshot ? –  Riduidel Apr 20 '11 at 8:10
I agree. The given solution should work. I've tested it on a JTable with a JScrollpane. the JScrollpane doesn't have any preferred size set. –  eee Apr 20 '11 at 9:25
I notice that you have two JScrollPanes...the main one views the jMainPanel and the second one views nothing. Why are you designing like that? If your intention is to trigger vertical scroll bar for the jMainPanel, you just need JMainPanel.setPreferredSize(new Dimension(500, 400)); and remove the need for the second JScrollPane which I don't see a purpose. –  eee Apr 21 '11 at 6:27
show 4 more comments

1 Answer

up vote 2 down vote accepted

Agree with the OP: it's bug. The setting of RToL orientation triggers the calculation of the viewPosition. This happens before the layout is done. In that case, the JViewport returns the view's preferredSize instead of its actual size (which at that time is zero). Deep in the bowels, the BasicScrollPaneUI.Handler doesn't know about that faked size and bases its calculation on incorrect data.

Here's some code to play with (the OPs original stripped down a bit further, added colored borders to see where is what):

public class COInScrollPane extends JFrame {

    public COInScrollPane(){

    private void initialize(){
        final JScrollPane jMainScrollPane = getJMainScrollPane();
        this.setSize(480, 339);
        Action action = new AbstractAction("Toggle CO") {

            public void actionPerformed(ActionEvent e) {
                ComponentOrientation co = jMainScrollPane.getComponentOrientation().isLeftToRight() ?
                        ComponentOrientation.RIGHT_TO_LEFT : ComponentOrientation.LEFT_TO_RIGHT;
        add(new JButton(action), BorderLayout.SOUTH);

    private JScrollPane getJMainScrollPane() {
        JScrollPane jMainScrollPane = new JScrollPane(getJMainPanel());
        return jMainScrollPane;

    private JPanel getJMainPanel() {
        JPanel jMainPanel = new JPanel();
        jMainPanel.add(new JButton("just a button"));
        return jMainPanel;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new COInScrollPane().setVisible(true);


The initial layout is completely wrong (as reported by OP), toggle the CO with the button twice - the Layout looks okay.

A quick and dirty hack might be to do just that in procduction context: after initial layout, force the CO into LToR to allow for correct coordinates then back to RToL.

share|improve this answer
Thank you, dirty hack works :) I've also posted a bug link, but - shame on me - I described a bug far worst then you did. –  Frozen Spider Apr 21 '11 at 10:52
@Frozen Spider glad it works for you :-) What's the review id (the number on the automatic bug response)? –  kleopatra Apr 21 '11 at 12:50
What is so secret about this bug anyway... Some bugs are not included in the Bug Database for security reasons. –  eee Apr 21 '11 at 13:45
Anyway, it has been reported before bugs.sun.com/bugdatabase/view_bug.do?bug_id=4845945 –  eee Apr 21 '11 at 14:06
Bug ID is posted at the bottom of a question: 7038455 @eee: It seems, you right. Well, I'm just glad they know about it. –  Frozen Spider Apr 21 '11 at 15:27
add comment

Your Answer


