【发布时间】:2014-06-15 05:49:02
【问题描述】:
如果我想将文本翻转到默认语言环境的适当方向,我可以调用applyComponentOrientation,它会只遍历一次组件树并正确设置方向。 p>
问题是,它真的只做一次。因此,如果您有一个 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,每个 LAF 都继承了其他一些实际的外观和感觉。在 installDefaults() 上,设置组件方向,然后委托给真实的 UI。
不幸的是,每个 LAF 都有很多 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 只是递归层次结构,到处添加监听器。这是一个肮脏的解决方案,我不知道拥有所有这些额外侦听器的内存成本是多少,但它适用于一个对话框,因此它至少解决了部分问题。
【问题讨论】:
-
有趣的问题+1
标签: java swing right-to-left