2013-05-08 52 views
0

我試圖測試->this answer <-中提供的技術。BufferedImage不在JPanel內部

private void jButton1MouseClicked(java.awt.event.MouseEvent evt) { 

     BufferedImage img = new BufferedImage(plotPanel.getWidth(),plotPanel.getHeight(),BufferedImage.TYPE_4BYTE_ABGR); 
     Graphics2D g2d = img.createGraphics(); 

     g2d.setColor(Color.red);   
     g2d.drawLine(0, 0, plotPanel.getWidth(), plotPanel.getHeight()); 

     JLabel picLabel = new JLabel(new ImageIcon(img)); 

     plotPanel.add(picLabel); 
     plotPanel.revalidate(); 
     plotPanel.repaint(); 
    } 

爲什麼plotPanel仍然保持完好?

UPDATE

這裏是很好的預期SSCCE:

package javaapplication10; 

import javax.swing.SwingUtilities; 


public class JavaApplication10 { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
       public void run() 
       { 
        new NewJFrame().setVisible(true); 
       } 
     }); 

    } 
} 

package javaapplication10; 

import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import javax.swing.ImageIcon; 
import javax.swing.JLabel; 


public class NewJFrame extends javax.swing.JFrame { 

    /** 
    * Creates new form NewJFrame 
    */ 
    public NewJFrame() { 
     initComponents(); 
    } 

    /** 
    * This method is called from within the constructor to initialize the form. 
    * WARNING: Do NOT modify this code. The content of this method is always 
    * regenerated by the Form Editor. 
    */ 
    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code"> 
    private void initComponents() { 

     plotPanel = new javax.swing.JPanel(); 
     jButton1 = new javax.swing.JButton(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     plotPanel.setBackground(new java.awt.Color(255, 255, 255)); 

     javax.swing.GroupLayout plotPanelLayout = new javax.swing.GroupLayout(plotPanel); 
     plotPanel.setLayout(plotPanelLayout); 
     plotPanelLayout.setHorizontalGroup(
      plotPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 0, Short.MAX_VALUE) 
     ); 
     plotPanelLayout.setVerticalGroup(
      plotPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 379, Short.MAX_VALUE) 
     ); 

     jButton1.setText("jButton1"); 
     jButton1.addMouseListener(new java.awt.event.MouseAdapter() { 
      public void mouseClicked(java.awt.event.MouseEvent evt) { 
       jButton1MouseClicked(evt); 
      } 
     }); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap() 
       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
        .addComponent(plotPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
        .addGroup(layout.createSequentialGroup() 
         .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 116, javax.swing.GroupLayout.PREFERRED_SIZE) 
         .addGap(0, 758, Short.MAX_VALUE))) 
       .addContainerGap()) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap() 
       .addComponent(plotPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
       .addComponent(jButton1) 
       .addContainerGap(124, Short.MAX_VALUE)) 
     ); 

     plotPanel.getAccessibleContext().setAccessibleName("plotPanel"); 
     plotPanel.getAccessibleContext().setAccessibleDescription(""); 

     pack(); 
    }// </editor-fold> 

    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) { 
      BufferedImage img = new BufferedImage(plotPanel.getWidth(),plotPanel.getHeight(),BufferedImage.TYPE_4BYTE_ABGR); 
     Graphics2D g2d = img.createGraphics(); 

     g2d.setColor(Color.red);   
     g2d.drawLine(0, 0, plotPanel.getWidth(), plotPanel.getHeight()); 

     JLabel picLabel = new JLabel(new ImageIcon(img)); 

     plotPanel.add(picLabel); 
     plotPanel.revalidate(); 
     plotPanel.repaint(); 

    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String args[]) { 
     /* Set the Nimbus look and feel */ 
     //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
     /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */ 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (InstantiationException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (IllegalAccessException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 


     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new NewJFrame().setVisible(true); 
      } 
     }); 
    } 

    private javax.swing.JButton jButton1; 
    private javax.swing.JPanel plotPanel; 

} 
+3

你可以發佈[SSCCE](http://sscce.org/)嗎? – Reimeus 2013-05-08 22:51:00

+0

'plotPanel'使用的佈局管理器是什麼? – wchargin 2013-05-08 22:58:47

+0

@ WChargin-GUI是使用NetBeans所見即所得工具自動創建的。 – 0x6B6F77616C74 2013-05-08 23:28:08

回答

2

確保添加JLabelpicLabel之後調用revalidate

plotPanel.revalidate(); 

另外,您正在使用GroupLayout,它要求將水平和垂直序列組添加到佈局中,以使任何新組件可見。這種佈局不是最容易手工編寫的,並且會產生大量的鍋爐代碼。使用更傳統的佈局管理器來熟悉代碼。見A Visual Guide to Layout Managers

2

而不是添加該組件沒有適當的限制,應該創建並使用自定義glass pane

class NewJFrame extends JFrame { 

    // ... 

    class RedLineGlassPane extends JComponent { 
     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      g2d.setColor(Color.red);   
      java.awt.Component contentPane = NewJFrame.this.getContentPane(); 
      g2d.drawLine(0, 0, 
         contentPane.getWidth(), contentPane.getHeight()); 
     } 
    } 

    private void jButton1MouseClicked(java.awt.event.MouseEvent evt) { 
     setGlassPane(new RedLineGlassPane()); 
     getGlassPane().setVisible(true); 
     repaint(); 
    } 

} 

通用編碼建議和提示

  • 不要使用GUI直到您可以自己編寫佈局代碼。我知道這很具有挑戰性,但如果您不理解正在生成的代碼,則會遇到問題。
  • 如果您必須使用GUI構建器,請不要使用Netbeans GUI構建器。這是主觀的,但我與Netbeans的建設者有幾個問題:
    • 它不允許你編輯它生成的代碼。
    • 它生成非常亂碼GroupLayout
    • 它實際上並沒有導入任何東西;它在任何地方都使用完全限定名
    • 它經常產生的代碼只是普通的不好:在你的例子中,鼠標監聽器應該是一個動作監聽器,所以用戶可以按下「Space」或其他來激活它。
    • 取而代之,我會推薦使用Eclipse和WindowBuilder GUI構建器,它過去是商業化的,但現在是開源的。這是一個更靈活的構建器,如果要編輯它生成的代碼,您可以讀取代碼並編寫代碼–,然後繼續使用構建器。
  • 閱讀Swing Trail真的很值得。
  • 如有疑問,請使用MigLayout作爲全面,易用的佈局管理器。
  • 給你的變量描述性名稱。plotPanel很好。 jButton1不是。
  • 寫入SSCCE時,請儘可能包含最少量的代碼。
    • 這將迫使您找到其中問題是,並且經常(對我而言,大約80%的時間)允許您自己找到解決方案。
    • 這也會迫使您真正理解GUI構建器爲您生成的代碼(儘管您應該已經這樣做了)。
    • 將您的代碼複製到一個新文件(單個文件!)並保持刪除代碼,直到問題消失。
    • 在你的榜樣,你可以去掉:
      • JavaApplication10類,因爲NewJFrame有一個main方法
      • 一切跟劇情面板
      • 一切與靈氣
      • 所有GroupLayout做代碼
+0

@ 0x6B6F77616C74請考慮發佈[SSCCE](http://www.sscce.org)更快,更好的幫助。 – wchargin 2013-05-08 23:45:40

2

你plotPanel使用的GroupLayout:

plotPanel = new javax.swing.JPanel(); 
javax.swing.GroupLayout plotPanelLayout = new javax.swing.GroupLayout(plotPanel); 
plotPanel.setLayout(plotPanelLayout); 

你不能僅僅將組件添加到一個GroupLayout的不指定約束條件:

plotPanel.add(picLabel); 

我不知道的GroupLayout是如何工作的,所以我會建議您在GUI構建器中創建JLabel並將其添加到您的plotPanel。也就是說,讓GUI構建器爲您創建所有約束。

然後,當你想實際的圖標添加到您只是做標籤:

picLabel.setIcon(new ImageIcon(img)); 

現在佈局管理器會自動佈局面板包括新形象。

0

主要問題是使用佈局管理器時,不能簡單地添加元素,尤其是GroupLayout。下面是完整的解決方案,立足camickr和Reimeus技巧和我進一步的調查:

private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {          
     BufferedImage img = new BufferedImage(plotPanel.getWidth(),plotPanel.getHeight(),BufferedImage.TYPE_4BYTE_ABGR); 
     Graphics2D g2d = img.createGraphics(); 

     g2d.setColor(Color.red);   
     g2d.drawLine(0, 0, plotPanel.getWidth(), plotPanel.getHeight()); 

     jLabel1.setIcon(new ImageIcon(img)); //placed on plotPanel 

     plotPanel.add(jLabel1); 
     plotPanel.revalidate(); 
     plotPanel.repaint(); 

    } 

總而言之,我們只需要關閉佈局管理器:

Windows的> Navigating-> Navigator-> [JFrame] - > plotPanel(右鍵單擊) - > Set layout-> null