将JFrame的方向从右到左设置!

15

要将我的JFrame从右到左对齐,我使用:

setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

但是这只在我使用JFrame的以下样式(装饰)时有效:

public class RightToLeft {
  public static void main(String []args){
    javax.swing.SwingUtilities.invokeLater(new Runnable(){
      public void run() {
        try { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); }
        catch (Exception e) { e.printStackTrace(); }
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("العنوان بالعربي");
        frame.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        frame.setSize(300,300);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setVisible(true);
      }
    });
  }
}

在此输入图片描述

但我希望它能在没有这个装饰的情况下工作。如何解决这个问题?

编辑:

@mre 我想要一个像这样的JFrame:

在此输入图片描述

编辑2:

我非常需要解决这个问题,所以我愿意支付500+给那些能提供这样的JFrame(使用WindowsLookAndFeel)的人:

在此输入图片描述


1
@Eng.Fouad,为什么不加载您想要使用的特定外观,而不是加载跨平台外观呢? - mre
@mre 我的意思是它不会影响JFrame的方向(即关闭按钮仍将位于右上角) - Eng.Fouad
@Eng.Fouad,有趣……也许是个bug? - mre
1
@Eng.Fouad,你应该报告它! :) - mre
1
我认为你可能在这件事上运气不佳。发现了一个被标记为“11-关闭,非缺陷”的错误:JFrame ComponentOrientation.RIGHT_TO_LEFT 在系统外观和感觉上无法正常工作 - obscuredlogic
显示剩余6条评论
6个回答

7
以下是您通过代码片段所观察到的情况解释:
ComponentOrientation仅适用于Swing(实际上也适用于AWT)组件。
使用JFrame.setDefaultLookAndFeelDecorated(true)时,整个框架装饰由Swing(实际上是LookAndFeel本身)执行,因此这按预期工作。
如果您没有设置此选项,则意味着OS负责框架装饰,但是OS无法了解您的Swing组件使用的ComponentOrientation!
我希望OS(您确切提到了使用的OS吗?似乎是Windows 7对吗?)根据当前选择的区域设置执行正确的装饰。因此,如果您在OS上设置并选择了阿拉伯区域设置,我猜所有窗口装饰都是从右到左的。你尝试更改该语言环境(通过“区域和语言”控制面板)了吗?它起作用了吗?
注意:我认为您无法直接从Java更改这些OS设置,但是可以使用Locale.getDefault()读取它们。
总之:
首先,必须确保您的操作系统在文本方向方面已正确配置,很抱歉我无法提供太多帮助,因为我在Windows计算机上没有安装任何从右到左的语言。
然后,使用系统外观并确保JFrame.setDefaultLookAndFeelDecorated(false)。
如果这样不起作用,那么您可以考虑将代码片段和系统配置一起发布到Oracle Java错误列表中。
以下是有关如何改进代码的额外注意事项(但这不是解决问题的方法)
顺便说一下,如果您允许用户定义其操作系统语言首选项,那么您不应明确硬编码frame.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT),而应使用类似于以下内容的东西:
frame.applyComponentOrientation(
    ComponentOrientation.getOrientation(Locale.getDefault()));

Locale.getDefault()会返回操作系统当前选择的Locale,除非在应用程序中明确更改了这个值。

另外请注意,最好使用applyComponentOrientation()而不是setComponentOrientation(),因为前者会递归地将给定的方向设置到整个组件层次结构中。

最后,请确保您的窗口中使用的LayoutManager具有从右到左的支持。几乎所有标准Swing布局都支持此功能,但如果使用第三方布局管理器,则可能不支持。


首先,您能确认您的操作系统语言环境是阿拉伯语吗?您可以在代码中添加 System.out.println(Locale.getDefault()); 来确认。 - jfpoilpret
System.out.println(ComponentOrientation.getOrientation(Locale.getDefault()); 这个怎么样? - jfpoilpret
你能确认系统中所有其他框架(非Java应用程序)在标题栏中使用RTL方向吗?此外,为什么要使用跨平台的外观和感觉,而不是使用系统外观和感觉呢? - jfpoilpret
System.out.println(ComponentOrientation.getOrientation(Locale.getDefault()).isLeftToRight()); 输出 false - Eng.Fouad
你说“两者都不接受…”,是指框架组件内部没有从右到左的布局吗?还是指标题栏不是从右到左的呢?如果是后一种情况,我的回答告诉你原因:框架的装饰是由操作系统绘制的,而不是Swing自己绘制的。 - jfpoilpret
显示剩余9条评论

5

@Eng.Fouad

只是一个玩笑,还有这个???...

Substance L&F

代码:

import java.awt.ComponentOrientation;
import javax.swing.JFrame;
import javax.swing.UIManager;
import org.pushingpixels.substance.api.skin.SubstanceOfficeSilver2007LookAndFeel;

public class RightToLeft {

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    //UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                    UIManager.setLookAndFeel(new SubstanceOfficeSilver2007LookAndFeel());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                JFrame.setDefaultLookAndFeelDecorated(true);
                JFrame frame = new JFrame("العنوان بالعربي");
                frame.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
                frame.setSize(300, 300);
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }

    private RightToLeft() {
    }
}

我在哪里可以下载这个包“org.pushingpixels.substance.api.skin”? - Eng.Fouad
@Eng.Fouad,这是来自旧的原始包http://java.net/projects/substance/,但在今年期间被分叉并以名称Insubstantial继续https://github.com/Insubstantial(对于最困难的更改,您必须使用invokeAndWait而不是invokeLater http://stackoverflow.com/questions/6579087/gui-problem-with-java-substance-look-and-feel/6579925#6579925),这里是有用的L&F年鉴https://dev59.com/rm865IYBdhLWcg3wKLT6,JGoodies具有良好的CompoentOrientation实现,您必须尝试一下,因为我从未需要更改它。 - mKorbel
请简要解释一下如何使用这个包?我不熟悉使用包。因为时间快到期了,而且你的解决方案似乎满足了我的需求,所以我会给你额外的50声望值。 - Eng.Fouad
1
只需下载此软件包并将其作为JDBC驱动程序或任何驱动程序进行链接或导入,示例代码在代码源中。 - mKorbel

3
我怀疑这更多与操作系统有关。通常情况下(如果您不调用setDefaultLookAndFeelDecorated),提供框架装饰的是操作系统,而不是LAF。
您应该尝试更改操作系统中的首选项,以指定您想要从右到左的方向。
抱歉,我不知道这些设置在哪里。一旦您这样做了,那么您就可以删除对setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);的调用,因为LAF将从区域设置中获取操作系统的设置。
编辑 此链接描述了如何在Windows 7上启用从右到左的文本。然后,我认为您还需要更改语言环境。

1

看起来 Windows LookAndFeel 不支持组件方向特性(至少不支持标题栏)


2
标题栏与LAF无关 - 它由操作系统提供。事实是,WindowsLAF不支持LAFDecoration(又称:不使用默认的操作系统窗口装饰,让LAF自己滚动)。 - kleopatra

1

这里有一种可能性。这个实用程序是为那些从Mac切换到Windows并希望将窗口按钮放在左侧的用户设计的,但它应该满足您的相同需求。

这个解决方案与Java无关(所以我不知道它是否符合您的需求),听起来它可能是外部于您的应用程序。我自己没有能够尝试过它(我没有运行Windows),所以我不能保证它,但它可能值得一试。


这个很有效,但我需要它在我的程序内部工作。 - Eng.Fouad

-1

你只需要添加这一行代码,我相信它可以百分之百地工作。

frame.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接