Hello.
In my game I use active rendering with 1 buffered image. I do setIgnoreRepaint(true) on JPanel and draw everything on buffered image and then display the image with one drawImage() call. So now I want to add JTextField to my game so players can chat in-game. How do I do that?
I’ve tried to bypass drawing on buffered image and I added it to JPanel and then called this.paintComponents(g) but I get JTextField with no width at all (only borders visible) and on upper middle of the screen, not where I set bounds to, plus it’s flickering. So the right thing to do is to draw it on buffered image I guess, how do I do that? Thank you.
I’ve made some progress, here’s what I wrote in JavaDesktop forums:
http://forums.java.net/jive/thread.jspa?threadID=19129
Hello.
I have a game and I would like to add chat option for players. I use active rendering with one buffered image (first I render everything to the image and then render image to the screen). So how do I add a swing component properly?
If I just use .setBounds() container.add(chat_tf) it dosn’t get rendered (which is normal since I must manually render it) but it’s there, you can select it and write stuff (although you don’t see it). When I try to call chat_tf.paint(my_buf_img) then it gets rendered but it’s always at 0,0,width,height. If I change width/height it changes accordingly, but it is always drawn starting at (0,0).
Anybody knows how to solve this or any better way to do it? Thank you.
so as it seems this isn’t so noobish of me afterall… the solution is to subclass JTextField, override paint() method so JTextField is painted on BufferedImage first, and then when need for active rendering it uses that image for display … it’s all in the sample code below, thanks to leouser from JavaDesktop forums for making most of it:
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class ActiveSwingRenderByLeouser extends JPanel implements Runnable {
private volatile boolean running = true;
private BufferedJTextField chat_tf = new BufferedJTextField();
private Image dbImage = null;
private Graphics dbg;
public static void main(String[] args) {
Runnable run = new Runnable() {
public void run() {
new ActiveSwingRenderByLeouser();
}
};
SwingUtilities.invokeLater(run);
}
public ActiveSwingRenderByLeouser() {
JFrame vframe = new JFrame("Active Swing Rendering to buffer image test");
setIgnoreRepaint(true);
setOpaque(true);
this.setLayout(null);
vframe.setContentPane(this);
vframe.setBounds(0,0,320,240);
vframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
vframe.setVisible(true);
chat_tf.setBounds(50,150,200,20);
this.add(chat_tf); // comment this to see that paint() is just painting from 0,0 on Graphics (image)
Thread animator = new Thread(this);
animator.start();
}
public void run() {
while (running) {
render();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void render() {
if (dbImage == null) {
dbImage = createImage(320, 240);
if (dbImage == null) {
return;
}
dbg = dbImage.getGraphics();
}
dbg.setColor(Color.GRAY);
dbg.fillRect(0, 0, 320, 240);
dbg.setColor(Color.BLUE);
dbg.drawRect(50, 100, 50, 50);
dbg.drawRect(75, 75, 50, 50);
dbg.drawRect(100, 50, 50, 50);
dbg.drawOval(150, 75, 100, 75);
synchronized(chat_tf){
Image image = chat_tf.image;
if(image != null){
dbg.drawImage(image, chat_tf.getX(), chat_tf.getY(), null);
}
}
Graphics g;
try {
g = this.getGraphics();
if ((g != null) && (dbImage != null))
g.drawImage(dbImage, 0, 0, null);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
catch (Exception e) {
System.out.println("Graphics error: " + e);
}
}
static class BufferedJTextField extends JTextField {
BufferedImage image;
int biwidth;
int biheight;
public void paint(Graphics g) {
synchronized (this) {
int width = getWidth();
int height = getHeight();
if (width <= 0 || height <= 0) return;
if (image == null || width != biwidth || height != biheight) {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
biwidth = width;
biheight = height;
}
Graphics g2 = image.createGraphics();
try{
super.paint(g2);
} finally {
g2.dispose();
}
g.drawImage(image, 0, 0, null);
}
}
}
}
First you must understand about layering… all objects are “painted” on the JPanel/ JFrame via layers…
because you are using the paint() or paintComponents() or drawImage(), the layering for the image is very high hence the components at a lower layering level will be “painted” over.
What you can do is instead of painting over the panel… just set the image to be the bg of the panel and painting your components over it… ^^
You can use AWT for more complex and fleixble configurations or use Swing for more complex and flexible user interfaces ^^
No, first you must understand what this topic is about. Read carefully, you totally didn’t understand any single point of it… but thank you for at least paying attention to it.
btw. I know how containers are painted
also I’ve found different kind of solution here on forums, didn’t read it yet, but CommanderKeith said it worked:
lolz… this what noobs are for… to post things which look stupid and learn from them… lolz ;D