Getting drawable area of an AWT frame in Mac OS X? - java

I have subclassed java.awt.Frame and have overridden the paint() method as I wish to draw the entire contents of the window manually.
However, on the graphics object, (0,0) corresponds to the upper left hand corner of the window inside the title bar decoration, not the first drawable pixel.
Can I determine the co-ordinate of the first drawable pixel (ie, the height of the decoration) in a cross-platform manner, avoiding using a Mac OS X-specific fudge factor? Will I be forced to nest a Panel component in order to find the actual drawable area of the window?
Here, my code fails to centre the blue square inside the paintable area of the window:
#Override
public void paint (Graphics g) {
g.setColor(Color.BLUE);
g.setPaintMode();
g.fillRect(30, 30, getWidth()-60, getHeight()-60);
}

You can find the frame insets by calling the getInsets method (defined in Container). Frame insets are discussed at the top of the Frame API docs.

So you want to paint the whole area and don't want a title bar at all?
Assuming that you use JDk 1.4 (at least) then you can declare the frame to be "undecorated" (java.awt.Frame#setUndecorated(boolean)). This way no title bar is created and therefore the frames-paintable area is the same as the frames-consumed area.

Related

Adding rendering offset to Frame

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).
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.
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).

How do I control individual pixels outside of a frame in Java?

I need a way to control individual pixels on a monitor that are not inside a frame. Is there any way I can directly change a pixel at a certain x,y to a certain colour?
Try using Java's "Full-Screen Exclusive Mode" API:
http://docs.oracle.com/javase/tutorial/extra/fullscreen/exclusivemode.html
In this example:
http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/extra/fullscreen/examples/CapabilitiesTest.java
You see a Java application acquiring the "ContentPane" container from the graphics device, then it creates a JPanel and adds it to content pane. Once you do that, you're free to override the paintComponent of the JPanel with something like this:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(50, 50, 50, 50);
}
You can of course set whatever you draw to any color, and you can draw something other than a rectangle too.
The drawback is, you don't get transparency, in case you're looking to draw ONLY that pixel and leave the rest of the screen preserved. This StackOverflow question investigates this issue further: java fullscreen window with transparency

AWT - rotate the entire Swing panel

I'm experiencing a problem with AWT in rotating the graphics in a panel by 90 degrees.
I can rotate the graphics in a panel by casting to Graphics2D and applying a transform.
The problem with this is that if the panel area is rectangular then part of the graphics becomes hidden. I can't seem to set clip bounds to the whole area.
If, for example, the window is short and wide then the clip region becomes narrow and tall. If the window is narrow and tall the clip region becomes short and wide. I don't know how to override this behavior.
Is there a better way of doing this or a way to work around the problem?
EDIT SOLVED:- It turns out that overriding behavior of getWidth() and getHeight() is a bad idea lol
As shown here, override getPreferredSize() on the enclosing panel to return a Dimension that can accommodate your desired view, e.g. Math.max(width, length). As shown here,
Translate the image to the origin.
Rotate the image.
Translate the image back to the center of the panel.

ToolTip for own drawings

my java application contains a JPanel on which I draw certain shapes. Now I would like to label these shapes with some kind of tooltips.
Therefore I tried to create my own "Tooltips" by using the drawString, setBackground, setColor method.:
public void drawToolTip(Graphics2D graphics, String text, Point2D position) {
graphics.setBackground(Color.RED);
graphics.setColor(Color.GREEN);
graphics.drawString(text, (float) position.getX(), (float) position.getY());
}
Unfortunately the setBackground method does not seem to work. The text background remains transparent although I set it to red. setColor and drawString just work fine.
My questions are:
What could be the reason that the setBackground method does not work?
Is there a possibility to draw a boarder arround the text without drawRect?
If I want to use "drawRect" method as a substitude to draw the text background and border: How can I make it automatically fit to the written text? Or in other words how can I get the dimensions of a specific text?
Regards Marc
Graphics2D.drawString() does not draw a background by default. You will have to do this yourself.
You can use drawRect() to draw a line border or fillRec() to draw a solid rectangle.
Oracle has a great tutorial on measuring String widths. Essentially, you need to create a java.awt.Font then get its FontMetrics and use that to calculate the width and height of your string.
A simple implementation would involve drawing onto the Graphics object of a JLabel's icon. And then simply adding the tool tip text to the Swing component.
For more information, see How to Use Tool Tips.
You can not change background color the way you expect using graphics.setBackground(..) call. Setting background color in the Graphics2D only affects the clearRect or fillRect kind of calls and not the background color of the Component.
For drawing a rectangle at a location you wish, with specific back ground, you will have to relay on following steps:
Define a rectangle - r
grpahics.setPaint() for background and
graphics.fill(r) graphcis.setPaint() for border and
graphics.draw(r) to draw border
now, comes the difficult part of drawing text in to the rectangle which involves computation of height etc. based on FontMetrics of the font you would set for drawing the text.
I googled and found an example for you here

create an hotspot and set an image without background (like earth icon) to my panel

I try to create a hotspot by Extends of canvas and I try to add it on a panel which is painted by images. So I must draw an icon (image) instead of clear rectangle of the screen. To do that I override the paint method to draw the icon I want to use. So far there is no problem; the hotspot works correctly and the icon is painted in the true size I want (32 x 24 pixels).
I try to add this hotspot after painting an image on the my panel in mypanel.paint(g) that override too.
The problem is that I use a car icon that has no background! (I hope you can understand me) Just the car icon must be shown on the panel that is painted with my images.
But an unwanted rectangle is created around the icon and makes a bad view.
How I can paint my icon on the panel without that background?
Please help me.
the problem solve by using JLable component, i extends JLabeles and set an icon to it, then i add a mouse listener to get mouse clicked event and then set Hand curser to it,
so the hotspot as a true HotSpot !!

Categories