2

Right now I am making my jinternal frames transparent using this code:

double rgbConversionBackpack = Double.parseDouble(MyClient.configFile.getProperty("BACKPACK_FRAME_ALPHA"));
double tmp = (rgbConversionBackpack / 100.0) * 255.0;
this.getContentPane().setBackground(new Color(140, 0, 0, (int)tmp));
this.setOpaque(false);

I have code on the sliders to set the alpha which all works perfectly and saves it to a properties file, yada, yada, yada. The question is how do I make the entire JInternal Frame transparent.

Right now I have only be able to set the content pane, and any other panels (etc) that are in the jinternal frames transparent, but I want to make the entire JinternalFrame(borders and all) transparent.

Screenshot below shows how on the backpack the red tinted are is partially transparent and looks decent, but still want the border to be transparent also.

enter image description here

Is there a way to override the draw super method for each of my classes the extend JInternalFrame to have it draw semi transparent(depending on value obviously)?

mKorbel
  • 109,525
  • 20
  • 134
  • 319
KisnardOnline
  • 653
  • 4
  • 16
  • 42

1 Answers1

4

You could do this by changing the AlphaComposite that the JInternalFrame's paint method uses. You have to be careful though to repaint the containing top level window at the location of the transparent component lest you have funny side effects. For example:

import java.awt.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

@SuppressWarnings("serial")
public class TransparentInternalFrame extends JDesktopPane {
   private static final Color COLOR_1 = Color.red;
   private static final Color COLOR_2 = Color.blue;
   private static final float PT_2 = 30f;
   private static final int PREF_W = 800;
   private static final int PREF_H = 500;

   public TransparentInternalFrame() {
      add(new MyInternalFrame("Foo", 50, 50, 300, 300, 0.2f));
      add(new MyInternalFrame("Foo", 400, 100, 300, 300, 0.4f));
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g;
      g2.setPaint(new GradientPaint(0, 0, COLOR_1, PT_2, PT_2, COLOR_2, true));
      g2.fillRect(0, 0, getWidth(), getHeight());
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      TransparentInternalFrame mainPanel = new TransparentInternalFrame();

      JFrame frame = new JFrame("TransparentInternalFrame");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

@SuppressWarnings("serial")
class MyInternalFrame extends JInternalFrame {
   private AlphaComposite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);

   public MyInternalFrame(String title, int x, int y, int w, int h, final float alpha) {
      super(title);
      setClosable(true);
      setBounds(x, y, w, h);
      setVisible(true);

      int sliderValue = (int) (alpha * 100);
      comp = comp.derive(alpha);
      final JSlider slider = new JSlider(0, 100, sliderValue);
      slider.setMajorTickSpacing(20);
      slider.setMinorTickSpacing(5);
      slider.setPaintLabels(true);
      slider.setPaintTicks(true);
      slider.setBorder(BorderFactory.createTitledBorder("Alpha Value"));
      slider.addChangeListener(new ChangeListener() {

         @Override
         public void stateChanged(ChangeEvent cEvt) {
            float alpha = (float) slider.getValue() / 100f;
            setAlpha(alpha);
            MyInternalFrame.this.repaint();

            Window win = SwingUtilities.getWindowAncestor(MyInternalFrame.this);
            win.repaint();
         }
      });

      add(new JLabel("My Label", SwingConstants.CENTER));
      add(slider, BorderLayout.SOUTH);
   }

   @Override
   public void paint(Graphics g) {
      Graphics2D g2 = (Graphics2D) g;
      g2.setComposite(comp);
      super.paint(g);
   }

   public void setAlpha(float alpha) {
      comp = comp.derive(alpha);
   }
}

AlphaComposite Demo

But note that this program is not fully fixed. You'll still see pixel errors if you drag one JInternalFrame over another. I still need to work the bugs out...

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • I tried your code and it works great during the jslider, but as you said when you move it around its glitchy. I tried listening to component move events, but when I try to repaint it glitches. Did you find any solution? – KisnardOnline Nov 27 '12 at 05:26
  • PERFECT, happy transparent stuffs :D –  Mar 14 '14 at 21:17