JScrollPanes in JInternalFrames for right to left

2019-08-25 06:00发布

问题:

So I have created some demo code, see below.

What I am seeing is that if a JScrollPane is within a JInternalFrame and component orientation is set to right-to-left, when minmising the frame, the scroll bar stays to the left of the content. I would expect, seeing as RtL, that it would stay to the right of the content, which is true if the scroll pane is not added to an internal frame (see both frames - one appears behind the other in the demo).

So is this a Java bug or have I forgotten to do something?

Here's the demo code:

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import java.awt.ComponentOrientation;
import java.awt.Dimension;


public class JScrollBarTest
{
    public static void main(String[] a)
    {
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) { }

        runInternalFrameDemo();
        runNormalDemo();
    }

    private static void runInternalFrameDemo()
    {
        // Frame...
        final JFrame frame = new JFrame("Internal Frame Demo");
        frame.setSize(new Dimension(500, 500));
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        // Desktop pane...
        JDesktopPane desktopPane = new JDesktopPane();

        // Table...
        JTable table = getTable();

        // Scroll pane...
        JScrollPane scrollPane = new JScrollPane();

        // Internal frame...
        final JInternalFrame internalFrame = new JInternalFrame("Test Internal Frame", true, true, true, true);
        internalFrame.setSize(400, 300);
        internalFrame.setLocation(50, 50);
        internalFrame.setVisible(true);

        // Add everything...
        frame.setContentPane(desktopPane);
        desktopPane.add(internalFrame);
        internalFrame.setContentPane(scrollPane);
        scrollPane.setViewportView(table);

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                internalFrame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
                frame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
                frame.setVisible(true);
            }
        });
    }

    private static void runNormalDemo()
    {
        // Frame...
        final JFrame frame = new JFrame("Normal Demo");
        frame.setSize(new Dimension(500, 500));
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        // Table...
        JTable table = getTable();

        // Scroll pane...
        JScrollPane scrollPane = new JScrollPane();

        // Add everything...
        frame.setContentPane(scrollPane);
        scrollPane.setViewportView(table);

        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                frame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
                frame.setVisible(true);
            }
        });
    }

    private static JTable getTable()
    {
        final String[] columns = { "test 1", "test 2", "test 3", "test 4" };
        final Object[][] data = { { "1", "2", "3", "4" }, { "1", "2", "3", "4" } };
        final JTable table = new JTable(data, columns);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        return table;
    }
}

Thanks in advance.

EDIT:

Apologies for the lack of clarity - written in quite a rush.

The issue is that when I reduce the width of the table, the 'Normal Demo' (not contained within a JInternalFrame) the horizontal scroll bar starts on the right, where as, doing the same for the 'Internal Frame Demo', the horizontal scroll bar starts on the left.

Any ideas?

回答1:

As discussed, with Java 1.6 there does not seem to be a difference in the behaviors of internal and standard frames.

Bug "JScrollPane ignores ComponentOrientation" describes your problem, but it has been fixed long time ago.

Bug "JScrollPane does not layout properly with RTL (RIGHT_TO_LEFT)" is still open and could cause your problem.

I found a solution in Sun Forums that made it work for me, although the problem was slightly different. Vertical scrollbar is displayed on the right side instead of the left.

scrollPane.setLayout(new ScrollPaneLayout() {

    @Override
    public void layoutContainer(Container parent) {
        JScrollPane scrollPane = (JScrollPane) parent;
        scrollPane.setComponentOrientation(
          ComponentOrientation.LEFT_TO_RIGHT);
        super.layoutContainer(parent);
        scrollPane.setComponentOrientation(
          ComponentOrientation.RIGHT_TO_LEFT);
    }
});

The current behavior sounds like a bug to me, since the bug (see above) has been fixed.



回答2:

I'm not sure what you see, but here is what i see.

alt text http://dl.dropbox.com/u/3608004/jframe.png

In both cases the scrollbar is on the left (before and after minimize), and this is the right thing. In Arabic (right-to-left langauge) the default position for scrollbars is on the left