Hi,
in my project I've got a class FrameProducer firing events each time a video frame has been created. Each frame is an image returned as an java.awt.Image.BufferedImage object.
I've got 2 FrameProducer objects and would like to render BufferedImage's produced by them simultaneously on the screen. I would like the picture rendered on the screen to be scalable (ie. when I drag the application-window's corner the rendered video gets smaller or bigger).
How do you think is this best do be achieved?
I've considered using java.awt.Graphics2D embedded in an java.awt.Frame, but don't know how such a thing can be done or if this is the best choice. I just need this for algorithm visualisation, it doesn't need to be nice and shiny, just fast and easy. Has maybe anyone got some ready code I could use or suggestions?
Edit: Ok, I implemented the solution as Rekin suggested, and it works. But as I'm not an Java expert and definately not a Swing expert, I'd like to ask you for kind remarks on my code - I'm sure many will benefit from that in the future.
As I said, there is a FrameProducer (never mind the implementation):
public abstract class FrameProducer extends Observable {
public abstract BufferedImage getFrame();
public void fireEvent() {
setChanged();
notifyObservers();
}
}
Then there is also a FrameRenderer waiting for events from the FrameProducer (a simple observer-pattern implementation using java.util):
public class FrameRenderer extends JPanel implements Observer {
private BufferedImage frame;
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(frame, null, 0, 0);
g2d.dispose();
}
@Override
public void update(Observable observable, Object arg) {
System.out.println("Cought an event from " + observable.getClass());
if (observable instanceof FrameProducer) {
frame = ((FrameProducer) observable).getFrame();
paint(getGraphics());
}
}
}
And then there is also the thing that needs rework: the MainFrame.
public class MainFrame extends JFrame {
FrameProducer[] producers;
public MainFrame(FrameProducer[] producers) {
this.setTitle("Playing what you feed.");
this.producers = producers;
initContents();
setVisible(true);
}
private void initContents() {
FrameRenderer renderer = new FrameRenderer();
renderer.setLocation(0, 0);
this.add(renderer);
producers[0].addObserver(renderer);
}
}
It all gets initialised in the main method:
public class FrameAccessTest {
public static void main(String[] args) {
final FrameProducer frameGrabber = new CameraFrameGrabber("vfw://0");
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
MainFrame mainFrame =
new MainFrame(new FrameProducer[] {frameGrabber});
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
How do I implement initContents() in such a way, that all the video streams provided in MainFrame's constructor as FrameProducer[] get rendered in a row and that they are scalable?
Again, thanks for any help.