如果您曾经使用过Visio或UML类图编辑器,那么您就知道我要完成的任务:在JFrame中,用户可以添加包含一个小的可编辑文本字段的省略号。当用户拖动它们时,可以在框架内重新定位这些椭圆。单击椭圆会使文本变得可编辑:出现一个克拉,突出显示一个子串,等等。
我已经设置了基本结构:'ellipse'是一个自包含的组件,其中包含从包含JFrame及其侦听器的方法调用它。我尝试了两种方法:
在组件的draw()方法中,使用TextLayout查找边界,将包含的文本放在椭圆内,然后使用TextLayout的draw()将其绘制到框架中。这很快。在JFrame中拖动组件,鼠标悬停和鼠标单击行为都很简单。但是对于编辑功能,我看起来需要编写大量自定义代码来处理命中测试,克拉定位,文本突出显示,换行等。
让组件包含对包含JFrame的引用,并在绘制椭圆后在该JFrame中添加或重新定位TextComponent。这具有用于编辑和换行的所有内置TextComponent行为的优点。但物流真的很草率,TextComponent的定位也变得混乱 - 特别是当用户拖动组件时。
我很可能会想到这一切都错了。任何人都可以提出一个简单的方法来做到这一点,我还没有偶然发现?
答案 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());
}
}