[java] Which surface to use?

Started by
3 comments, last by Deprecated 14 years, 5 months ago
Hello there! I've been reading some tutorials about java 2D Graphics and game programming. But there's alot of diffrent ideas on how to design the games and which surface to display the game on. 1. Which surface to use? Should I use a JFrame, JPanel, BufferStrategy or something totally different as my surface when I draw? With JFrame and JPanel I'm having trouble with the drawing, I can't get any other method than paint to draw something even when I get the surface.getGraphics() from another method. With BufferStrategy it seems like I can't draw anything in color, just grey or black.. Although I can draw pictures without problem. 2. Which Graphics object? Should I use the Graphics or the Graphics2D object? And if using the Graphics2D object, what effect will these lines of code have to the drawing? Except making it "smoother" (according to the article where I saw it).

        RenderingHints rh =
            new RenderingHints(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

        rh.put(RenderingHints.KEY_RENDERING,
               RenderingHints.VALUE_RENDER_QUALITY);

        g2d.setRenderingHints(rh);
Those who can do, do; those who can't do, do teach.
Advertisement
IMHO the best way is to use a Canvas and create a BufferStrategy within it (Canvas.createBufferStrategy). Then put the Canvas within whatever top-level component best suits you (probably a JFrame or similar). Then use BufferStrategy.getDrawGraphics and cast the result to a Graphics2D (it only returns a Graphics object for compatibility reasons, and is guranteed to be a Graphics2D object iirc).
Thank you, I'm trying it out right now but I'm still having trouble getting it to display any colors. Also, it seems like the buffer is smaller than the frame, even if I specify the same size for both of them.

public class Window extends Canvas {    private JFrame frame = null;    private JPanel panel = null;    private BufferStrategy surface = null;    public Window() {        this.frame = new JFrame("Testing");        this.panel = (JPanel) this.frame.getContentPane();        this.panel.setPreferredSize(new Dimension(800, 600));        this.panel.setLayout(null);        this.setBounds(0, 0, 800, 600);        this.panel.add(this);        this.setIgnoreRepaint(true);        this.frame.pack();        this.frame.setResizable(false);        this.frame.setLocationRelativeTo(null);        this.frame.setVisible(true);        this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        this.requestFocus();        this.createBufferStrategy(2);        this.surface = this.getBufferStrategy();    }    public Graphics2D getSurface() {        Graphics2D g = (Graphics2D) this.surface.getDrawGraphics();        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);        rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);        g.setRenderingHints(rh);        return g;    }    public void flip() {        this.surface.show();    }}

public class Main{    public static void main(String argv[]) {        Window window = new Window();        window.getSurface().setColor(Color.RED);        window.getSurface().fillRect(0, 0, 800, 600);        window.flip();    }}
Those who can do, do; those who can't do, do teach.
IIRC the size of the frame includes the title bar, so you probably just want to set the size of the canvas and let the JFrame automatically grow a bit bigger as needed.

I suspect you don't have colour problems, rather you're just seeing the default grey background. If you draw a small circle does it appear and in what colour?

At a guess because you've said setIgnoreRepaint you'll have to manually call repaint() on the canvas or frame after the flip().
No I don't see the default color. Using the code above whatever shape I try to draw shows up in dark grey, doesn't matter what color I set. I stayed up most of the night looking for a solution to the problem and I've found a few pages which suggest that there's a bug with Canvas and Microsoft Windows.

Using the code above should work in linux, but wont do anything but draw the same grey color in Microsoft Windows. But when I try to use the code supplied at this page (http://forums.java.net/jive/thread.jspa?threadID=17074&tstart=525) I can draw colors, even though that code is supposed to recreate the very same problem.

From what I've tested so far I'm pretty sure that the Canvas, the JFrame and the BufferStrategy needs to be variables in the same class. If I change the code I have now (partly working) to extend Canvas instead of using it as a variable it breaks. Adding the Canvas to a JPanel and the JPanel to the JFrame will also break the build.

I don't fully understand what they mean on the page above, I've tried not to use the Canvas but then I can't get the code to compile. Could anyone confirm this bug and if so, please explain how to solve it. This is what I've come up with so far, it does work but it is really fragile. If I try to change something directly from the window.getSurface() like window.getSurface().setColor(Color.RED); it breaks and everything will be displayed in grey.
public class Window {    private Canvas canvas = null;    private JFrame frame = null;    private BufferStrategy surface = null;    public Window(String title, int width, int height) {        this.canvas = new Canvas();        this.canvas.setIgnoreRepaint(true);        this.frame = new JFrame(title);        this.frame.setSize(width, height);        this.frame.setResizable(false);        this.frame.setLocationRelativeTo(null);        this.frame.getContentPane().add(this.canvas);        this.frame.setVisible(true);        this.canvas.createBufferStrategy(2);        this.surface = this.canvas.getBufferStrategy();    }    public void setKeyAdapter(KeyAdapter adapter) {        this.frame.addKeyListener(adapter);    }    public Graphics2D getSurface() {        return (Graphics2D) this.surface.getDrawGraphics();    }    public void flip() {        this.surface.show();    }}...public class Main {    public static void main(String argv[]) {        Window w = new Window("Test", 800, 600);        Graphics2D g = w.getSurface();        g.setColor(Color.RED);        g.fillRect(0, 0, 800, 600);        Graphics2D f = w.getSurface(); // Just trying to break it, works though.        f.setColor(Color.BLACK);        f.drawString("Hello world", 20, 20);        w.flip();    }}
Those who can do, do; those who can't do, do teach.

This topic is closed to new replies.

Advertisement