JLayeredPane dynamic resizing problem
Problem -I can't get JLayeredPane to resize dynamicly.
The code in the following class is where my problem lies.
the whole lot compiles as Problem.java to give a nice animated demo.
My code is a little fatter than it would need to be but I submit it
as I have to illustrate what I'm looking to achieve in my app
- a containing component that holds JComponents transparently
(behaves like it were the JComponent it contains) whilst allowing me to:
1 mask the component in any way I want to
(with a static image or a filter (rasterMan))
2 mask it from user input
it took me ages to get as far as I have.
I'm not sure why the paint method NEEDS to be as it is,
-that's another quirk though.
I've written a demo of the problem - if this lot gets cut and pasted,
saved as Problem.java and compiled you get some pretty animation showing
problems - a secondary problem is the mouse doesn't work on the Masker.
I need to solve this in java 1.4. Thanks!
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;
class Maskerextends JLayeredPaneimplements MouseListener{
//I'd like this class to behave like a JPanel with regards to its
//looks as its composition changes.
private JComponent component;
private JLabel mask;
privateboolean masked;
Masker(){
super();
setOpaque(false);
}
void setComponent(JComponent c){
component = c;
Dimension s = c.getPreferredSize();
int w = (int)s.getWidth();
int h = (int)s.getHeight();
mask =new JLabel();
c.setBounds(0, 0, w, h);
mask.setBounds(0, 0, w, h);
add(component,new Integer(0));
add(mask,new Integer(1));
mask.addMouseListener(this);
setMask(false);
}
publicvoid mousePressed(MouseEvent e){}
publicvoid mouseReleased(MouseEvent e){}
publicvoid mouseEntered(MouseEvent e){}
publicvoid mouseExited(MouseEvent e){}
//not working in my demo - I don't know why.
publicvoid mouseClicked(MouseEvent e){
setMask(!masked);
}
//not working as I want it to. anywhere.
public Dimension getPreferredSize(){
if(component !=null)return component.getPreferredSize();
returnnew Dimension(0,0);
}
publicvoid setPreferredSize(Dimension d){
if(component !=null) component.setPreferredSize(d);
super.setPreferredSize(getPreferredSize());
}
//part of what I want to achieve
privatevoid rasterMan(WritableRaster raster){
int w = component.getWidth(), h = component.getHeight();
float[] mults =newfloat[]{0.4f, 0.4f, 0.4f, 1f};//acts like stained glass mixed with xray specs
float[] rgba =newfloat[4];
for(int y=0; y<h; y++){
for(int x=0; x><w; x++){
rgba = raster.getPixel(x, y, rgba);
for(int i=0; i><4; i++) rgba[i] *= mults[i];
raster.setPixel(x, y, rgba);
}
}
}
void setMask(boolean value){
mask.setVisible(value);
masked = value;
repaint();
}
publicvoid paint(Graphics g){
if(masked){
int w = getWidth(), h = getHeight();
BufferedImage buffer =new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
mask.setIcon(new ImageIcon(buffer));//could be non transparent but I only want clear pixels
Graphics2D g2 = buffer.createGraphics();
super.paint(g2);
g2.dispose();
WritableRaster raster = buffer.getRaster();
rasterMan(raster);
g.drawImage(buffer,0,0,this);
}else{
super.paint(g);
}
}
}
//ilustrates my problem main problem. the mouse not controling the masker is secondary.
class Problemextends JPanelimplements Runnable{
ToMask healthy;
ToMask stunted;
Thread grower;
int size = 0;
Problem(){
healthy =new ToMask("healthy");
JPanel a =new JPanel();
a.add(healthy);
JPanel abox =new JPanel(new BorderLayout());
abox.setBorder(new LineBorder(Color.red, 4));
abox.add(a);
stunted =new ToMask("stunted");
Masker b =new Masker();
b.setComponent(stunted);
JPanel bbox =new JPanel(new BorderLayout());
bbox.setBorder(new LineBorder(Color.red, 4));
bbox.add(b);
add(abox);
add(bbox);
grower =new Thread(this);
grower.start();
}
privatestaticvoid createAndShowGUI(){
Problem app =new Problem();
JFrame frame =new JFrame("a problem...");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(app);
frame.setSize(640, 280);
frame.setVisible(true);
}
publicstaticvoid main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
publicvoid run(){
createAndShowGUI();
}
});
}
publicvoid run(){
boolean fliped =false;
while(true){
if(size > 100 || size < -70) fliped = !fliped;
if(!fliped) size += 10;
else size -= 10;
healthy.sizeTo(100+size, 100+size);
stunted.sizeTo(100+size, 100+size);
repaint();
try{
Thread.currentThread().sleep(500);
}catch (InterruptedException e){}
}
}
}
class ToMaskextends JLabel{
ToMask(String s){
super(s);
sizeTo(100, 100);
setBorder(new LineBorder(Color.black, 1));
}
void sizeTo(int w,int h){
BufferedImage buffer =new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = buffer.createGraphics();
g2.setColor(Color.red);
g2.fill(new Ellipse2D.Float(w/5f, h/2f, w, h/3f));
g2.setColor(Color.green);
g2.fill(new Ellipse2D.Float(w/5f*2, h/-5f, w/5f, h*1.4f));
g2.setColor(Color.yellow);
g2.fill(new Ellipse2D.Float(w/-3f, h/-5f, w/3f*2, h/3f*2));
g2.setColor(Color.blue);
g2.drawString("thanks for", w/10f, h/3f);
g2.drawString("looking", w/5f, h/2f);
g2.dispose();
setIcon(new ImageIcon(buffer));
}
}

