gpt4 book ai didi

java - 当 ComponentOrientation 设置为 RTL 时 JLabel 和 JTextField 之间的不一致

转载 作者:行者123 更新时间:2023-11-30 11:11:05 27 4
gpt4 key购买 nike


关于 swing 中从右到左的组件方向,我有一个奇怪的问题 - JLabel 和 JTextField 之间关于相同值的显示不一致。附件是演示该问题的 SSCCE。

我做错了什么吗?

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class GuiTest2 extends JFrame
{
public GuiTest2()
{
super( "Test" );

JLabel testLabel = new JLabel();
testLabel.setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT );
testLabel.setText( "ca 12 בדיקה" );
testLabel.setBorder( new LineBorder( Color.BLACK ) );

JTextField testTextField = new JTextField();
testTextField.setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT );
testTextField.setText( "ca 12 בדיקה" );
testTextField.setBorder( new LineBorder( Color.BLACK ) );

JPanel panel = new JPanel( new BorderLayout( 5, 5) );
panel.setBorder( new EmptyBorder( 10, 10, 10, 10 ) );
panel.add( testLabel, BorderLayout.NORTH );
panel.add( testTextField, BorderLayout.SOUTH );

setContentPane( panel );
pack();
setLocationRelativeTo( null );
setVisible( true );
}

public static void main( String[] args )
{
SwingUtilities.invokeLater( new Runnable()
{
@Override
public void run()
{
new GuiTest2();
}
} );
}
}


这是上面代码的截图:
1
结果字符串不应该相同吗?

没有 setComponentOrientation 我有以下内容( 相同):
2

最佳答案

简短的回答是 JLabel 忽略 componentOrientation

稍长的答案...

文本最终是呈现为基本 LTR 还是基本 RTL 取决于 TextLine 中的逻辑。在文本上有属性的情况下,属性中包含双向嵌入的信息,该信息用于设置默认的文本方向。这通常出现在 JTextPaneJTextField 等组件中,它们也基于 Document,可能具有相同的行为(尽管在今天之前,我根本不知道 JTextField 和 JTextArea 有任何属性,这个会有点意义。)

在信息不存在的情况下,从 Unicode 双向算法 (UAX #9) 计算出来的逻辑在 java.text.Bidi 中。该算法非常复杂,但本质上,如果您的行不是以强 RTL 字符开头,则默认情况下该行将被假定为 LTR。

可以说,setComponentOrientation() 应该告诉渲染器更改默认设置,所以我将其视为 Java 错误。

一种解决方法(假设您控制应用程序中所有标签的构造!)是在文本开头插入\u202E:

    String text = "\u202Eca 12 \u05D1\u05D3\u05D9\u05E7\u05D4";

JLabel testLabel = new JLabel();
testLabel.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT );
testLabel.setText(text);
testLabel.setBorder( new LineBorder( Color.BLACK ) );

screenshot of new behaviour

插入字符串的方式取决于方便的方式:

  1. 检查 setText 的所有用法,如果其中任何一个可能以非 RTL 字符开头,则插入该字符。
  2. 查看资源包中的所有字符串格式,如果其中任何一个可能以非 RTL 字符开头,请将该字符插入到消息格式中。 (当您控制字符串时,这听起来是个不错的解决方案,但当您在第三方库中遇到此问题时,效果就不是很好了。)
  3. JLabel 替换为可解决此问题的子类。这适用于所有 LAF,但同样,如果您在第三方库中遇到问题,则必须说服他们应用类似的修复程序。
  4. BasicLabelUI 替换为固定的子类,以此类推您打算支持的所有其他 LAF。这在重复方面很痛苦,但该修复程序将自动适用于标签的任何第三方使用。

当然,当您发现问题时,可以根据具体情况应用上述任何方法。

关于java - 当 ComponentOrientation 设置为 RTL 时 JLabel 和 JTextField 之间的不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27542648/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com