2010-11-03 18 views
4

Quelqu'un peut-il expliquer pourquoi Nimbius traite le setOpaque() différemment des autres Java LaF. Il casse mon code car les composants normalement transparents ne le sont plus.setOpaque() dans java

EDIT: Le problème semble ne concerner que JTextAreas (ce dont j'ai besoin) ou des composants similaires.

EDIT EDIT: Ceci est un écran de l'application actuelle. Lors de l'application de la solution trashgod, l'arrière-plan ne s'affiche toujours pas.

alt text

EDIT EDIT EDIT: Je
essayé la suggestion de trashgod pour remplacer la peinture(). J'ai travaillé avec cela pendant des heures et je n'ai pas réussi à le faire fonctionner. J'ai réussi à faire apparaître l'arrière-plan, mais le JinternalFrame n'a pas pu être déplacé, redimensionné et son texte a été sélectionné. L'appel de super.paint (g) n'a pas réussi à résoudre la solution. Y at-il un moyen facile de faire cela que je pourrais manquer?
J'ai pris une nouvelle approche à ce sujet. À l'intérieur du JInternalFrame est un JLayeredPane.
couche 0 - JLabel
Couche 1 - JTextArea

Lorsque le JInternalFrame est déplacée ou redimensionnée:

  1. se fait invisible
  2. Prend une capture d'écran d'où il se trouvait dans le récipient de son contenu dans
  3. Peint le JLabel avec l'image qu'il a prise
  4. Se rend visible à nouveau.

Puisque je ne pouvais pas obtenir le JInternalFrame pour être transparent du tout. J'ai simulé sa transparence. Le seul problème est, il y a beaucoup de frais généraux associés à cela. Des pensées?

alt text

 

package newpackage; 

import java.awt.Color; 
import java.awt.Component; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.image.BufferedImage; 
import javax.swing.ImageIcon; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JInternalFrame; 
import javax.swing.JLayeredPane; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 

/** 
* Example of how to create a transparent internal frame. 
* @author dvargo 
*/ 
public class TransparentInternalFrame extends JInternalFrame { 

    JLayeredPane container; 


    /** 
    * Defualt constructor to set the frame up 
    * @param container The container for the frame 
    * @param opacity The opacity of the frame 
    */ 
    public TransparentInternalFrame(JLayeredPane container, int opacity) { 
     super("", true, true, true, true); 
     this.container = container; 
     initComponents(); 
     setSize(200, 200); 
     putClientProperty("JInternalFrame.isPalette", Boolean.TRUE); 
     scrollPane.setBackground(new Color(0, 0, 0, opacity)); 
     scrollPane.getViewport().setBackground(new Color(0, 0, 0, opacity)); 
     textArea.setBackground(new Color(0, 0, 0, opacity)); 
     setBG(); 
    } 

    /** 
    * Builds the GUI 
    */ 
    private void initComponents() { 

     layeredPane = new javax.swing.JLayeredPane(); 
     imageLabel = new javax.swing.JLabel(); 
     scrollPane = new javax.swing.JScrollPane(); 
     textArea = new javax.swing.JTextArea(); 

     imageLabel.setBounds(0, 0, 360, 260); 
     layeredPane.add(imageLabel, javax.swing.JLayeredPane.DEFAULT_LAYER); 

     scrollPane.setBorder(null); 

     textArea.setColumns(20); 
     textArea.setRows(5); 
     textArea.addKeyListener(new java.awt.event.KeyAdapter() { 

      public void keyPressed(java.awt.event.KeyEvent evt) { 
       textAreaKeyPressed(evt); 
      } 

      public void keyReleased(java.awt.event.KeyEvent evt) { 
       textAreaKeyReleased(evt); 
      } 

      public void keyTyped(java.awt.event.KeyEvent evt) { 
       textAreaKeyTyped(evt); 
      } 
     }); 

     addComponentListener(new java.awt.event.ComponentAdapter() { 

      public void componentMoved(java.awt.event.ComponentEvent evt) { 
       frameMoved(); 
      } 

      public void componentResized(java.awt.event.ComponentEvent evt) { 
       frameResized(); 
      } 
     }); 

     scrollPane.setViewportView(textArea); 

     scrollPane.setBounds(0, 0, 360, 260); 
     layeredPane.add(scrollPane, javax.swing.JLayeredPane.PALETTE_LAYER); 



     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
       layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(layeredPane, javax.swing.GroupLayout.PREFERRED_SIZE, 362, javax.swing.GroupLayout.PREFERRED_SIZE)); 
     layout.setVerticalGroup(
       layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(layeredPane, javax.swing.GroupLayout.PREFERRED_SIZE, 261, javax.swing.GroupLayout.PREFERRED_SIZE)); 
    } 

    /** 
    * The text will be blurred with out this 
    * @param evt 
    */ 
    private void textAreaKeyTyped(java.awt.event.KeyEvent evt) { 
     repaintAll(); 
    } 

    /** 
    * The text will be blurred with out this 
    * @param evt 
    */ 
    private void textAreaKeyPressed(java.awt.event.KeyEvent evt) { 
     repaintAll(); 
    } 

    /** 
    * The text will be blurred with out this 
    * @param evt 
    */ 
    private void textAreaKeyReleased(java.awt.event.KeyEvent evt) { 
     repaintAll(); 
    } 

    /** 
    * Capture whats behind the frame and paint it to the image label 
    */ 
    private void setBG() { 

     setVisible(false); 
     Rectangle location = new Rectangle(this.getX() + container.getX(), 
       this.getY() + container.getY(), 
       (int) this.getSize().getWidth() + 8 + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getWidth(), 
       (int) this.getSize().getHeight() + ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane().getHeight() + 4); 
     ImageIcon newIcon = new ImageIcon(createImage((JComponent) container, location)); 
     setVisible(true); 
     imageLabel.setIcon(newIcon); 
     repaint(); 
    } 

    /** 
    * Only need to update the image label if the frame is moved or resized 
    */ 
    private void frameResized() { 
     setBG(); 
     textArea.repaint(); 
    } 

    /** 
    * Only need to update the image label if the frame is moved or resized 
    */ 
    private void frameMoved() { 
     setBG(); 
     for(Component x : container.getComponents()) 
     { 
      //see if its a jinternalframe 
      if(x.getClass().getName().equals(this.getClass().getName())) 
      { 
       //cast it 
       TransparentInternalFrame temp = (TransparentInternalFrame)x; 
       //make sure its not the same one as this 
       if(x.getBounds().equals(this.getBounds())) 
       { 
        return; 
       } 
       //if they intersect 
       if(x.getBounds().intersects(this.getBounds())) 
       { 
        this.setVisible(false); 
        temp.setBG(); 
        this.setVisible(true); 
       } 
      } 
     } 

     textArea.repaint(); 
    } 

    private void repaintAll() { 
     textArea.repaint(); 
     imageLabel.repaint(); 
     layeredPane.repaint(); 
     scrollPane.repaint(); 
     scrollPane.getViewport().repaint(); 
     textArea.repaint(); 
     repaint(); 
    } 

    /** 
    * Create a BufferedImage for Swing components. 
    * All or part of the component can be captured to an image. 
    * 
    * @param component Swing component to create image from 
    * @param region The region of the component to be captured to an image 
    * @return image the image for the given region 
    */ 
    public static BufferedImage createImage(JComponent component, Rectangle region) { 
     // Make sure the component has a size and has been layed out. 
     // (necessary check for components not added to a realized frame) 

     if (!component.isDisplayable()) { 
      Dimension d = component.getSize(); 

      if (d.width == 0 || d.height == 0) { 
       d = component.getPreferredSize(); 
       component.setSize(d); 
      } 

      layoutComponent(component); 
     } 

     BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB); 
     Graphics2D g2d = image.createGraphics(); 

     // Paint a background for non-opaque components, 
     // otherwise the background will be black 

     if (!component.isOpaque()) { 
      g2d.setColor(component.getBackground()); 
      g2d.fillRect(region.x, region.y, region.width, region.height); 
     } 

     g2d.translate(-region.x, -region.y); 
     component.paint(g2d); 
     g2d.dispose(); 
     return image; 
    } 

    public static void layoutComponent(Component component) { 
     synchronized (component.getTreeLock()) { 
      component.doLayout(); 

      if (component instanceof Container) { 
       for (Component child : ((Container) component).getComponents()) { 
        layoutComponent(child); 
       } 
      } 
     } 
    } 
    private javax.swing.JLabel imageLabel; 
    private javax.swing.JScrollPane scrollPane; 
    private javax.swing.JLayeredPane layeredPane; 
    private javax.swing.JTextArea textArea; 


    public static void main(String args[]) 
    { 
     try 
     { 
      UIManager.setLookAndFeel(
       "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 

     JFrame container = new JFrame(); 
     container.setSize(800, 800); 

     JLayeredPane layerPanel = new JLayeredPane(); 
     layerPanel.setSize(800, 800); 
     container.getContentPane().add(layerPanel); 
     layerPanel.setVisible(true); 

     JPanel colorPanel = new JPanel(); 
     colorPanel.setSize(800,800); 
     colorPanel.setBackground(Color.red); 
     layerPanel.add(colorPanel); 
     layerPanel.setLayer(colorPanel, JLayeredPane.DEFAULT_LAYER); 

     TransparentInternalFrame frameA = new TransparentInternalFrame(layerPanel,0); 
     frameA.setVisible(true); 
     layerPanel.add(frameA); 
     layerPanel.setLayer(frameA, 1); 
     frameA.setSize(282,282); 

     TransparentInternalFrame frameB = new TransparentInternalFrame(layerPanel, 0); 
     frameB.setVisible(true); 
     layerPanel.add(frameB); 
     layerPanel.add(frameB,1); 
     frameB.setLocation(300, 300); 
     frameB.setSize(282,282); 

     container.repaint(); 
     container.setVisible(true); 

    } 
} 

 
+0

Code reformaté; s'il vous plaît revenir si incorrect. – trashgod

Répondre

11

Vous pouvez obtenir un aperçu de la section sur Opacity dans l'article Painting in AWT and Swing. En particulier, définir la propriété opaque ne signifie pas: "Rendre l'arrière-plan du composant transparent". Un sscce qui démontre le problème peut également être fructueux.

Addendum: En simplifiant votre exemple, il semble que la zone de texte elle-même puisse être rendue transparente, mais les Nimbus defaults affectent les bordures de la zone. Vous pourriez essayer de les changer en conséquence.

Quelques notes sur votre code:

  • Toujours construire vous GUI sur le thread d'envoi de l'événement.
  • Ne dessinez pas à partir d'un autre fil.
  • Ne pas avaler l'exception.

Addendum: Voir les modifications apportées à create().

Addendum: Vous pouvez regarder la propriété isPalette aussi

jif.putClientProperty("JInternalFrame.isPalette", Boolean.TRUE); 

alt text

import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import javax.swing.JInternalFrame; 
import java.awt.Font; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextArea; 
import javax.swing.UIManager; 

public class TransparentTextArea extends JTextArea { 

    int alpha; 

    public TransparentTextArea(int alpha) { 
     super(4, 16); 
     this.alpha = alpha; 
     this.setBackground(new Color(0, 0, 0, alpha)); 
     this.setFont(new Font("Serif", Font.ITALIC, 24)); 
     this.setEditable(false); 
     this.setText("Twas brillig and the slithy toves,\n" 
      + "Did gyre and gimble in the wabe;\n" 
      + "All mimsy were the borogoves,\n" 
      + "And the mome raths outgrabe."); 
    } 

    private static void create() { 
     JFrame f = new JFrame(); 
     f.setLayout(new FlowLayout()); 
     f.getContentPane().setBackground(new Color(0xffffc0)); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JInternalFrame jif = new JInternalFrame(); 
     JPanel panel = new JPanel(); 
     panel.setBackground(new Color(0xffffc0)); 
     panel.add(new TransparentTextArea(0)); 
     jif.add(panel); 
     jif.setVisible(true); 

     f.add(jif); 
     f.pack(); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 

     try { 
      UIManager.setLookAndFeel(
       "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       create(); 
      } 
     }); 
    } 
} 
+0

Merci, c'était très instructif. J'ai essayé de ne pas compter sur setOpaque() pour rendre les composants transparents, mais de rendre l'arrière-plan des composants avec une valeur 0 alpha. J'ai ajouté un sscce. – user489041

+0

Merci pour le code simplifié. Cela fonctionne très bien. Pour mon problème particulier, le TransparentTextArea va être contenu dans un JInternalFrame. J'ai essayé d'ajouter le TransparentTextArea à un JInternalFrame, définir l'arrière-plan à une couleur avec une valeur 0 alpha et/ou setOpaque (faux), mais dans ce cas, l'arrière-plan ne sera pas visible. Des suggestions sur la modification du code pour lui permettre de travailler avec un JInternalFrame? Encore une fois, merci pour votre aide. – user489041

+0

@ user489041: Cela semble fonctionner lorsque j'ajoute le panneau à l'image interne dans 'create()'. Désolé pour le délai de réponse. – trashgod

1

Comme expliqué here, setOpaque ne fait pas ce que vous pensez qu'il fait, et que l'échec est évident dans Nimbus. L'autre réponse qui fait référence à la couleur alpha est la bonne façon d'accomplir ce que vous voulez.

+0

Lorsque je place la couleur alpha de l'arrière-plan de JInternalFrame sur 0, l'arrière-plan JFrames ne s'affiche pas. Des suggestions pour le code sscce ci-dessus? – user489041

+0

Essayez le code ici: http://webcache.googleusercontent.com/search?q=cache:_b8VVS1MT8QJ:forums.sun.com/thread.jspa%3FthreadID%3D5347527+make+jinternalframe+background+transparent+nimbus&cd=1&hl= fr & ct = clnk & gl = nous & client = firefox-a – Yishai