-1

I am trying to refresh some components of my main JPanel (eg JLabels / JTextFields, contained in sub-JPanels) but I don't seem to be able to. The components data (eg JLabels text) are populated based on an instance variable object of my JFrame class, and I want to refresh those components when this object data change :

enter image description here

I've tried using :

    jPanel.revalidate();
    jPanel.repaint();

both on the main JPanel and on each component's sub-JPanel but this didn't seem to work.. Any suggestion on how this should be done ?

[EDIT] Below's the code from where I'm trying to refresh the JPanel. This is fired up by a pop-up JDialog, after filling some fields and pushing a "save" button triggering the below actionPerformed code

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        myObject.setOwner(jTextField1.getText());
        myObject.setPurpose(jTextField2.getText());
        myObject.setProject(jTextField3.getText());
        myObject.setUntil(jTextField4.getText());
        jDialog1.dispose();
        jPanel1.revalidate();
        jPanel1.repaint();
}     
nullPointer
  • 4,419
  • 1
  • 15
  • 27
  • For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). BTW - how does that layout make any sense? It looks a dogs' breakfast, only more messy. – Andrew Thompson Jan 14 '19 at 15:59
  • The screenshot was simply to describe the hierarchy of the containers, and NOT the layout. And BTW how's the layout event relevant here ? – nullPointer Jan 14 '19 at 16:02
  • 3
    *"how's the layout event relevant here"* How is it that you missed the main advice? – Andrew Thompson Jan 14 '19 at 16:17
  • 1
    (1-) The screenshot tells us nothing. The problem is with your code that creates the hierarchy. We are NOT mind readers. We can't guess what you are doing. If you don't post the [mcve] we can't help. – camickr Jan 14 '19 at 16:17
  • A simple `setText()` should suffice. No need to refresh anything. – xehpuk Jan 14 '19 at 16:20
  • Edited to add some relevant code. As explained the initialization of the components is done via the Netbeans-generated initComponents() non-modifiable method - nothing complicated but quite long piece of code. The hierarchy is simply as per the screenshot provided – nullPointer Jan 14 '19 at 16:35
  • *"Edited to add some relevant code"* Why did you do that rather than add a [mcve]? Tip: Add @camickr (or whoever, the `@` is important) to *notify* the person of a new comment. – Andrew Thompson Jan 15 '19 at 05:09

2 Answers2

1

It seems you are assuming that there is some binding between your UI components and application data by default. Unfortunately there is no such feature by default. If you want such binding, you have to use a data binding framework.

This post discuss few such data binding frameworks: Swing data binding frameworks

If you want to do this binding yourself without using a framework, then you can use java.beans.PropertyChangeListener and related classes in Java.

Prasad Karunagoda
  • 2,048
  • 2
  • 12
  • 16
  • Hi Prasad, fair point, however the initialization of the components is using/based on these app data as explained. All I need is to somehow "re-run" the init parts only relevant to the JPanel components (eg and not the whole JFrame). Do I really need a data binding framework for that ? – nullPointer Jan 14 '19 at 16:44
  • 1
    Yes, either data binding or manually setting values in UI components. For example `JLabel` and `JTextField` components' value are `String`. So you set some `String` fields of your application object to components in `initComponents()`. Later you set another different `String` object to application object's field. How would the UI component know that you changed the field value? (`String` objects are immutable. So, when a `String` field value changes, actually one `String` object is replaced with another `String` object.) – Prasad Karunagoda Jan 14 '19 at 17:01
  • if I'm to use the PropertyChangeListener, shouldn't this be attached to my app object to "listen" for changes ? Because normally PropertyChangeListeners are used in UI components instead if I understand correctly ? – nullPointer Jan 15 '19 at 08:57
  • No, property change events will be fired from your application objects and UI components will listen to those events and update themselves. (i.e. UI components will implement `PropertyChangeListener`.) – Prasad Karunagoda Jan 15 '19 at 11:44
-2

Have you tried using jPanel.removeAll() and then re-adding the text/image/button components before you repaint and revalidate?

Or try removing your revalidate and repaint and just call removeAll, in the worst case it will show you if that code segment gets hit (assuming you don't/can't breakpoint there for some reason).

Alex
  • 80
  • 6
  • I tried adding jPanel.removeAll() right before revalidate and repaint and this leaves me with an empty jPanel, so the code segment gets hit. By "re-adding the text/image/button components" , the init code runs via initComponents() non-modifiable Netbeans part... so how could I really do this apart from duplicating all that auto-generated code? – nullPointer Jan 14 '19 at 16:10
  • 1
    `Or try removing your revalidate and repaint` - please don't guess. The "revalidate()" is necessary because it invokes the layout manager for the panel. By default components have a size of (0, 0) so there is nothing to paint. The repaint() just makes sure the panel and its children are painted after the layout manager have given compnents a size and location. – camickr Jan 14 '19 at 16:15
  • whilst I would agree that guessing is to be avoided: a) knowing perfectly well what the repaint/revalidate do, if this was a deployed app rather than locally running then you could verify that the contained functionality actually got hit (which I thought was rather clear) by actually 'doing' something. Which seems to be the issue (i.e. nothing is done). b) Based on the info given, its about as clarity inducing as is possible - work with what we have rather than what we would like. – Alex Jan 14 '19 at 17:04
  • If you want to check if the code is executed, then add a simple System.out.println(...). Don't tell the OP to remove code this IS required to make sure the layout manager is invoked. – camickr Jan 15 '19 at 15:27