3

The scenario here is as so: I am using a Frame object to do some lower-ish level rendering with AWT (no Swing). The only issue is, Frames, when rendering directly to them, do not account for their borders. So, as we all likely know, rendering a Rectangle at (0,0) does not look like it is doing the right thing. This is because (0,0) is the literal top-left of the Frame.

So the problem is, instead of adding in the Frame insets for everything to be rendered on-screen like so:

//This is within the rendering method in the Frame subclass. A buffer strategy is already created
Graphics2D g = (Graphics2D)bufferStrategy.getDrawGraphics();
g.clearRect(0, 0, getWidth(), getHeight());
g.setColor(Color.WHITE);
Insets insets = this.getInsets();
g.drawString("FPS: " + getFPS(), 100 + insets.left, 100 + insets.top); //<-- Ugh.
g.dispose();

I would like to be able to simply add an offset of sorts to the underlying graphics of the Frame. Is this possible? To be clear, it would be nice to have some functionality like this:

g.setDrawingOrigin(x, y);

With this sort of method, I could get away with murder. I don't know why there wouldn't be one buried somewhere...

NOTE: It is a Frame and not a JFrame, so we lack a content pane to reference. Another thing, it would be nice to avoid adding any other component to the Frame. I am trying to keep this as lightweight as possible (hence, the Frame instead of JFrame. Okay, there isn't much of a difference, but let me have my fun :D).

CoderTheTyler
  • 839
  • 2
  • 11
  • 30
  • 2
    Instead of rendering to the frame, use a component and paint your custom painting to it, it will then be laid within the frame – MadProgrammer Aug 10 '14 at 02:28
  • I normally just throw a Canvas onto the Frame and let the pack() method do all the work. I was just curious in this particular situation though. Thanks for clarifying that point though :D – CoderTheTyler Aug 10 '14 at 02:33

2 Answers2

3

The method you are looking for is Graphic's translate(int, int).

So you would call,

g.translate(insets.left, insets.top);

One other approach is that instead of drawing to the Frame directly, you can add another component which fits and uses all of the Frame's space, and then do all the drawing in that subcomponent's paint method where x and y are where you expect.

NESPowerGlove
  • 5,496
  • 17
  • 28
  • Wow. I have to admit, that WAS much simpler than I expected. I don't know why it didn't occur to me earlier, but ah well! Thank you! Your advice of adding another component is very wise, but I am trying to avoid it. It may be a bit knit-picky of me, but its really for a proof-of-concept design. Anyway, thank you! – CoderTheTyler Aug 10 '14 at 02:08
  • 1
    @MrDoctorProfessorTyler No problem. Sometimes these old classes have poor method naming it seems, so sometimes it's best to open up the Javadoc page for the class and search for keywords, like in this case the word origin. – NESPowerGlove Aug 10 '14 at 02:23
  • Thank you for the advice. I'll be sure to dig deeper next time before resorting to asking here – CoderTheTyler Aug 10 '14 at 02:30
2

Directly from the JavaDocs...

The size of the frame includes any area designated for the border. The dimensions of the border area may be obtained using the getInsets method, however, since these dimensions are platform-dependent, a valid insets value cannot be obtained until the frame is made displayable by either calling pack or show. Since the border area is included in the overall size of the frame, the border effectively obscures a portion of the frame, constraining the area available for rendering and/or displaying subcomponents to the rectangle which has an upper-left corner location of (insets.left, insets.top), and has a size of width - (insets.left + insets.right) by height - (insets.top + insets.bottom).

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366