The Artima Developer Community
Sponsored Link

News & Ideas Forum (Closed for new topic posts)
How Would You Redesign java.awt.Component?

5 replies on 1 page. Most recent reply: 45 minutes ago by RoseGul Andersan

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
    Next Topic
Flat View: This topic has 5 replies on 1 page
Chris Dailey

Posts: 56
Nickname: mouse
Registered: Dec, 2002

How Would You Redesign java.awt.Component? Posted: Aug 13, 2003 4:30 AM
Reply to this message Reply
Advertisement
I recently took a look at the javadoc for java.awt.Component, and I was rather amazed at its size. It is incredible. I cannot see how it can be proven correct no matter how many unit tests one would write for it. Its cohesion cannot be very good! I tried to make a list of the public non-deprecated methods, and I identified at least 14 different concepts and responsibilities that it deals with (see Appendix A below).

There are a number of heuristics that I think it violates (I happened to choose this subset from Arthur J. Riel's Object Oriented Design Heuristics, but I'm sure most books on OO would have similar rules of thumb):

A class should capture one and only one key abstraction.
Minimize the number of classes with which another class collaborates.
Minimize the amount of collaboration between a class and its collaborator.
Minimize fanout in a class.
Most of the methods defined on a class should be using most of the data members most of the time.
Classes should not contain more objects than a developer can fit in his or her short-term memory.
A class must know what it contains, but it should never know who contains it.

How would you address these criticisms? How should java.awt.Component have been designed? Would redesigning to meet these "good" attributes create too poor performance? Is there a GUI toolkit that meets these attributes? And would an API meeting these attributes still be easy to use?

I was thinking that the Artima community minds would be the best ones to ask. What do you think? (Extra points for UML diagrams.)


Appendix A. java.awt.Component responsibilities

1. manage hierarchy
add(PopupMenu)
addHierarchyBoundsListener(HierarchyBoundsListener)
ad dNotify()
getComponentAt(int, int)
getComponentAt(Point)
getHierarchyBoundsListeners()
getHierarchyListeners( )
getParent()
getTreeLock()
processHierarchyBoundsEvent(HierarchyBoundsEvent)
pr ocessHierarchyEvent(HierarchyEvent)
remove(MenuComponent)
removeHierarchyBoundsL istener(HierarchyBoundsListener)
removeHierarchyListener(HierarchyListener)
remo veNotify()

2. paint
getIgnoreRepaint()
paint(Graphics)
paintAll(Graphics)
print(Graphics)
pri ntAll(Graphics)
repaint()
repaint(int, int, int, int)
repaint(long)
repaint(long, int, int, int, int)
setIgnoreRepaint(boolean)
update(Graphics)

3. input : key + mouse events
addInputMethodListener(InputMethodListener)
addKeyListener(KeyListener)
addMouseListener(MouseListener)
addMouseMotionListener(MouseMotionListener)
addM ouseWheelListener(MouseWheelListener)
enableInputMethods(boolean)
getInputContex t()
getInputMethodListeners()
getKeyListeners()
getMouseListeners()
getMouseMoti onListeners()
getMouseWheelListeners()
processInputMethodEvent(InputMethodEvent)
processKeyEvent(KeyEvent)
processMouseEvent(MouseEvent)
processMouseMotionEvent (MouseEvent)
processMouseWheelEvent(MouseWheelEvent)
removeInputMethodLIstener(I nputMethodListener)
removeKeyListener(KeyListener)
removeMouseListener(MouseList ener)
removeMouseMotionListener(MouseMotionListener)
removeMouseWheelListener(Mo useWheelListener)

4. focus, traversal
addFocusListener(FocusListener)
areFocusTraversalKeysSet(int)
getFocu sCycleRootAncestor()
getFocusListeners()
getFocusTraversalKeys(int)
getFocusTrav ersalKeysEnabled()
hasFocus()
isFocusable()
isFocusCycleRoot(Container)
isFocusO wner()
processFocusEvent(FocusEvent)
removeFocusListener(FocusListener)
requestF ocus()
requestFocus(boolean)
requestFocusInWindow()
requestFocusInWindow(boolean )
setFocusable(boolean)
setFocusTraversalKeys(int, Set)
setFocusTraversalKeysEnabled(boolean)
transferFocus()
transferFocusBackwar d()
transferFocusUpCycle()

5. image
checkImage(Image, ImageObserver)
checkImage(Image, int, int, ImageObserver)
createImage(ImageProducer)
createImage(int, int)
createVolatileImage(int, int)
createVolatileImage(int, int, ImageCapabilities)
imageUpdate(Image, int, int, int, int, int)
prepareImage(Image, ImageObserver)
prepareImage(Image, int, int, ImageObserver)

6. layout
applyComponentOrientation(ComponentOrientation)
doLayout()
getAlignmentX ()
getAlignmentY()
invalidate()
isValid()
setComponentOrientation(ComponentOrien tation)
validate()

7. background/foreground
getBackground()
getForeground()
isBackgroundSet()
isForeg roundSet()
setBackground(Color)
setForeground(Color)

8. component
addPropertyChangeListener(PropertyChangeListener)
addPropertyChangeLi stener(String, PropertyChangeListener)
firePropertyChange(String, boolean, boolean)
firePropertyChange(String, int, int)
firePropertyChange(String, Object, Object)
getListeners()
getName()
getPropertyChangeListeners()
getPropertyChange Listener(String)
removePropertyChangeListener(PropertyChangeListener)
removeProp ertyChangeListener(String, PropertyChangeListener)
setName()

9. generic event handling
coalesceEvents(AWTEvent, AWTEvent)
disableEvents(long)
enableEvents(long)
dispatchEvent(AWTEvent)
proces sEvent(AWTEvent)

10. position / size
contains(int, int)
contains(Point)
getBounds()
getBounds(Rectangle)
getHeight()
getLocation()
getLocation(Point)
getLocationOnScreen()
getMaximumSize()
getMinimumSize()
getP referredSize()
getSize()
getSize(Dimension)
getWidth()
getX()
getY()
addComponen tListener(ComponentListener)
getComponentListeners()
isShowing()
processComponen tEvent(ComponentEvent)
removeComponentListener(ComponentListener)
setBounds(int, int, int, int)
setBounds(Rectangle)
setLocation(int, int)
setLocation(Point)
setSize(Dimension)
setSize(int, int)

11. cursor
getCursor()
isCursorSet()
setCursor(Cursor)

12. Enabled
isEnabled()
setEnabled(boolean)

13. Font
getFont()
getFontMetrics(Font)
isFontSet()
setFont(Font)

14. debug
list()
list(PrintStream)
list(PrintStream, int)
paramString()
toString()

15. other
getAccessibleContext()
getColorModel()
getComponentOrientation()
getDropT arget()
getGraphics()
getGraphicsConfiguration()
getLocale()
getToolkit()
isDisp layable()
isDoubleBuffered()
isLightweight()
isOpaque()
isVisible()
setDropTarge t(DropTarget)
setLocale(Locale)
setVisible(boolean)


Bruce Chapman

Posts: 8
Nickname: chappy
Registered: Mar, 2003

Re: How Would You Redesign java.awt.Component? Posted: Aug 19, 2003 10:15 PM
Reply to this message Reply
I'm just shooting from the hip here, but I reckon you have already started step 1, which is to identify the different concerns.

After that was refined, I might look at defining an interface for each of these concerns.

After that I might create a private inner class for each concern (implementing the interface).

In the end I might move every method to an inner class and just have a few methods that gave me a "view" of the Component as a Paintable, or as a HeirarchyMember or whatever.

It wouldn't change much under the hood, but the API documentation would sure be simpler.

Jan Ploski

Posts: 8
Nickname: jploski
Registered: Aug, 2003

Re: How Would You Redesign java.awt.Component? Posted: Aug 20, 2003 12:49 PM
Reply to this message Reply
I also feel that segregating interfaces is a key step to improving a design.

You have split the Component's interface topically. Another interesting aspect to consider would be which methods in those interfaces tend to be used together (maybe some statistics from existing source code that uses Component would help there).

While creating all those helper (inner or package level) classes implementing each subinterface, it would be quite interesting to have a look at dependencies between the interfaces and between the underlying implementations. I am pretty sure you could isolate independent pieces, not just by topical cohesion, but also by looking at the references in code.

Using interfaces instead of concrete classes opens new ways for testing GUI-dependent code using the "mock objects approach". I believe that the heavy dependence on concrete classes in GUI toolkits (AWT/Swing/SWT - no difference) is one major reason why the client code is so difficult to test automatically.

As far as the performance impact is concerned, you cannot tell much about it without designing some sort of benchmarks up-front that would allow to objectively compare the "before" and "after" states.

George A Smith

Posts: 4
Nickname: zgas
Registered: Sep, 2003

Re: How Would You Redesign java.awt.Component? Posted: Sep 26, 2003 4:35 PM
Reply to this message Reply
I would wonder if the "slicing" should be around the "types" of the Component. When looking at all the methods, it is clear that they don't all apply to all Components. I was thinking of the following Components:

JPanel (or any Container),
Label,
TextField, &
Button.

While they all probably need to support repaint or invalidate, and position sizing, they all don't need to "expose" the fact that they have children or that the children need to be layed out. And what does foreground color mean (or Focus) to a Container?

A "simple" first attempt might be to make Component ONLY support painting (with size & positioning) and Mouse support; and then see what is missing.

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: How Would You Redesign java.awt.Component? Posted: Dec 19, 2005 11:46 AM
Reply to this message Reply
GUIs are very complex beasts, so almost every GUI lib has a monster class that provides almost all of the functionality. Qt has the monster Widget class, MFC has the CWnd monster class, Swing has the Component class.

RoseGul Andersan

Posts: 1
Nickname: endrio
Registered: Dec, 2014

Re: How Would You Redesign java.awt.Component? Posted: Dec 19, 2014 2:14 AM
Reply to this message Reply
It seems like Sun's philosophy towards interoperability is that you can call any API you like so long as it's over the network. Java is a first-class ciziten when it comes to API's such C2010-590 exam - testking.net as SOAP, RMI, CORBA, HTTP, X11, and so on. But try to call the same functionality via a DLL or a command-line tool and they'll make you jump through hoops.

Flat View: This topic has 5 replies on 1 page
    Next Topic Topic: The Trouble with Checked Exceptions


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us