我想画一幅画布( JPanel
)可以有文本框的( JTextArea
)在上面,我还可以拖动画布或文本框。现在拖动文本框功能正常。我可以用 setBounds()
设置 JTextArea
.
然而,当涉及到拖拽画布时,问题就来了。我用 Graphics2D.transform
移动画布。画布移动后,将出现一个可视文本区域和一个隐藏的真实文本区域。我已经重新设定了 JTextArea
以适应画布的移动偏移,但它不起作用。
下面是一个例子,
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.AffineTransform;
/**
* @author Zhijie Lan<p>
* create date: 2020/11/25<p>
**/
public class TranslateJPanel extends JFrame
{
public TranslateJPanel() throws HeadlessException
{
Canvas canvas = new Canvas();
add(canvas,BorderLayout.CENTER);
this.setSize(1280, 720);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public static void main(String[] args)
{
new TranslateJPanel();
}
}
class Canvas extends JPanel
{
private final JTextArea jTextArea;
private int offset = 0;
public Canvas()
{
setLayout(null);
jTextArea = new JTextArea("hello!!!!!!!!!!!");
jTextArea.setBounds(0,0,100,100);
jTextArea.setBorder(BorderFactory.createLineBorder(Color.BLACK));
add(jTextArea);
this.addMouseMotionListener(new MouseMotionAdapter()
{
@Override
public void mouseDragged(MouseEvent e)
{
super.mouseDragged(e);
offset++;
revalidate();
repaint();
}
});
this.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
super.mouseClicked(e);
System.out.println("M: "+ e.getX()+" "+e.getY());
}
});
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
at.translate(offset, offset);
g2.transform(at);
jTextArea.setBounds(offset,offset,100,100);
System.out.println(offset);
System.out.println(jTextArea.getX()+" "+jTextArea.getY());
System.out.println("***************************");
}
}
2条答案
按热度按时间vsdwdz231#
我找到了解决这个问题的办法。
在
void paintComponent(Graphics g)
,而不是使用
解决问题,但不知道为什么。
我是java新手,所以我不能深刻理解大家的建议中的所有警告,但还是非常感谢!
xriantvc2#
对于可拖动的文本区域,我建议如下:
不要覆盖paintcomponent或任何绘制方法,不要使用仿射变换或任何移动像素的方法。而是移动组件本身。
这可能是我使用空布局的少数几次之一。请注意,有一些布局管理器可以代替它使用(我认为camickr已经为此编写了代码,也许可以给您一个链接)。
永远不要设置jtextarea的大小,甚至是它的首选大小。
而是设置列和行属性。
将jtextarea添加到jscrollpane(实际添加到其视口)
将mouselistener和mousemotionlistener添加到移动它的jscrollpane
将mouselistener和mousemotionlistener添加到jtextarea,该区域将鼠标操作转发到保存它的jscrollpane,但请确保更改mouseevent的source属性以反映jscrollpane,而不是jtextarea。
例如: