2

I'm new in Java Swing and I have a strange problem to refresh my JPanel.

I create a static JPanel componant in my frame and I call a static method from a FileListenner to repaint my JPanel

 public static void repaintPlan(JPanel f) {
    f.paint(f.getGraphics()); 
    f.revalidate(); // or validate
}

I mean, when I detect change in file content, I calculate the new coordinates and I repaint the JPanel (I create a class exends from JPanel to definepaintComponent()` method)

Everything is working fine when I run the app, and the repaint works when a change data in file; but if I click with my mouse in the Jpanel, the repaint() method doesn't work anymore. Can you tell me why after clicking on JPanel, repainting doesn't work ?

Sorry for my bad english Thanks in advance:)

Edit: Thanks for your repsonses! But even if I use repaint() method, it's the same problem. I'm trying to understand what happens when I click on JPanel. Should I use mouse events in Swing to solve the problem?

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Anass
  • 6,132
  • 6
  • 27
  • 35
  • 4
    don't feel shy about your English friend :-) – Mayank Pandya Apr 28 '12 at 13:21
  • 1
    You will want to avoid using static fields and methods here. If it doesn't hamper your program now, it will later. Please do yourself a favor and use instance fields at all times except in rare specific circumstances. Also, you will almost never want to call paint directly. – Hovercraft Full Of Eels Apr 28 '12 at 13:23
  • 2
    You said you calling `repaint()` but looking at the code snippet provided by you, you calling `paint()` that too explicitly, `paint()` calls belong to the Swing, so let Swing call it at the appropriate time, never call yourself such delicate methods :-) , Call `repaint()` better yet, call `repaint(x, y, width, height);` – nIcE cOw Apr 28 '12 at 13:36
  • When i call repaint(), it works after once ! After a second change in my file, the JPanel is not refreshed, that's why i used paint() which work all the time ! – Anass Apr 28 '12 at 14:10
  • I think the problem concerns the mouse event, and i don't know how to disable it ! – Anass Apr 28 '12 at 14:11
  • 2
    Anass: We may need to know more about your problem and see more of your code to help you solve the overall problem. Best if you can whittle your code down to the barest essential to demonstrate your problem, code that is complete enough to compile and run but small enough to not drown us in irrelevant detail, an [sscce](http://sscce.org). Failing that, post your program on [Pastebin](http://pastebin.com). – Hovercraft Full Of Eels Apr 28 '12 at 14:20

4 Answers4

7

1) for Swing JComponents is there method paintComponent(), method paint() is for Top-Level Containers (JFrame, JDialog ...) and for AWT Components

2) don't use getGraphics() this method created snapshot that after calling validate, revalidate, repaint expired

3) you have look at tutorial about 2D Graphics, examples here

4) in the case that you'll have real question, please edit your question with SSCCE

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • @nIcE cOw but true is most of them use paint(), instead of paintComponent() – mKorbel Apr 28 '12 at 13:39
  • I just found out, that in certain situations one has to use `paint()` over `paintComponent()`, but it's like 1 out of 20 , under which such situations may arise. Though most of the work is indeed done by `paintComponent()` – nIcE cOw Apr 28 '12 at 13:42
  • @nIcEcOw You code AWT? If not, I've never found a justifiable reason to override `paint(Graphics)` in Swing. – Andrew Thompson Apr 28 '12 at 13:45
  • 1
    @Andrew: Have you had a chance to check out [Filthy Rich Clients](http://filthyrichclients.org/)? If not, you owe it to yourself to do so, and in fact early in the book it will give a great example of where paint comes in handy in their example of creating a translucent JButton. They will also explain other situations where it is very useful to override this method for Swing JComponents. 1+ to mKorbel (again), by the way. – Hovercraft Full Of Eels Apr 28 '12 at 13:53
  • 1
    @AndrewThompson : Though I don't know the detail, still have to read that part, I read that much "paint() is used, when you want to render a Swing Component to an image instead of to its usual place in the Swing window". Now exactly what is this stuff is way back, in the book, so cann't say much :-) . LITTLE KNOWLEDGE IS ALWAYS DANGEROUS (I do know this thingy), so will wait to answer on this , till I reach that part in that book :-) Exactly what HCFE, said, that book is what i am reading :-) – nIcE cOw Apr 28 '12 at 13:55
  • 1
    @Hov No. And you're right, I really should read it. In the meantime I'll 'soften' my statement to "in 99(.9)% of cases with Swing, `paint()` is the wrong method". – Andrew Thompson Apr 28 '12 at 14:00
  • @AndrewThompson : Just a small indication, some people do have some different tastes, when it comes to Swing, like the OP in this [Thread](http://stackoverflow.com/questions/10338163/paintcomponent-does-not-work-if-its-called-by-the-recursive-function), wants to `Paint` inside his `for Loop` and he/she wants to see all the dots too, during iteration. So instead of `repaint()` , I used `paintImmediately(...)` – nIcE cOw Apr 28 '12 at 14:33
  • continued... : , so here since repaint() won't work, since repaint() requests get combined, so any new will be discarded for the old one in queue, one has to change to other area. Similarly I guess paint() will be useful too, likewise in some areas :-) – nIcE cOw Apr 28 '12 at 14:33
  • @Andrew Thompson (I can't resist :-) "in 99(.9)% of cases with Swing, paint() is the wrong method" --> BasicXxxUI is based on paint(), I think that there is created bridge betweens lightweight JComponent and their bases from/on heavyweight AWT Components and its methods :-) – mKorbel Apr 28 '12 at 16:33
  • @mKorbel I give in. I retract everything. ***..Everything.*** – Andrew Thompson Apr 28 '12 at 16:36
4

I'm trying to understand what happens when I click on JPanel. Should I use mouse events in Swing to solve the problem?

You might get some insight from this example that responds to mouse pressed events. In this case, paintComponent() is called automatically when the color is updated. See also Painting in AWT and Swing.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Are you sure that paintcomponent() is called after a mouse pressed event ? how can i disable it ? – Anass Apr 28 '12 at 14:15
  • That is interesting for me, that `repaint()` is called automatically under this situation of setting the background. Will NOTE it down :-) – nIcE cOw Apr 28 '12 at 14:21
  • 2
    @Anass: You shouldn't disable `paintComponent(...)`, but the logic in the method can change its behavior depending on your object's state. – Hovercraft Full Of Eels Apr 28 '12 at 14:21
  • @nIcEcOw: `JComponent` overrides `setForeground()` to call `repaint()` which calls `paintComponent()`. – trashgod Apr 28 '12 at 14:28
  • @Anass we an help you in the case that you post here concrete question, but too hard we can suply lessons from 2D Graphics tutorial – mKorbel Apr 28 '12 at 16:12
  • @nIcE cOw I miss there info very important for you paint / paintcomponent() is done automatically, when J/Component required repaint itself (-: some implementations in the APIs :-), – mKorbel Apr 28 '12 at 16:24
  • @trashgod excelent link, previously +1 – mKorbel Apr 28 '12 at 16:26
3

No, paintComponent is not called after a mouse press, not unless you've got some code that makes it do this. For example:

import java.awt.*;
import javax.swing.*;

public class MyPanel extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = 400;

   public MyPanel() {
      setBorder(BorderFactory.createTitledBorder("My Panel"));
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);

      System.out.println("myPanel's paintComponent method has been called");
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      MyPanel mainPanel = new MyPanel();

      JFrame frame = new JFrame("MyPanel");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

As you can plainly see, in a plain JPanel, paintComponent is not called after any mouse action unless you change the size of the GUI.

Something else is wrong with your GUI, and also, it shouldn't matter if paintComponent is called once or several times since your program logic should not depend on whether or not this method gets called.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • agreed, hmmm shot to the dark, only resize of container (its childs) required MouseEvent, why bothering with that, ComponentListener for AbsoluteLayout :-) ???? +1 – mKorbel Apr 28 '12 at 22:00
0

I resolve my problem by overriding mouse event methods of my JPanel like this

 myJPanel.addMouseListener(new MouseListener() {

        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        public void mouseClicked(MouseEvent e) {
            // TODO Auto-generated method stub

        }
    });

thanks

Anass
  • 6,132
  • 6
  • 27
  • 35
  • Hm, you really shouldn't have to do this unless for some reason a MouseListener had already been added to your JPanel. This is strange indeed. – Hovercraft Full Of Eels Apr 28 '12 at 18:26
  • Also consider `MouseAdapter`, shown [here](http://stackoverflow.com/a/3538279/230513). – trashgod Apr 28 '12 at 18:29
  • paintcomponent() is called after a mouse pressed event, that why i override these methods – Anass Apr 28 '12 at 20:23
  • @Anass: no as a matter of course, `paintComponent(...)` is not called on a standard JPanel with mousepress. Please see my answer that proves this statement. Something else is wrong with your program and you've created a kludge to fix it. – Hovercraft Full Of Eels Apr 28 '12 at 21:26