如果我想将文本翻转到适合默认语言环境的方向,我可以调用applyComponentOrientation函数,它将遍历组件树一次,正确设置方向。
问题是,它只会执行一次。因此,如果您的GUI中动态添加了组件,则这些动态添加的组件将带有错误的方向。
以下是一个快速的、人为的演示程序:
即使没有上述问题,我仍然需要手动将其添加到应用程序中的每个帧和对话框中。这不仅因为有很多对话框,而且因为不是团队中的每个开发人员在创建新的对话框时都会考虑这种事情。即使我以某种方式引入了一个正确执行此操作的
这也有点愚蠢,因为每个组件的
这让我思考了一种可能自动实现此操作的方法——编写多个自定义 LAF,每个都是其他实际外观的子类。在 installDefaults() 中,设置组件方向,然后委托给真正的UI。
不幸的是,每个LAF都有很多UI类,并且并非所有UI类都适合于允许委派的整洁系统中。此外,在某些情况下,使用非标准LAF会触发库中微妙的错误,这些库使用UI类名称检查来确定要绘制其自己的东西的样式。因此,这种方法并不是很吸引人。
还有更好的方法吗?
编辑:
我现在有一个解决方案,可用于单个对话框内的内容。
问题是,它只会执行一次。因此,如果您的GUI中动态添加了组件,则这些动态添加的组件将带有错误的方向。
以下是一个快速的、人为的演示程序:
import java.awt.ComponentOrientation;
import java.awt.FlowLayout;
import java.util.Locale;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class OrientationTest implements Runnable {
public static void main(String[] args) {
// Deliberately set locale to one with RTL orientation.
Locale.setDefault(new Locale("ar", "SA"));
SwingUtilities.invokeLater(new OrientationTest());
}
@Override
public void run() {
JFrame frame = new JFrame("Test program");
JPanel contentPane = new JPanel();
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.PAGE_AXIS));
frame.setContentPane(contentPane);
contentPane.add(makePanel());
frame.applyComponentOrientation(
ComponentOrientation.getOrientation(Locale.getDefault()));
// usually dynamically added later:
contentPane.add(makePanel());
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
private JPanel makePanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEADING));
panel.add(new JLabel("First"));
panel.add(new JLabel("Second"));
return panel;
}
}
即使没有上述问题,我仍然需要手动将其添加到应用程序中的每个帧和对话框中。这不仅因为有很多对话框,而且因为不是团队中的每个开发人员在创建新的对话框时都会考虑这种事情。即使我以某种方式引入了一个正确执行此操作的
FixedJDialog
类,也无法保证每个人都会使用它。这也有点愚蠢,因为每个组件的
ComponentUI
在构造每个组件时都会自动设置,而无需我做任何事情,因此您可能认为方向可以使用相同的机制。这让我思考了一种可能自动实现此操作的方法——编写多个自定义 LAF,每个都是其他实际外观的子类。在 installDefaults() 中,设置组件方向,然后委托给真正的UI。
不幸的是,每个LAF都有很多UI类,并且并非所有UI类都适合于允许委派的整洁系统中。此外,在某些情况下,使用非标准LAF会触发库中微妙的错误,这些库使用UI类名称检查来确定要绘制其自己的东西的样式。因此,这种方法并不是很吸引人。
还有更好的方法吗?
编辑:
我现在有一个解决方案,可用于单个对话框内的内容。
ContainerListener listener = new ContainerAdapter() {
@Override
public void componentAdded(ContainerEvent e) {
e.getChild().applyComponentOrientation(
e.getContainer().getComponentOrientation());
addListenersToTree(e.getChild());
}
};
addListenersToTree(frame);
addListenersToTree
就是递归遍历整个层次结构,在任何地方添加监听器。这是一个不太优雅的解决方案,我不知道拥有所有这些额外监听器的内存成本是多少,但它至少可以解决一部分问题,对于一个对话框而言是有效的。
SwingConstants.LEADING
,你会发现即使 Second 在 First 的左侧,它的图标也在文本的左侧,这与指定的方向不匹配。 - Hakanainew FlowLayout()
替换为new MyFlowLayout()
,例如class MyFlowLayout extends FlowLayout{public MyFlowLayout(){//orientation based code goes here}}
。 - Braj