I have following code:
canvas=new MembershipFunctionComponent(functions);
canvas.setPreferredSize(new Dimension((int)this.getWidth(), (int)this.getHeight()));
canvas.addMouseListener(canvas);
pane.add(canvas);
MembsershipFunctionComponent extends JComponent. Why is paintComponent method executed 2 times?
paintComponent can get called at pretty much any time by the Swing framework. Examples of when this might happen:
Any time a component is resized
Any time part of the component is revealed (for example in a scrollable window)
Any time the repaint() method is called on your component (or possibly a parent or sub-component)
Any time there is a layout change
None of this should worry you - you should just write your code so that it doesn't care how many times paintComponent is called.
Related
Is the setBounds() method of a Component like JPanel called on the Event Dispatch Thread? I am asking this because I am writing a program that draws platforms and uses a Swing Timer to move them up. I override the setBounds() method so that every time the JPanel is resized, the platforms will resize too. I just want to make sure that setBounds() doesn't resize the platforms while the Timer is moving them. Also, would it be better to use a WindowListener to check if the JPanel was resized?
setBounds() will be called on the EDT by Swing code, but you have to ensure your code's own invocations of setBounds() also only calls it on the EDT. If you can ensure all calls of setBounds() occur on the EDT, then you shouldn't have to worry about setBounds() being executed while your SwingTimer is being executed because SwingTimers also execute on the EDT by default (so they won't execute at the same time).
Also I never seen someone override setBounds() so I do wonder if there's not an alternative solution such as just querying the bounds every time your SwingTimer executes. Using a listener listening for window resizes like you say does sound much better.
I am a novice Java programmer and I'm finding quite some difficulty in figuring out the actual difference between the functioning of the paint() and repaint() method.
Also in some of the programs that I studied I found paint() and repaint() interchangeable.
Can someone please explain the difference? Thank you
Assuming that you are referring to the void paint(Graphics g) method that is declared in the Component class:
This paint method is called automatically, whenever it is necessary to paint (parts of) the component. For example, when the window was obstructed by another window and then becomes visible again: The window manager will determine this, and call paint on the top level component (e.g. a Frame) and this call will make its way down to the actual "bottom" components (e.g. a Button). The Graphics object that is passed to this method is provided by the Window manager, and corresponds to the area on the screen where the component should be painted. (And this Graphics object is only valid during the paint method).
In contrast to that, repaint() just triggers a new painting process. It is telling the system: "Please call paint on this component as soon as possible". You can call this method manually. And you can call it freuqently: The calls to repaint are coalesced. That means that when you issue many calls to repaint in a short period of time, then these calls may be summarized and may eventually only trigger one call to paint.
The paint method should not be called directly as the javadoc states:
Invoked by Swing to draw components. Applications should not invoke
paint directly, but should instead use the repaint method to schedule
the component for redrawing.
The repaint method should be used instead if you want the component to be repainted (redrawn). The javadoc also refers to the following documentation: Painting in AWT and Swing
paint() get called automatically at runtime. If you want to call paint() manually(again) then repaint() is used.
The paint() method contains instructions for painting the specific component.
The repaint() method, which can't be overridden, is more specific: it controls the update() to paint() process. You should call this method if you want a component to repaint itself or to change its look (but not the size).
I create a little program that load a frame in which I added some panels.
When I click on some button it should show some panels and hide other.
I'm experiencing some difficult to do it, even because I don't really figure out the diference between setVisible(true), repaint() and validate() (that some friends of mine suggested to me).
I hope you can make me to understand!
Thank you.
Carefully read the API for JComponent. The usages are:
setVisible - it will hide or show your component altogether. If you set it as false, you won't see it at all.
repaint() - is called when the actual pixels need to be redrawn, this is done automatically. It's used, for example, when you move a window on top of your GUI and then move it away. The part that was covered needs to be redrawn.
validate() - you should call this when the layout of your GUI has changed and you need the manager to replace and redraw your GUI.
It's a bit more complicated than that, so again, carefully read the API.
setVisible(true): sets the component so that it's visible.
repaint(): calls the paint method on the component.
revalidate(): updates the component based on the root component
just working on some code to do with java graphics, very simple example from a lecture I had today. Anyway, the internet seems to say that update will not be called by a System trigger such as resizing a frame etc. In this example, update is called by such a trigger (hence update and paint are called when I only expect paint to be called). He seemed to put it down to Operating Systems and different results on each.
Can anyone clarify this for me?
Working on windows 7
Thanks in advance
Ben
Here's a great article that really says it all:
http://java.sun.com/products/jfc/tsc/articles/painting/
1) Painting in AWT
To understand how AWT's painting API works, helps to know what
triggers a paint operation in a windowing environment. In AWT, there
are two kinds of painting operations: system-triggered painting, and
application-triggered painting.
2) System-triggered Painting
In a system-triggered painting operation, the system requests a
component to render its contents, usually for one of the following
reasons:
The component is first made visible on the screen.
The component is resized.
The component has damage that needs to be repaired. (For example, something that previously obscured the component has moved, and a
previously obscured portion of the component has become exposed).
3) App-triggered Painting
In an application-triggered painting operation, the component decides
it needs to update its contents because its internal state has
changed. (For example,. a button detects that a mouse button has been
pressed and determines that it needs to paint a "depressed" button
visual).
4) The Paint Method
Regardless of how a paint request is triggered, the AWT uses a
"callback" mechanism for painting, and this mechanism is the same for
both heavyweight and lightweight components. This means that a program
should place the component's rendering code inside a particular
overridden method, and the toolkit will invoke this method when it's
time to paint.
How to use paint() such that when repaint() is called the previously drawn object should not get deleted when drawing the new object. That is the drawing area must get UPDATED only and not REDRAWN.
In my code when one of many button is clicked, some aplhabet get displayed. I want to have functionality such that when other buttons are clicked the previously drawn alhabets must be present.Take is as if a string of alphabets getting created as the buttons are clicked.
Im using Java Swing for coding.
Some piece of my code:
if(source == btnAlpha[i] )
bollyDraw.repaint(); //bollydraw is an object of a JPanel extended class having implemented the paintComponent(Graphics g) method
In the paint() method:
if (word[i] == key) {
g.drawChars(word, i, 1, x, y);
}
In a project I worked on I used a List to store the objects that were to be drawn as a member of a class. Then as the user interacted with my UI I added/removed items from this list. The JPanel that rendered the items painted the items that were in this list. It's helps separate the UI logic from the paint logic as you can determine what goes into the paint list when an event is fired rather than in the paint method ( which should be as clean as possible ). However this will force you to repaint everything on every paint call.
In conjunction with this Kim's RepaintManager is a great way to limit what gets repainted. It is region based so there is some complexity in determining what region of the screen has changed. If you have the time it is better to use something like this otherwise it could be difficult to add this functionality down the road.
Your app must be prepared to re-paint anything it has painted. From your description, I'm afraid that means you have to keep track of everything you've painted.
The Swing behavior is partially dictated by the underlying window manager and graphical system, which at any time may chose to paint over an area where your application is present. You can override update() to control repaints initiated by your own app, and might be able to improve performance by implementing your own RepaintManager.
This tutorial explains Swing painting in more detail: http://java.sun.com/products/jfc/tsc/articles/painting/
Custom Painting Approaches shows a couple of ways to do this depending on your exact requirement.