Overlay mit Transparentem JWindow und Canvas

windl

Bekanntes Mitglied
Hi liebe Newsgroup,

folgendes Problem bzw. Herausforderung.
Ich habe eine kleine Mediaanlage in Java entwickelt wo man u.a. Filme anschauen kann.
Als Player verwende ich den DSJ-Player und binde diesen als Komponente auf das Frame.
Natürlich kann der Player auch mit Overlay-Images umgehen. Problem ist nur wenn man
Farbverläufe hat - dann sieht das sehr unschön aus(weiße Flecken usw).

Die Bewegungen des Menüs usw. male ich auf einen Canvas mit BufferStrategy (das zur Erklärung).

Nun war meine Idee - ich erstelle ein JWindow und setze dies auf Unsichtbar und binde darauf einen Canvas ein und male dort mit Hilfe der BufferStrategy normal weiter!
Leider geht das nicht so - wie ich mir das vorgestellt habe - da das transparente Verhalten sich auf die innere Canvas Komponente überträgt.

Mit einem einfachen Repaint würde es funktionieren - hat aber den schlechten Effekt, dass dann die Bewegungen wieder ruckeln.

Hat jemand eine Idee wie man das Problem angehen könnte.
Auch Gedankengänge wären klasse.

Ich habe gerade noch ein Bild angehängt - dass man sieht wo das Problem liegt.
Der blaue Fleck läuft nach außen hin aus und wird transparent. Das lässt sich leider mit dem eingebauten Overlaymanager nicht realisieren.

Ich hoffe - es ist nun besser verständlich wo mein Problem liegt 😳


Danke
Uwe
 

Anhänge

  • Overlay.jpg
    Overlay.jpg
    29,9 KB · Aufrufe: 40
Zuletzt bearbeitet:
Hallo,

ich hänge jetzt mal ein Stück SourceCode ein - wie ich mir das so vorstelle - aber nicht funktioniert.
Der Source läuft unter JAVA 1.7_025.

Java:
package glasspane;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

import javax.swing.JPanel;
import javax.swing.JWindow;

import com.sun.awt.AWTUtilities;

public class MGlassPane extends JWindow{

	private static final long serialVersionUID = 3062222891648932817L;
	
	/*Hält die Innere Komponente auf der Gezeichnet wird*/
	private InnerComponent innerComponent = new InnerComponent();
	
	public MGlassPane(){
		setSize(300, 300);
		add(innerComponent);
//		AWTUtilities.setWindowOpaque(this, false);
		setOpacity(0.5f);
		setVisible(true);
		
		//Bufferstrategy initiieren und den RenderLoop startetn...
		//Wichtig ist - dass zu diesem Zeitpunkt das Fenster bereits
		//sichtbar sein muss
		innerComponent.intitStrategy();
		innerComponent.renderingLoop();
	}
	
	
	public class InnerComponent extends JPanel{
		
		private static final long serialVersionUID = -3389113752123511499L;
		//BufferStrategy
		private BufferStrategy bufferStrategy = null;
		
		public void intitStrategy(){
			//BufferStrategy erzeugen
			createBufferStrategy(2);
			//und zweisen um damit arbeiten zu können
			bufferStrategy = getBufferStrategy();
		}

		
		
		private void renderingLoop(){
			int i = 0;
			while(true){
				try{
					Graphics2D g2D = (Graphics2D)bufferStrategy.getDrawGraphics();
					g2D.clearRect(0, 0, getWidth(), getHeight());
					g2D.setColor(new Color(0,0,0,0));
					g2D.fillRect(0, 0, 200, 200);
					/**
					 * Ab hier den Code eintragen.... 
					 */
					i = i >300?0:i+1;
					g2D.setColor(Color.BLACK);
					g2D.setFont(g2D.getFont().deriveFont(Font.BOLD, 30f));
					g2D.drawString("Dies ist ein Test", i, 200);
					
					/**
					 * Code Ende...
					 */
					g2D.dispose();
					bufferStrategy.show();
					Thread.yield();
					
				}catch(Exception error){
					error.printStackTrace();
				}
			}
			
		}
	}
	
	
	public static void main(String[] args) {
		new MGlassPane();

	}

}

Hoffe - es fällt jemanden irgendwie eine Lösung ein!

Danke
Uwe
 
So ich habe jetzt eine Lösung die funktioniert.
Ob mir die Lösung auf Dauer gefallen wird muss ich erst noch entscheiden 😳

Angehängt habe ich einen Screenshot wie es im Augenblick aussieht.

Die beiden angehängten Klassen haben dann zum Ziel geführt. Wer es testen möchte muss sich von der Homepage bei Humatic den Player runterladen und einbinden.

Java:
package glasspane;

import java.awt.Dimension;
import java.awt.FileDialog;
import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.JFrame;

import de.humatic.dsj.DSFiltergraph;
import de.humatic.dsj.DSMovie;

public class MainFrame extends JFrame implements PropertyChangeListener{

	private static final long serialVersionUID = 5775743817102755209L;
	private DSMovie movie;
	
	public MainFrame(){
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		int width = 600;
		int height = 500;
		setSize(width, height);
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		int x = (dim.width / 2) - (width / 2);
		int y = (dim.height / 2) - (height / 2);
		setLocation(x, y);
		
		FileDialog fd = new FileDialog(this, "select movie", java.awt.FileDialog.LOAD);
		fd.setVisible(true);
		if (fd.getFile() == null) return;
		movie = new DSMovie(fd.getDirectory()+fd.getFile(), DSFiltergraph.EVR, this);
		movie.setLoop(true);
		try{ movie.setVolume(0); } catch (Exception ex){}
		getContentPane().add( movie.asComponent());
		setVisible(true);
		pack();
		
		new MGlassPane(this);
		
	}
	
	public void propertyChange(PropertyChangeEvent evt) {
		// TODO Auto-generated method stub
		
	}
	
	
	public static void main(String[] args) {
		new MainFrame();

	}

}

Und nun noch die GlassPane

Java:
package glasspane;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferStrategy;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JWindow;


public class MGlassPane extends JWindow implements WindowListener,ComponentListener{

	private static final long serialVersionUID = 3062222891648932817L;
	
	int i = 50;
	//BufferStrategy
	private BufferStrategy bufferStrategy = null;
	private ImageIcon icon = new ImageIcon(MGlassPane.class.getResource("HomeBarFO.png"));
	private Insets insets = null;
	
	public MGlassPane(JFrame mainFrame){
		insets = mainFrame.getInsets();
		//Größe berechnen...
		int breite = mainFrame.getWidth() - (insets.left + insets.right);
		int hoehe  = mainFrame.getHeight() - (insets.bottom + insets.top);
		
		setSize(breite,hoehe);
		setLocation(mainFrame.getX() + insets.left,mainFrame.getY() + insets.top);
		
		mainFrame.addWindowListener(this);
		mainFrame.addComponentListener(this);
		
		setAlwaysOnTop(true);
		
		setVisible(true);
		
		//Bufferstrategy initiieren und den RenderLoop startetn...
		//Wichtig ist - dass zu diesem Zeitpunkt das Fenster bereits
		//sichtbar sein muss
		createBufferStrategy(2);
		bufferStrategy = getBufferStrategy();
		setIgnoreRepaint(true);
		renderingLoop();
		
	}
	
	public void windowActivated(WindowEvent e) {}
	public void windowClosed(WindowEvent e) {}
	public void windowClosing(WindowEvent e) {}
	public void windowDeactivated(WindowEvent e) {}
	public void windowOpened(WindowEvent e) {}
	public void windowDeiconified(WindowEvent e) {
		setVisible(true);
	}
	
	public void windowIconified(WindowEvent e) {
		setVisible(false);
	}

	
	public void componentHidden(ComponentEvent e) {
		setVisible(false);
		
	}
	public void componentMoved(ComponentEvent e) {
		insets = ((JFrame)e.getSource()).getInsets();
		//Größe berechnen...
		int breite = ((JFrame)e.getSource()).getWidth() - (insets.left + insets.right);
		int hoehe  = ((JFrame)e.getSource()).getHeight() - (insets.bottom + insets.top);
		
		setSize(breite,hoehe);
		setLocation(((JFrame)e.getSource()).getX() + insets.left,((JFrame)e.getSource()).getY() + insets.top);
		
	}
	public void componentResized(ComponentEvent e) {
		insets = ((JFrame)e.getSource()).getInsets();
		//Größe berechnen...
		int breite = ((JFrame)e.getSource()).getWidth() - (insets.left + insets.right);
		int hoehe  = ((JFrame)e.getSource()).getHeight() - (insets.bottom + insets.top);
		
		setSize(breite,hoehe);
		setLocation(((JFrame)e.getSource()).getX() + insets.left,((JFrame)e.getSource()).getY() + insets.top);
		
	}
	public void componentShown(ComponentEvent e) {
		setVisible(true);
		
	}
	
	private void renderingLoop(){
		int i = 50;
		setOpacity(0.3f);
		while(true){
			try{
				Graphics2D g2D = (Graphics2D)bufferStrategy.getDrawGraphics();
				g2D.clearRect(0, 0, getWidth(), getHeight());
				g2D.setColor(new Color(1,0,0,1));
				g2D.fillRect(0, 0, getWidth(), getHeight());
				/**
				 * Ab hier den Code eintragen.... 
				 */
				i = i >300?0:i+1;
				g2D.setColor(Color.BLACK);
				g2D.setFont(g2D.getFont().deriveFont(Font.BOLD, 30f));
				g2D.drawString("Dies ist ein Test", i, 50);
				g2D.drawImage(icon.getImage(), 0, getHeight() - icon.getIconHeight(),getWidth(),icon.getIconHeight(), null);
				/**
				 * Code Ende...
				 */
				g2D.dispose();
				bufferStrategy.show();
				Thread.yield();
				
				Toolkit.getDefaultToolkit().sync();
			}catch(Exception error){
				error.printStackTrace();
			}
		}
		
	}
	

}

Wenn jemand weiterentwickeln möchte - würde ich mich freuen auch mit in den Verteiler zu kommen :applaus:

Gruß
Uwe
 

Anhänge

  • Screenshot.jpg
    Screenshot.jpg
    24 KB · Aufrufe: 36
Zuletzt bearbeitet:

Zurück
Oben