swing Aktuell Seminare Reports Homepage Software
printer / text mode version
university-logo
draheim
@informatik.hu-berlin.de

Reports
- postindustr.CC
- XML/Ti Report
- pTA StudienArbeit  .
- sch_llf study
- Geschichte des PC

TechDocs
- Perl Objects
- Installing Oracle
- shell cmds in python
- Using css for xml
    defs   tricks
- Unsafe mono  [x]  !
- Docbook Manpages
- Java Bean   Code
rpm-suse
 
- schema-mappingen
  ig cv hg re dv ev
  zz mk pr
- java problemsen
  lang swing ext gtk jjtree xul
 
boot
-grub-netboot
-grub-gtk
-partclone freshmeat
-partimage links
 
-releaseuploader


sitemap


-guidod-pygtk
sitemap             *offsite link

2004-04-28
(C) Guido Draheim
guidod@gmx.de

 
generated by mksite.sh

java swing problems

callback lists for signal handles

The java/swing gui system does somewhat suffer from the language problems themselves. The signal/slot mechanism is generally implemented as callbacks over lists with anonymous class objects. That looks something like this:

  interface EntryListener {
     public void entryEvent(EntryEvent e); }
  class MyObject {
              /** Listeners for handling Editable events */
        private Vector entryListeners = null;

        /**
         * Register an object to handle spin events.
         * @see EntryListener
         */
        public void addListener(EntryListener listener) {
                // Don't add the listener a second time if it is in the Vector.
                int i = findListener(entryListeners, listener);
                if (i == -1) {
                        if (null == entryListeners)
                                entryListeners = new Vector();
                        entryListeners.addElement(listener);
                }
        }
        /**
         * Removes a listener
         * @see #addListener(EntryListener)
         */
        public void removeListener(EntryListener listener) {
                int i = findListener(entryListeners, listener);
                if (i > -1)
                        entryListeners.remove(i);
                if (0 == entryListeners.size())
                        entryListeners = null;
        }

        protected void fireEntryEvent(EntryEvent event) {
                if (null == entryListeners)
                        return;
                int size = entryListeners.size();
                int i = 0;
                while (i < size) {
                        EntryListener el = (EntryListener)entryListeners.element
At(i);
                        el.entryEvent(event);
                        i++;
                }
        }

The problem here is that events are never stored or qeued! Actually, all the signals are really callbacks that will nest deeply and whenever there is a complex functionality (time-consuming) bound to the end of a callback object then you might see the GUI widgets hang for a while. That's because the GUI widgets can not run themselves and especially not react to user events such as mouse clicks or keypress events.

The worker thread solution

The latter is the reason why java GUI systems do generally feel very slow. Luckily however (most of) the GUI element calls are properly synchronized - so you can put the real functionality into a seperate thread. The (user) gui thread can trigger a widget update but the (app) worker thread can do it as well and independently. Of course, the "synchronize" protocol consumes itself some time and machine power and limits the speed of any java gui.

Anyway, you will find an fly-by worker-thread in the combo-box description since it is largely not nice to have the dropdown list still open going to react to a "changed" signal and updating the other widgets which are possibly covered by the dropdown list. That looks something like this:

    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource() == _DateComboBox) {
            final int record = _DateComboBox.getSelectedRecord();
            final ThisClassView our = this;
            if (_SelectThread != null) _SelectThread.interrupt();
            _SelectThread = new Thread() {
                    ThisClassView _our = our;
                    int _record = record;
                    public void run() { try {
                        _our.showView("... loading "+_record+" ...");
                        // _URL = new ThisClassPage(record); 
                        _our.setBlock(_our._URL.getThisBlock(_record)); 
                    } catch(java.net.MalformedURLException e) {
                        System.err.println("select error:"+e);
                        _our.showView("sorry, Bad URL Exception");
                    } catch (java.io.IOException e) {
                        System.err.println("select error:"+e);
                        _our.showView("sorry, IO Exception");
                    }}};
            _SelectThread.start();
            }}
In that script, all "actionPerformed" slots are called, the dropdown-list is closed, and the other threads get a "yield" to actual load new data and display it on the view widgets. And just in that order.