2014-11-23 56 views
1

有很多相反的問題,將JTextPane插入到JPanel中。這不是我的問題。我需要能夠將自定義JPanel(拖放,拖動和鼠標單擊偵聽器)插入到JTextPane中,然後將其放入JScrollPane中,最後放入JFrame中進行顯示。原因是因爲我需要在支持通過在聊天客戶端中拖動它來調整大小的圖像,而聊天客戶端本身主要是文本。如何在JTextPane中嵌入可調整大小的JPanel?

足夠方便的是,JTextPane中有一個相關的方法:insertComponent(Component c),但是每當我使用它時,我的組件最終都會壓縮到恰好一行文本的空間值(儘管它們報告有更大的尺寸)。這對於簡單的按鈕來說是完美的,但是如果我需要更大的東西,我會很失敗。我可以通過ImageIcons自己插入圖像,但是包裝在JPanel中的圖像根本不起作用(另外我不能將任何偵聽器添加到ImageIcons中,因爲它們不是GUI元素;覆蓋一個不是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()。現在,圖像具有適當的高度,但被拉伸到JTextPane的寬度(這看起來就像之前做的那樣)。此外,調整大小似乎並不重要 - 圖像的大小根本不會改變。鼠標事件肯定會經過,但不會影響大小。看起來好像原始問題沒有完全解決,因爲JPanel的大小並不是我所需要的,解決方案也將導致解決調整大小問題。

更新2:我做到了!我終於做到了。對於有這個問題的旅行者來說,我基本上在JTextPane上大吼大叫,不僅在我重寫的JPanel中使用setSize(),而且還使用setPreferredSize()和setMaximumSize()。首選的一個可以很好地適應高度,而最大的設置寬度(上帝知道爲什麼)。感謝您的提示,@camickr!

回答

0

我的組件最終被壓縮到恰好一行文本的空間值(即使它們報告具有較大的大小)。

我猜想大小並不重要。

我認爲你需要重寫DraggerPanel的getPreferredSize()方法來返回面板的首選大小,以便文本窗格可以顯示面板。

此外,自定義繪畫是通過重寫paintComponent(...)方法而不是paint()方法來完成的。

+0

非常感謝你爲我設定正確的思路。更新主要帖子的結果。 :) – rushingseas 2014-11-24 06:33:13

相關問題