Is there any way I can print/show images on top of each other. The picture on top will always be positioned a little lower so that the one under will show partially. How can I decide which image is on top of what image? What layout lets me do this kind of positioning?
Is there any way that I can make a border appear on the image when I click it, and then move to (doesnt have to be animated, can be a "jump") where I click next inside the JFrame.
I've been trying to do this whole day now (I'm pretty new to swing), before I carry on I'd like to know if I'm trying something impossible.
So far I've been printing the images right on to the JFrame as JPanels... Inside the JPanel I add in the paintComponent(Graphics g) method: g.drawImage
Sounds like a Swing tutorial is in order.
What you're describing shouldn't be very hard. Instead of painting the images directly, load them up in ImageIcons, and pass those to JLabels. That way you can manipulate your images as JComponents, using layout managers, or direct coordinates by setting the layout to null. You can set the Z-Order with setComponentZOrder regardless of the layout you choose. You can draw borders by adding swing borders (see BorderFactory) to the JLabels. You can handle the manipulation with MouseListeners.
Look into Root Panes. You may be able to do something with the Layered Pane or the Glass Pane. I would try the Layered Pane first.
Related
I want to add JLabels to JFrame directly. I don't want use JPanel. But I have a position problem. I set layout as null.
I tryed draw line to see what's going on.
#Override
public void paint(Graphics g){
g.setColor(Color.red);
g.drawLine(0, 31, super.getWidth(), 31);
}
And the zero is actually 31.
Drawing screenshot
Why? And how can I fix that?
I want to add JLabels to JFrame directly. I don't want use JPanel.
If you're adding the JLabel "to the JFrame" then you're adding it to the contentPane which is almost always a JPanel, so 99% of the time, you're still using a JPanel, even without trying to.
But I have a position problem. I set layout as null.
Which is almost always a bad thing to do. This makes for GUI's that don't work on all platforms, fighting against the Java philosophy and structure.
And the zero is actually 31.
Why? And how can I fix that?
Because of the top part of the JFrame is taken up by the OS window's menu bar. The contentPane, starts 31 pixels below the top of the JFrame (in your case -- different for different OS's and screen resolutions).
Best to avoid drawing directly on the JFrame, which is actually composed of many sub-components -- the content pane, the root pane, the glass pane,... and instead draw within the paintComponent method of a JPanel that you either add to the contentPane or make as the contentPane. Then 0,0 is the top left of the usable portion of your main window.
Also, please elaborate more on the underlying reason why you're trying to avoid use of a JPanel. Your issue may in fact be an XY Problem type issue.
Positions in a JFrame are relative to the edge of the window, not the content pane. To get the dimensions of the content pane, use getContentPane().getWidth() and getContentPane().getHeight().
So the intial setup for this issue is that there's a JDialog, and inside that I've placed a JPanel that would house the rest of the components (since painting the JDialog itself is apparently a bad idea). This JPanel has an overriden paintComponent(Graphics g) method that only paints the background and adds a faint border for aesthetic purposes.
Now inside that is a series of JPanels that categorize the contained form components, and each JPanel has an overridden paintComponent(Graphics g) as well, painting a semi-transparent background.
Inside each of those JPanels is where I start to have some issues, presumably with transparency. I have JTextFields, JCheckBoxes, JLabels, JSliders, etc inside these panels, and when you interact with one (hover, click, etc), the background goes from transparent to opaque, with an occassional ghosted image from another field (which appears slightly random sometimes). I'm using a custom LAF called Web, but I tested with other built-in LAFs and the same thing happens.
Is this a glitch with Java or did I mess something up? If so, how can I patch this up? I can paste code fragments later if necessary, but I've used several custom classes and nine-patch style image stitching which may make the code fragments hard to follow. Thanks in advance!
If you are painting components with a transparent background it is very important that the component is marked as transparent (setOpaue(false)) so that the repaint manager knows that it must paint the components below it.
It is also very important that when you are performing custom painting that you call super.paintComponent first.
This is especially important in the case of transparent components, as this prepares the Graphics context for painting.
Graphics is a shared resource. All the components painted in your window will share the same Graphics object, meaning that if you don't allow paintComponent to first prepare it, then you will see what was previously painted on it.
I need to layer JPanels but I don't know how. I have 3 panels, the first is for the background, the second is for a Character/Sprite to move around and layers the first panel(background, and the third is a bar off to the side (Used for buttons and has nothing to do with they layers). How do I layer panel 1 and panel 2?
edit: The background is made up of a grid of 25x25 labels with an icon in each.
Some options:
Use a JLayeredPane which can layer components using a z-order Integer constant. Remember that when doing this, you are also essentially using a null layout, and so you will be fully responsible for setting the size and position of all components added to the JLayeredPane.
If all the background is doing is painting an image, you could use a single JPanel, and then simply paint the image as a BufferedImage that is displayed in the JPanel's paintComponent method. The sprite would also be painted but its location would vary.
See How to Use Layered Panes.
Don't forget to use:
panel.setOpaque(false);
Or you don't need to layer panels. You can just paint a background image on the panel. See Background Panel for an example of this.
We just recently worked on a top-down video game for my CSC class. All we did was draw the background and then all the sprites after it in the paint() method on the JPanel. We also used a Timer and an ActionListener to constantly update the JPanel.
Give that I have written a JPanel with many different components on it, is there a way to apply an overall "dilate" ability on the panel so that everything in it stretches proportionally when I resize my window?
That is, if I manually resize my window to be 1/4 the size, everything in the panel should also shrink by 1/4 so the new panel is just a dilation of the first. Given that I have not designed the individual components inside to do this (there are many) is there any easy way to make the panel behave this way?
UPDATE: In order to be more clear on the solution I need, I will describe the panel contents:
The panel is a "game" of sorts, with a single null-layout and dozens of ImageIcons flying around the screen at any time. The ImageIcons are preloaded PNG files, which already have a permanent size. Of course, I could manually resize each ImageIcon and reposition them relative to window size, but that would involve recoding many components.
There are no buttons or text to worry about, so what I'm really looking for is some kind of "postprocessed" resize where the panel simply shrinks whatever's rendered by some porportion (think of resizing an image in Photoshop).
One option is of course to give up swing all together and use some 3rd party widget component library which draws itself using any Graphics. Then you can either draw the widgets on the image and resize the image, or, better yet, apply a transform to the graphics object you pass to the library.
If you do want to stick with swing there is the SwingUtilities.paintComponent method, which you could use to paint the Panel onto a BufferedImage which you could then resize. (I've used this myself to do some nice transitions between "views" in a game.)
The problem is of course that you somehow need to translate the user input accordingly. I have no solution for this right now, but the above perhaps helps you in some way.
You can try to override paintChildren() method of the panel and scale graphics to achieve desired visible size.
You could try J(X)Layer, see http://www.pbjar.org/blogs/jxlayer/jxlayer40/
Using layout managers instead of absolute positioning of the widgets will give you this behaviour. See the oracle tutorials: Using Layout Managers.
Do you really want fonts to resize on resize events? I don't know a layout manager which will do that for you.
I want to make board(map) like this in Java.
Each small hexagon is image.
Suppose I have two Java classes. Canvas(big hexagon) and Hexagon. First is entire board from which I generate randomly all small hexagons. Both classes derived from JPanel. Now I have GridLayout. How can I arrange layout like this?
Why do you need the small hexagon panels?
I would rather just define List (list of Hexagons) each with desired position and just override paintComponent() method of main JPanel. You can use this http://java-sl.com/shapes.html to create hexagon shapes.
To track mouse click you can use contains() method of Shape.
you can
1) common way
by painting to the JPanel/JComponent by override paintComponent() (I asumed that there are Image/BufferedImage/Icon/ImageIcon)
2) by place Icon/ImageIcon to the JLabel
you have look at JLayer (since Java7) or use (former) JXLayer
OverlayLayout or customizations for OverlayLayout by #camickr
The point of layout manages is to make it possible for the layout to auto-adjust when components change their size or the window does.
It looks like your hexagons will always be the same size, so you really don't need a layout manager, and positioning the hexagons absolutely should be fine.