gpt4 book ai didi

java - 如何在 JTextPane 中嵌入可调整大小的 JPanel?

转载 作者:太空宇宙 更新时间:2023-11-04 14:21:52 26 4
gpt4 key购买 nike

相反,将 JTextPane 插入到 JPanel 中会有很多问题。这不是我的问题。我需要能够将自定义 JPanel(带有拖放、拖动和鼠标单击监听器)插入到 JTextPane 中,然后将其放入 JScrollPane 中,最后放入 JFrame 中进行显示。原因是因为我需要一个支持通过在聊天客户端中拖动来调整大小的图像,该图像本身主要是文本。

足够方便的是,JTextPane 中有一个相关的方法:insertComponent(Component c),但是每当我使用它时,我的组件最终都会被压缩到恰好一行文本的空间(即使它们报告具有更大的尺寸) )。这对于普通按钮来说是完美的,但如果我需要更大的按钮,我就不走运了。我可以使用 ImageIcons 自行插入图像,但是包裹在 JPanel 内的图像根本不起作用(而且我无法向 ImageIcons 添加任何监听器,因为它们不是 GUI 元素;覆盖一个不是一个选项)。

每当用户将图像拖动到聊天客户端时,这段代码就会插入自定义 JPanel:

private void sendImage(BufferedImage im, int cl) throws IOException {
if(output == null) return;

//Send the image itself over to your friend
byte[] toSend = toBytes(im, cl);
sendString(nickname.hashCode() + "image"); //Header for image
output.writeInt(toSend.length); //Tells how many bytes to read.
output.write(toSend);

//Let the user know that the image was sent
float linmb = (float)(toSend.length / 1048576.0); //Size of file sent
addText("\n" + nickname + " sent an image! (" + linmb + " MB)\n", Color.RED.darker());

//Show the image itself
DraggerPanel d = new DraggerPanel(im, true);
text.insertComponent(d);
d.repaint();

//Spacer
addText("\n");
}

这是 DraggerPanel 的源代码,这是保存图像的自定义 JPanel:

public class DraggerPanel extends JPanel {
private BufferedImage image; //The image we're drawing
private Point startingPoint = null; //Starting point for resizing
private boolean first = true; //Is this the first drag?
private boolean lockedDrag; //If true, then lock x and y to be proportionally dragged.

public DraggerPanel(BufferedImage image, boolean lockedDrag) {
super();
this.image = image;
this.lockedDrag = lockedDrag;

//The listener for dragging events.
addMouseMotionListener(new MouseMotionListener() {
private int inWidth = 0, inHeight = 0; //Initial height and width values
private double ratio = 0; //Ratio of height to width for locked drag.

public void mouseDragged(MouseEvent m) {
if (first) { //If we're first, record initial position.
startingPoint = m.getPoint();
first = false;
inWidth = getWidth();
inHeight = getHeight();
ratio = (double)inHeight / inWidth;
} else { //Otherwise, change the size of the window.
if (!lockedDrag) {
int w = (int)startingPoint.getX() - m.getX();
int h = (int)startingPoint.getY() - m.getY();
setSize(Math.abs(inWidth - w), Math.abs(inHeight - h));
} else {
int w = (int)startingPoint.getX() - m.getX();
int h = (int)((double)ratio * w);
setSize(Math.abs(inWidth - w), Math.abs(inHeight - h));
}
}
repaint();
}

public void mouseMoved(MouseEvent m){
}
});

//Lets us know when you're not dragging anymore.
addMouseListener(new MouseAdapter(){public void mouseReleased(MouseEvent m){first = true;}});

//Set appropriate size.
if(image != null) setSize(image.getWidth(), image.getHeight());
else setSize(200,200);

//We're live, baby.
setVisible(true);
}

public void paint(Graphics g) {
if (image == null) super.paint(g);
else g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
}
}

更新1:我遵循@camickr的建议,更新了DraggerPanel以使用setPreferredSize而不是setSize,并覆盖paintComponent()而不是paint()。现在,图像具有适当的高度,但被拉伸(stretch)到 JTextPane 的宽度(这看起来就像之前所做的那样)。此外,调整大小似乎并不重要——图像根本没有改变其大小。鼠标事件肯定会发生,但不会影响大小。看来原来的问题没有完全解决,因为 JPanel 的大小不是我需要的,解决这个问题也将导致调整大小问题的解决方案。

更新2:我做到了!我终于做到了。对于遇到此问题的 future 时间旅行者,我基本上对 JTextPane 大喊大叫,不仅在我重写的 JPanel 中使用 setSize(),而且还使用 setPreferredSize() 和 setMaximumSize()。首选的与高度配合良好,而最大值则设置宽度(天知道为什么)。感谢您的提示,@camickr!

最佳答案

my components end up being squished to exactly one line of text worth of space (even though they report having a larger size).

我猜大小并不重要。

我认为您需要重写 DraggerPanel 的 getPreferredSize() 方法以返回面板的首选大小,以便文本 Pane 可以显示面板。

此外,自定义绘制是通过重写 paintComponent(...) 方法而不是 Paint() 方法来完成的。

关于java - 如何在 JTextPane 中嵌入可调整大小的 JPanel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27092550/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com