更好的选择:TextLayout或JTextComponent是否为“带有可编辑文本的椭圆”组件?

时间:2011-06-16 16:33:32

标签: swing jtextcomponent

如果您曾经使用过Visio或UML类图编辑器,那么您就知道我要完成的任务:在JFrame中,用户可以添加包含一个小的可编辑文本字段的省略号。当用户拖动它们时,可以在框架内重新定位这些椭圆。单击椭圆会使文本变得可编辑:出现一个克拉,突出显示一个子串,等等。

我已经设置了基本结构:'ellipse'是一个自包含的组件,其中包含从包含JFrame及其侦听器的方法调用它。我尝试了两种方法:

  1. 在组件的draw()方法中,使用TextLayout查找边界,将包含的文本放在椭圆内,然后使用TextLayout的draw()将其绘制到框架中。这很快。在JFrame中拖动组件,鼠标悬停和鼠标单击行为都很简单。但是对于编辑功能,我看起来需要编写大量自定义代码来处理命中测试,克拉定位,文本突出显示,换行等。

  2. 让组件包含对包含JFrame的引用,并在绘制椭圆后在该JFrame中添加或重新定位TextComponent。这具有用于编辑和换行的所有内置TextComponent行为的优点。但物流真的很草率,TextComponent的定位也变得混乱 - 特别是当用户拖动组件时。

  3. 我很可能会想到这一切都错了。任何人都可以提出一个简单的方法来做到这一点,我还没有偶然发现?

1 个答案:

答案 0 :(得分:0)

为什么不将两种方法结合起来。只要您正在编辑,就会显示文本组件,否则使用TextLayout绘制所有文本。以下示例代码显示了这种扩展简单JComponent的方法。它绘制一个矩形的形状,里面有一些文字,如果你点击它里面就显示了编辑的可能性。只要再次单击外部,组件就会消失。请注意,此基本示例中缺少所有编辑处理功能。

class TestComponent extends JComponent {
    JTextArea jta = new JTextArea("12345");

    public TestComponent() {
        setPreferredSize(new Dimension(400, 400));
        setLayout(null);
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(final MouseEvent e) {
                SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        if (e.getX() >= 40 && e.getX() <= 200 && e.getY() >= 40 && e.getY() <= 80) {
                            TestComponent.this.add(jta);
                            jta.setBounds(42, 42, 156, 36);
                        } else {
                            TestComponent.this.remove(jta);
                        }
                        repaint();
                    }
                });
            }
        });
    }

    @Override
    public void paintComponent(Graphics _g) {
        Graphics2D g = (Graphics2D) _g;
        g.drawRect(40, 40, 160, 40);
        TextLayout layout = new TextLayout("12345", g.getFont(), g.getFontRenderContext());
        layout.draw(g, 42, 42 + layout.getAscent());
    }
}