Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在JTextPane中嵌入可调整大小的JPanel?_Java_Image_Swing_Jpanel_Jtextpane - Fatal编程技术网

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

Java 如何在JTextPane中嵌入可调整大小的JPanel?,java,image,swing,jpanel,jtextpane,Java,Image,Swing,Jpanel,Jtextpane,相反,在JPanel中插入JTextPane有很多问题。这不是我的问题。我需要能够将自定义JPanel(带有拖放、拖动和鼠标单击侦听器)插入JTextPane,然后将其放入JScrollPane,最后放入JFrame中进行显示。原因是我需要有一个支持通过在聊天客户端中拖动来调整大小的图像,而聊天客户端本身主要是文本 非常方便的是,JTextPane中有一个相关的方法:insertComponent(Component c),但每当我使用它时,我的组件都会被压缩到正好一行文本的空间(即使它们报告的

相反,在JPanel中插入JTextPane有很多问题。这不是我的问题。我需要能够将自定义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的源代码,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()。现在,图像具有适当的高度,但被拉伸到JTextPane的宽度(这似乎与之前的操作相同)。此外,调整大小似乎并不重要——图像根本不会改变大小。鼠标事件肯定会发生,但不会影响大小。原来的问题似乎还没有完全解决,因为JPanel的大小不是我所需要的,而解决这个问题的方法也将导致重新调整大小问题的解决

更新2:我做到了!我终于做到了。对于有这个问题的未来时间旅行者,我基本上是在JTextPane上大喊大叫,不仅在重写的JPanel中使用setSize(),而且还使用setPreferredSize()和setMaximumSize()。首选的一个适合高度,最大值设置宽度(天知道为什么)。谢谢你的提示,@camickr

我的组件最终被压缩成一行文本,占了相当大的空间(尽管它们报告的大小更大)

我想尺寸并不重要

我认为您需要覆盖DraggerPanel的
getPreferredSize()
方法,以返回面板的首选大小,以便文本窗格可以显示面板


另外,自定义绘制是通过覆盖
paintComponent(…)
方法而不是paint()方法来完成的。

非常感谢您为我提供了正确的思路。更新了主要帖子和结果。:)