I have been trying to paint the graphics of an Applet when Applet.setVisible(false); and painting it onto my JPanel when JPanel.visible(true);
I tried to use Image i = Applet.createImage(width,height); and then paint the image to my JPanel with g.drawImage(i, 0, 0, this);
All I am left with is a blank JPanel when JPanel.paintComponent(Graphics g)... is invoked.
Is there a better approach to this?
If I'm not mistaken, the Applet won't draw when it's visibility is set to false, which explains why your JPanel is coming up blank. Is it necessary for you to hide the Applet? A typical solution would be to add the Applet directly to the JPanel by calling:
myJPanel.add(myApplet);
Of course, this mixes Swing and AWT components, which some people will object to, but it still works. Note however that a single instance of an Applet cannot be drawn to two places at once, so you cannot add your Applet to the JPanel and another place at the same time.
Related
I need some help with Java Swing components and its capabilities. I need to add a JPanel to a JFrame and paint an Ellipse2D on it. Onto the Ellipse2D I want to add another element, in my case it is a picture (right now I use an ImageIcon, maybe wrong). How can I achieve adding the Ellipse2D and the picture on the panel as shown in the image I attached?
The reason why I need the images separated is, because I need to change the filling color of the ellipse sometimes.
Thanks for any help.
What you need is to create a custom JPanel implementation and override paintComponent method.
Inside it, you just do:
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw ellipse here
// Draw your image here. It will be drawn on top of the ellipse.
}
This way, you can hold the ellipse fill color in the CustomPanel class, and just call repaint() method after you change the color.
your idea could be very good described (including code example) in the Oracles tutorial How to Decorate Components with the JLayer Class
notice JLayer is available only for Java7, but its based on (for Java6) JXLayer
you can use (I'm using) GlassPane too, with the same / similair output to the Swing GUI
EDIT
quite easy and nice output is by using OverlayLayout, there is possible to overlay J/Component(s) with Graphics e.g., a few examples
take the two images as image icons like
ImageIcon car=new ImageIcon("image path");
ImageIcon elipse=new ImageIcon("image path");
add those two image icons two label
JLabel carLabel=new JLabel(car);
JLabel ellipseLabel=new JLabel(ellipse);
and set the position of ellipse and car
carLabel.setBounds(0,0,50,50);
ellipseLabel.setBounds(10,10,50,50);
I am having an issue painting a JPanel. It paints correctly, however when I resize the parent container, the JPanel gets painted at the top left corner of the window, as well as in the correct position.
The JPanel has a custom paint method, that paints a set of components that don't belong to any JPanel (including it). These are added to the JPanel immediately before their paint method is called, and is removed immediately after:
paintOnto.setIgnoreRepaint(true);
paintOnto.add(getPaintableComponent());
getPaintableComponent().paint(g);
paintOnto.remove(getPaintableComponent());
paintOnto.setIgnoreRepaint(false);
paintOnto is a reference to the JPanel, getPaintableComponent() returns a JComponent that is to be drawn. g is the Graphics object passed through from the JPanel paint method.
The add/remove code was not required in mac at all, but under windows without it the components didnt paint at all.
This issue is only present in windows and ubuntu, not mac. Other systems are untested.
Any ideas what could be causing it? I have checked the position of the JPanel whenever it is painted, and it never is positioned at the top left corner.
Thanks
TRy to save AffineTransform of the graphics before and restore it after painting.
I am writing a mapping application in Java, using Swing for the UI (I've included a prototype drawing at the end of this post). The map is implemented using a custom MapPanel class that extends JPanel. The map is fetched from the server as a series of 300x300 images (tiles) that are painted on the MapPanel whenever its paintMap() method is called. Due to the length and complexity (multiple classes, etc.) of the code I can't include all of it here but the paintMap() method basically works like this:
// Loop for each map tile (image, xPos, yPos)
getGraphics().drawImage(image, xPos, yPos, 300, 300, null);
I would like to have another JPanel (containing a JSlider for zoom control) overlayed on top of the map panel, but I'm having difficulties getting this to work. Whenever I paint the map, the overlayed JPanel disappears. If I repaint the overlayed JPanel in the paintMap() method, it flickers badly when the map is being dragged (and thus repainted continuously).
Any suggestions for how I could implement my UI without flickering?
getGraphics().drawImage(image, xPos, yPos, 300, 300, null); // WRONG!!
Don't call getGraphics() - instead override the paintComponent(Graphics) of a JPanel or JComponent and paint when requested to do so.
Use this as the ImageObserver
This article describes using JLayeredPane and an abstract base class to overpaint arbitrary effects on a given Swing component.
I am working on a JPanel extension that is only for rendering its contents to a BufferedImage, which I then use as a texture for rendering in OpenGL. For this, I create my special JPanel extension with a layout manager etc., like I would if I was building a normal Swing GUI.
In order to render it to an image, I make sure to call doLayout first and then I use the printAll(java.awt.Graphics) method to print it and the added components:
Graphics2D g = image.createGraphics();
printAll(g);
Swing itself (EDT, RepaintManager etc) is never involved, I just create the components (outside any window or frame) and directly use printAll.
This is working perfectly well for most "atomic" components (such as buttons, labels, lists), but I hit on a problem with the JScrollPane. Whatever I try, the JScrollPane will never paint its viewports (the main viewport and the scroll bars) to the given Graphics but only its border, and even manually calling printAll on the viewports yields no result.
I attached two screenshots which show a "before and after" of a simple GUI consisting of a JList and a JButton. On the first image, I use the raw JList, in the second image, I wrapped it into a JScrollPane using new JScrollPane(list).
I failed to find any magic inside the JScrollPane code related to painting its viewports. Maybe something needs to be initialized that Swing would do, but I forgot. Is there any way I can get those viewports to show up?
See Why does the JTable header not appear in the image? for some general tips about rendering components to images. Try calling combinations of validate(), addNotify() & doLayout() as mentioned in the code of that thread.
not sure from your question
1) if there is about JScrollPane or JViewport, becasue JViewport is only (from JScrollPane) about visible Rectangle on the screen,
2) every JComponent returns Graphics2D
3) please why do you call doLayout() / addNotify(), in the case that all events for Swing GUI are done on EDT, or are there some events based on Swing Timer
4) better would be edit your question with SSCCE that generated un_wanted output to the GUI
5) for JViewport you have to create and override your own RepaintManager
6) maybe stupid question, please ensure us that there isn't any animations of JComponent, meaning moving accross JScrollPane and freezed on EDT by Thread.sleep(int)
EDIT (could be most important)
7) for OpenGL you have to implements Components based on Java AWT
I'm trying to make a paint editor with Java in which I have a toolbar with the objects that I would like to paste in the canvas. I'm using Swing components to make the GUI, but when I looked for the way of making the canvas, I only found the class canvas from AWT.
Is there any way to make something similar to canvas with Swing? (for example, JPanel?) I have read that using the class canvas from AWT with a GUI made with swing won't work correctly, is that true?
In order to make a custom 'Canvas' in swing you usually write a subclass of a JPanel. Then, you must overwrite the protected paintComponent(Graphics g) method of JPanel.
In the paint method, you can call methods on the Graphics object to actually draw on the JPanel.
As always, the Java Tutorials have a great reference on this to get you started.
You'll probably want to make a subclass of JPanel and implement your own way of painting components you want to draw onto the panel.
The basic approach will probably be along the line of assigning a MouseListener to the subclass of JPanel, then implement painting functionality.
The basic idea may be something along the line of:
class MyCanvas extends JPanel implements MouseListener
{
Image img; // Contains the image to draw on MyCanvas
public MyCanvas()
{
// Initialize img here.
this.addMouseListener(this);
}
public void paintComponent(Graphics g)
{
// Draws the image to the canvas
g.drawImage(img, 0, 0, null);
}
public void mouseClicked(MouseEvent e)
{
int x = e.getX();
int y = e.getY();
Graphics g = img.getGraphics();
g.fillOval(x, y, 3, 3);
g.dispose();
}
// ... other MouseListener methods ... //
}
The above example is incomplete (and not tested -- it definitely won't compile), but it gives an idea about how to implement a MyCanvas class in which a user can click on and draw circles.
The img object is used to hold the image of the canvas. The paintComponent method is used to paint the img object to the canvas. In the mouseClicked method, the Graphics object associated with img is retrieved in order to fillOval onto the image.
Since one the requirements is to paste images onto the canvas, it may be a good idea to hold some Images that you want to paste into the canvas. Perhaps something along the line of:
Image[] myImages; // Used to store images to paint to screen.
Then, in the routine to paint the image onto img stored in MyCanvas:
g.drawImage(myImage[INDEX_OF_DESIRED_IMAGE], 0, 0, null);
By using the drawImage method of the Graphics object, other Images can be drawn onto Images.
As for the question on AWT and Swing, yes, it is true that you do not want to mix components from the AWT and Swing, as they differ in the way they render GUI components. AWT is based on heavyweight components, meaning they native windowing for painting the GUI, while Swing is based on lightweight components, meaning the GUI is drawn by Java itself without using native components.
A good guide on the difference of AWT and Swing is provided in Painting in AWT and Swing article from Sun.
Simply subclass JComponent.
JPanel is an inappropriate class. It is often suggested as it appears to have setOpaque(true) invoked on it automatically. It's actually the PL&F which does that, and whether or not it actually happens is implementation and vendor dependent.
Canvas is a heavyweight component. That is to say that it is controlled by the underlying windowing system. The result is that it will typically be drawn over the top of Swing components, without respect to z-order or clipping (putting it in a scroll pane will give odd behaviour).
You might want to look at the Minueto API. It is a very simple to use graphics api, and you can combine the Java event listening with it to provide your drawing capability.
http://minueto.cs.mcgill.ca/