Making a graphics object move - java

In my code I override the paintComponent method and draw a rectangle inside JPanel.
The JPanel is then added to JFrame and I use a method that updates the position of the rectangle via a Thread.
The rectangle does actually move .. but only when I minimize the window and maximize it back again. So in other words.. it doesn't do it as I'm looking at it.. the rectangle will just sit there.. but after I minimize and bring the window back up, the rectangle will have moved.
What can I do to fix this?

I am guessing you forgot to call the Repaint of the JPanel whose paintComponent you are overriding everytime you update the object. The reason you are only seeing the change on minimize/maximize is because that is when swing calls the repaint of the component.

Related

Can't understand JPanel setBackground method behavior

JPanel.setBackground method does nothing (although opaque attribute is true) if super.paintComponent father method isn't being called.
I have read a lot of similar questions here about this issue, and in each one of them I've only found solutions without explanation that helped me to understand why setBackground method when written before adding the JPanel to JFrame changes the JPanel background color, while when the setBackground is written inside paintComponent nothing is changed (only when calling father's paintComponent method as already mentioned).
Is it somehow related to Graphics object?
I have tried to change JPanel's opaque attribute to true and using setBackground(COLOR.BLACK) in paintComponent() method I had overriden in a class that extends JPanel
paintComponent(Graphics g)
{
this.setOpaque(true);
this.setBackground(COLOR.BLACK);
}
I expect that the JPanel background color will be black
Instead, background color is the default one
Well, first of all if you're using paintComponent(Graphics g) method, the first line you need to have inside is: super.paintComponent(g) otherwise you're breaking the paint-chain.
This will allow the parent component to draw the default component, before any customizations you do to it. If you don't do it, well, is like having a drawing in a piece of paper, imagine a circle, then cutting that circle and then trying to paint the outside.
Here's a more in-depth answer to How does super.paintComponent(g) works
However I wouldn't write
this.setOpaque(true);
this.setBackground(COLOR.BLACK);
inside the paintComponent(...) method, as it gets called several times and you can't control when it will ever get called. I would put those lines in a constructor, unless you want to change it later in your program while it's being painted depending on the state of your program or a gradient maybe.
For this part:
why setBackground method when written before adding the JPanel to JFrame changes the JPanel background color
Honestly, I don't understand what you mean.
Why do you say that if i won't call super.paintComponent(),it will break the chain? It's still drawing all the shapes and lines i want using graphics object.
From the docs:
The JPanel has a UI delegate which performs the background painting for itself. You call it by using super.paintComponent(g) and we pass the Graphics component to prevent irrevocable changes such as Graphics.translate
Your JPanel knows how to paint its children, but requires some help to paint itself, and this help comes from its parent.
When I mentioned "break the paint chain" I didn't mean nothing would paint, but that you would get strange behaviors such as the one of the JPanel's background disappearing or not being set.
In addition,something weird happens if the argument i'm sending to setBackground method is a random color(using Random object). JPanel changing color very quickly although i'm not doing anything(not minimizing,not resizing,etc).Can you consider why?
As I said before, the paintComponent gets called several times and you don't have control over when it will be called, even moving your mouse or something else will trigger the panel to repaint.

JPanel custom paint

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.

repaint() method causes a second, non-functional JMenuBar to appear?

I am creating a program in which the user can draw lines and erase them. I am able to create my window and create a functioning JMenuBar. When the drawing capability is not enabled, everything is fine. But when the drawing capability is enabled, a second JMenuBar is painted below the original. This menu bar is not functional, and sometimes when it is drawn, ALL of the graphics on the screen are repainted lower as well. Re-sizing the window in any way remedies these problem.
I would post pictures but, you know, I'm a new user and can't.
I have been able to narrow the problem down to a point in my paint() method. Need to know: When the mouse is dragged, the repaint() method is called. It uses my paint() method which calls the paintObject(Graphics g) method in my Line class. The JMenuBar error is appearing at the END of the paint method in the top class.
public void paint(Graphics g)//paint() in the top class
{
for(int i = 0; i < objs.size(); i++)//Loop that finds all Tool(Line) objects that
((Tools)objs.get(i)).paintObject(g);//have been drawn, and redraws them.
//This part of the code completes successfully with no error.
}//ERROR OCCURS HERE!!!!!!
I have no idea why this is happening. As a side note, there is also a JTextField on the screen that doesn't appear until it is highlighted. Thanks for at least reading this far!
Edit: I'll go on a limb, I'll bet you in fact are drawing directly on the top level window (JFrame or JApplet or JDialog...) and have added the mouse listener to this window as well -- hence the drawing of components translated down a bit.
The solution is to look at the tutorials first before attempting something fairly complex like this. They'll tell you how to draw correctly including the suggestions I've given in my comments, such as drawing in a JComponent or JPanel's paintComponent method and calling the super.paintComponent(g) method as the first method call of your paintComponent override.

Java JFrame / Canvas doesn't repaint

A mouse listener calls repaint() and I can see that it does actually go past the drawing part because I see globalcounter incremented in the output of System.out.println(). On the screen, however, I don't see any change until I minimize the window and maximize again, resize it, or move it out of the visible screen area and back in. Obviously I'd like it to update without my intervention.
class GUI extends javax.swing.JFrame {
int globalcounter=0;
class MyCanvas extends Canvas {
#Override
public void paint(Graphics g) {
globalcounter++;
g.drawString(globalcounter,100,100);
System.out.println(globalcounter);
}
}
}
(Originally I was loading an image from a file that got constantly updated (webcam) and painting it on the canvas. When I dragged it partly out of the visible screen area and back in, the part that has been 'outside' was refreshed, the rest not.)
revalidate() instead of repaint() didn't change anything.
I know this post is a duplicate to Java repaint not working correctly but when I posted it there it was deleted.
Why are you adding an AWT component, Canvas, to a Swing component, JFrame? You should stick with Swing components only. And also do you know the size of your MyCanvas, and how have you added it to the JFrame as you don't show this code.
Consider
using a JPanel instead of a Canvas object,
drawing in its paintComponent method,
showing us an sscce if you're still stuck.
And also, if all you're doing is drawing text, use a JLabel rather than drawing in paint/paintComponent, and change its text with its setText(...) method.

Removing a JPanel from a JFrame

I am currently working on an intro screen for a game designed using JOGL. I want the intro to be a JPanel with a few buttons to alter options before starting the game.
So, I have JFrame which I add a GLCanvas to. The GLCanvas also contains a GLEventListener. Finally, I add the JPanel.
I have overridden the JPanel paintComponent method to set a background image. I have a few buttons within the panel. Whenever you click the 'play' button, it calls a function which does:
frame.remove(JPanel);
frame.repaint();
animator.start();
What happens is that my JPanel goes away correctly, but when repaint is called, my frame is just filled with grey. I know that the animator is starting correctly as the display method in my GLEventListener is getting called.
Does anyone know what the problem is there?
What is your LayoutManager? If you didn't specify one, then by adding the JPanel you replace the GLCanvas.
I would make your code do this:
frame.remove(JPanel); frame.add(glcanvas); animator.start();
you may need to throw in a frame.revalidate(). I'm not up on how all that works right now.

Categories

Resources