Search code examples
javaswingeventsuser-interfacecomponentlistener

How can you fire ComponentListener programatically?


Is there any way we can fire a ComponentListener programatically? For an example, have a look at the below code snap.

    private class DisplayAllRevenue extends ComponentAdapter
         {
             @Override
             public void componentShown(ComponentEvent e)
             {
                }
    }

allRevenueJScrollPane.addComponentListener(new DisplayAllRevenue());

I have created a ComponentListener and attached it into a JScrollPane. Now I need to fire this manually using my own code too. How can I do it? I need to fire this code once JComboBox event has occured. That means, user selects year or something and this code is then fired... There are lot of ComponentListeners I need to fire based on this. These are all heavy database calls which will feed data into different screens, therefore, I am not gonna use the entire set of code inside ItemStateChanged


Solution

  • You state:

    I have created a ComponentListener and attached it into a JScrollPane. Now I need to fire this manually using my own code too. How can I do it? I need to fire this code once JComboBox event has occured. That means, user selects year or something and this code is then fired...

    The standard way to respond to JComboBox selection events is to use an ItemListener or perhaps an ActionListener.

    There are lot of ComponentListeners I need to fire based on this. These are all heavy database calls which will feed data into different screens, therefore, I am not gonna use the entire set of code inside ItemStateChanged

    I don't see anything in this statement above that would recommend to me to create a kludge like trying to artificially fire a ComponentListener. If you have stronger reasons for this, you'll have to tell us, otherwise the canonical answer is not to do this but rather to use the standard listeners as I mentioned above.

    Assuming that your program's structure roughly approximates an MVC design, note that your combobox selection can trigger your Control class to change the Model, and the Model change can be significant or can have significant effect on multiple components of your view, components that themselves are listening to the model's state, and I think that this is really what you want to do.


    Edit
    You state:

    The reason why I am trying to fire this manually is this. I have JTabbedPane. There are 5 tabs. In every tab, there is a table,which takes its data from the database. The SQL Queries I use to feed the data into tables are extremely heavy, some even join 5-6 tables together. That is why I can't fire the all 5 SQL Queries (for all 5 tables) at once, bcs I am afraid it will fail. If I have a component listener, they will only call the SQL code appropriate to the current displaying table. The SQL code takes parameters. Years. That is why the combobox is there.

    Of course it's your program of course, and you can structure it any way that you wish, but if it were mine, I'd gear mine towards an MVC structure mainly so I could more easily debug the constituent parts in isolation and be able to do mocking and such. Sure you could call getComponentListeners() on your Comopnent and then fire them if you desire by creating your own ComopnentEvent and then calling each listener's componentXXX(ComponentEvent cEvt) method, but I fear that this will result in hard to find bugs and difficulty in testing and upgrading your program. Which component notification method would you decide to fire? What is the program supposed to do when the JVM fires that same method appropriately?

    I wonder if you are mixing model and view together. I wonder if better would be to abstract out the model -- the business logic that underpins your whole program and work from there. The model should be notified and thus be aware of table is currently being displayed, and likewise the control will notify it of when the years change. Then the model can request an update from the database, in a background thread of course, and I believe done by the Control. This data will then be sent back to the model. The view will have listeners in the model to be notified of its change, and it will then change the display of your currently displayed table.

    If you absolutely must use a GUI-based listener, then use a PropertyChangeListener, since each GUI component has innate support for this listener, and by creating your own bound property, you will have created a listener that shouldn't collide with other GUI behaviors or states.