I am creating a lightweight client for the game Runescape that has various user features such as custom keybinds/hotkeys. I'm pretty good with java and swing, but AWT and applets I am mediocre at best. I was able to get the applet downloaded and displayed on a JPanel and then in a JFrame and the game runs perfectly so far. However, when adding features I ran into a problem when I tried to implement a screenshot function to the client.
It's hard to post a concise working example so I'll post the methods I was trying based off of some other SO answers I was reading. I tried creating BufferedImage from the Applet, applet Canvas, the JPanel it is handled by, and the JFrame.
Here are some things I tried to create a screenshot from the Applet canvas:
public BufferedImage getScreenShot() {
//getting the applet canvas
Canvas canvas = (Canvas) this.getApplet().getComponent(0);
//bufferedImage to draw to
BufferedImage image = new BufferedImage(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_INT_ARGB);
//Graphics2D g2=(Graphics2D)image.getGraphics();
//test.print(g2);
//g2.dispose();
Graphics g = image.getGraphics();
Image image2 = canvas.createImage(canvas.getWidth(), canvas.getHeight());
canvas.print(g);
System.out.println("Canvas Size: " + canvas.getSize().width + " x " + canvas.getSize().height);
return image;
}
This one I tried in the JPanel class which holds only the Applet:
public BufferedImage getScreenShotFINAL(){
BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
applet.paint(bi.createGraphics());
return bi;
}
I understand that the idea here is to create an off-screen BufferedImage, then to create a Graphics2d object and to then call the applet's paint() method to paint to the off-screen image. I tried this solution from here:
public BufferedImage getScreenShotFINAL2() {
Dimension size = applet.getSize();
BufferedImage offScreenImage = (BufferedImage) applet.createImage(size.width, size.height);
Graphics2D g2 = offScreenImage.createGraphics();
g2.setBackground(applet.getBackground());
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.clearRect(0, 0, size.width, size.height);
applet.paint(g2);
return offScreenImage;
}
When saving the BufferedImages these and other methods I tried to a file the images just show up as black, just the default background color. Is there a good way to just get a BufferedImage from the JPanel which would include the Applet so I never have to deal with the Applet directly? Another thing, I had to override the java Canvas class in order to get the game to display (because it is double buffered I believe). I tried following a bunch of solutions from here but had no success. Any suggestions would be greatly appreciated. I also can provide a link to the full project or the custom Canvas project if you would like. Thanks!
EDIT
Here is the Canvas class which overrides the java AWT one. Didn't write it, followed a tutorial for this one and I think this is where the problem is, because the paint() method only calls clearRect():
package java.awt;
import Client.Client;
import java.awt.image.BufferStrategy;
import java.awt.peer.CanvasPeer;
import javax.accessibility.*;
import loaders.ClientPool;
public class Canvas extends Component implements Accessible {
private Client client = null;
private static final String base = "canvas";
private static int nameCounter = 0;
private static final long serialVersionUID = -2284879212465893870L;
public Canvas() {
super();
}
public Canvas(GraphicsConfiguration config) {
this();
setGraphicsConfiguration(config);
}
@Override
void setGraphicsConfiguration(GraphicsConfiguration gc) {
synchronized(getTreeLock()) {
CanvasPeer peer = (CanvasPeer)getPeer();
if (peer != null) {
gc = peer.getAppropriateGraphicsConfiguration(gc);
}
super.setGraphicsConfiguration(gc);
}
}
@Override
public Graphics getGraphics(){
if (this.client == null) {
this.client = ClientPool.getClient(this);
}
if (client != null) {
//call custom draw functions for specific client. for drawing/double buffering
return client.drawGraphics((Graphics2D) super.getGraphics());
}
return super.getGraphics();
}
@Override
String constructComponentName() {
synchronized (Canvas.class) {
return base + nameCounter++;
}
}
@Override
public void addNotify() {
synchronized (getTreeLock()) {
if (peer == null)
peer = getToolkit().createCanvas(this);
super.addNotify();
}
}
@Override
public void paint(Graphics g) {
g.clearRect(0, 0, width, height);
}
@Override
public void update(Graphics g) {
g.clearRect(0, 0, width, height);
super.paint(g);
}
@Override
boolean postsOldMouseEvents() {
return true;
}
@Override
public void createBufferStrategy(int numBuffers) {
super.createBufferStrategy(numBuffers);
}
@Override
public void createBufferStrategy(int numBuffers,
BufferCapabilities caps) throws AWTException {
super.createBufferStrategy(numBuffers, caps);
}
@Override
public BufferStrategy getBufferStrategy() {
return super.getBufferStrategy();
}
@Override
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTCanvas();
}
return accessibleContext;
}
protected class AccessibleAWTCanvas extends AccessibleAWTComponent
{
private static final long serialVersionUID = -6325592262103146699L;
public AccessibleRole getAccessibleRole() {
return AccessibleRole.CANVAS;
}
}
}