0

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

我已经建立了基本结构:“椭圆”是一个自包含的组件,其中包含从包含 JFrame 及其侦听器调用的方法。我尝试了两种方法:

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

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

我很可能认为这一切都是错误的。任何人都可以提出一个我还没有偶然发现的简单方法吗?

4

1 回答 1

0

Why don't you combine both your approaches. As long as you are editing, display the text component, otherwise paint all text using a TextLayout. The following example code shows such an approach extending a simple JComponent. It draws a rectangular shape with some text in it and if you click inside it shows an editing possibility. As soon as you click outside again, the component vanished. Note that all the edit-handling functionality is missing in this basic example.

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());
    }
}
于 2011-06-16T17:23:53.893 回答