Swing 更好的选择:TextLayout还是JTextComponent用于“带可编辑文本的椭圆”组件?

Swing 更好的选择:TextLayout还是JTextComponent用于“带可编辑文本的椭圆”组件?,swing,jtextcomponent,Swing,Jtextcomponent,如果您曾经使用过Visio或UML类图编辑器,您就会知道我正在尝试实现的目标:在JFrame中,用户可以添加包含一个小的可编辑文本字段的省略号。当用户拖动椭圆时,可以在帧内重新定位这些椭圆。单击椭圆会使文本变得可编辑:出现克拉,可以突出显示子字符串,等等 我已经建立了基本结构:“ellipse”是一个自包含的组件,包含从包含JFrame及其侦听器调用的方法。我尝试了两种方法: 在组件的绘制方法中,使用TextLayout查找边界,将包含的文本定位在椭圆内,然后使用TextLayout的draw将

如果您曾经使用过Visio或UML类图编辑器,您就会知道我正在尝试实现的目标:在JFrame中,用户可以添加包含一个小的可编辑文本字段的省略号。当用户拖动椭圆时,可以在帧内重新定位这些椭圆。单击椭圆会使文本变得可编辑:出现克拉,可以突出显示子字符串,等等

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

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

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


我很可能把这件事想错了。有谁能提出一个我还没有想到的简单方法吗?

为什么不将这两种方法结合起来呢。在编辑时,显示文本组件,否则使用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());
    }
}

Thx Howard,我试试这个方法!