I'm refreshing my knowledge of Java by looking through some of the java tutorials. On this page I saw the addHierarchyListener and removeHierarchyListener method.
I've searched the API and google and this website. All I got was this:
Adds or removes the specified hierarchy listener to receive hierarchy changed events from this component when the hierarchy to which this container belongs changes. If listener l is null, no exception is thrown and no action is performed.
~Java Tutorial
And the API notes the listener:
The listener interface for receiving hierarchy changed events. The class that is interested in processing a hierarchy changed event should implement this interface. The listener object created from that class is then registered with a Component using the Component's addHierarchyListener method. When the hierarchy to which the Component belongs changes, the hierarchyChanged method in the listener object is invoked, and the HierarchyEvent is passed to it.
Hierarchy events are provided for notification purposes ONLY; The AWT will automatically handle changes to the hierarchy internally so that GUI layout, displayability, and visibility work properly regardless of whether a program registers a HierarchyListener or not.
~JavaAPI#HierarchyEventListener
And Later On the events:
Hierarchy events are provided for notification purposes ONLY. The AWT will automatically handle changes to the hierarchy internally so that GUI layout and displayability works properly regardless of whether a program is receiving these events or not.
This event is generated by a Container object (such as a Panel) when the Container is added, removed, moved, or resized, and passed down the hierarchy. It is also generated by a Component object when that object's addNotify, removeNotify, show, or hide method is called. The ANCESTOR_MOVED and ANCESTOR_RESIZED events are dispatched to every HierarchyBoundsListener or HierarchyBoundsAdapter object which registered to receive such events using the Component's addHierarchyBoundsListener method. (HierarchyBoundsAdapter objects implement the HierarchyBoundsListener interface.) The HIERARCHY_CHANGED events are dispatched to every HierarchyListener object which registered to receive such events using the Component's addHierarchyListener method. Each such listener object gets this HierarchyEvent when the event occurs.
~JavaAPI#HierarchyEvent
My understanding of hierarchy outside of Java is that they specify when one thing is above another etc. Like Maslow's Hierarchy of needs (some needs are above others in importance). So I know what the word means, but what does it mean for a component to belong to a hierarchy? Is it 'owned' by another component, or is one the parent?
THe only event out of added, removed, moved, or resized I can envisionage happening at runtime is the resizing event...but when would this matter?
Would an example be of a JFrame being resized, and then via a HierarchyEvent telling a JPanel to change the layout to fit the new size?
Could someone help explain them?
Related
I want to implement a MultipleSelectionModel ComboBox for Open Java FX 8, which would include all of the functionalities of the ControlFX CheckComboBox (as seen in this post) plus other supplementary functions that are out of the scope of this question.
My issue is that I have been reading through the JavaFX source for hours now and I have yet to find in which method 1. the ComboBox creates the list of element to print (using ListView and other JFX UI elements) and 2. the ComboBox receives the event to show the list and shows it.
Could you help me find these methods?
I have read through the following classes:
javafx.scene.control.ComboBox,
javafx.scene.control.ComboBoxBase,
com.sun.javafx.scene.control.skin.ComboBoxBaseSkin,
com.sun.javafx.scene.control.behavior.ComboBoxBaseBehavior,
javafx.scene.control.Cell
and some other unrelated classes like the MultipleSelectionModel.
I plan to extend ComboBoxBase to make my MultipleComboBox. I have yet to be able to determine if ComboBoxBase can support MultipleSelectionModel.
The standard location for sources is here.
I don't understand the first question: "the ComboBox creates the list elements to print". What does this mean?
For 2: ComboBoxBaseSkin registers a listener with the comboBox's showingProperty() (this is done in the constructor). The handleControlPropertyChanged(...) method invokes show() or hide() when the property changes. These are abstract methods, implemented in the subclass ComboBoxPopupControl; the implementation of show() in that class basically just calls show(...) on the PopupControl that holds the list view. The content of the popup (i.e. the list view) is created in the subclass ComboBoxListViewSkin.
The actual trigger to show the popup is managed by calling the ComboBox's show() method, which causes the isShowing property to be set to true, triggering the listener described above. This is done from the ComboBoxBaseBehavior method.
When it comes to events, I definitely come from an ActionScript background. I am currently working on a project using Swing in which I need to dispatch an event from one object and capture the event in the parent, and I have no idea how to do it.
In ActionScript3, you can dispatch an event with a dispatchEvent call. For example, let's say I wanted to programmatically dispatch a mouseClick event (even though the mouse was not clicked) so that some other listener will activate. I can do that by using
dispatchEvent(MouseEvent.Click);
Once that gets called, the event will bubble up through it's parent objects until it hits the top, and event listeners can capture it on the way. (Technically it bubbles down and back up, but that's outside the scope of the question, I believe). So if I want to listen for that mouseClick event in the parent object, I would just add a listener like so:
parent.addEventListener(MouseEvent.Click, Function);
Which would capture that mouseClick and perform the Function.
That's how it works in ActionScript3. I'm trying to do something similar in Java, and there appears to be some big theory changes in how Java events work. How would I do the same thing in java? Specifically, how to I programmatically dispatch an event and capture that event in a parent object?
I have done my own research on the subject, and it has merely confused me further. I have looked at:
How do I programatically send ActionEvent to JButton?
Concurrency in Swing - The Event Dispatch Thread.
Events and listeners - How do you create a custom event?
For firing events programmatically, look at AbstractButton.doClick() if you are outside the button, or preferably AbstractButton.fireActionPerformed() in a subclass.
When developing components, the lack of bubbling means that each parent component needs to handle and redispatch child component events:
innerButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent buttonEvent) {
MyEvent myEvent = ... // process buttonEvent
fireMyEventHappened(myEvent);
}
});
The Component class has a dispatchEvent(...) method, so you can create and dispatch an event to any component directly.
Or if you want to generate an OS event manually then you can use the Robot class and Java will do the dispatching of the event for you. In this case
I have an alternative tree implementation because Treeview did not do what I needed it to do. It works great except for one thing: event handling.
The tree consists of logical nested objects and each object is represented using a multitude of hbox, vbox, labels, etc.
When you use the tree, you want to register your event handlers on the root of the tree and intercept all the events, this works however there is not enough context information.
You might get a mouse click event from a certain instanced Label but no way of checking which item in the tree it corresponds to. When building the tree the containers for each object can intercept the events and "enhance" them to provide new context information but I'm not sure how to do this.
The copyFor() is useless as it is overriden again when you fire the event. So how can I take generic events like MouseEvent.ANY and KeyEvent.ANY and add a minimum amount of context? Am I forced to create my own events?
UPDATE
For example if we have the tree:
A
B
C
In GUI elements it could look like this:
VBox(A)
HBox(A)
Icon(A)
Label(A)
VBox(B)
HBox(B)
Icon(B)
Label(B)
VBox(C)
...
All event handler can be registered on the root VBox of A here. However suppose someone clicked on the Label(B) element, the root listener would only see that the original element is a Label. However as the listener, you want to know that it's linked to B.
IMO you can utilize the Node.setUserData() method of the label/container/treeitem/tree for keeping its related context data. Then use it first by getting the source and target nodes of desired event. Otherwise, you may have to create your own events.
When we implement Listener, Renderer or Editor, inside methods how Java its calling automatically?
Code:
Class A implements ActionListener{
A(){
//bla bla
//bla bla
this.addActionListener(btn);
}
public void actionPerformed(ActionEvent e){**// How actionPerformed method called //automatically if we register button**
}
}
How its calling actionPerformed method automatically after registering button object? We are just passing the btn object into addActionListener(btn). How inside its calling that method?
I checked through netbeans inside addActionListener method*. There is no calling method of actionPerformed method. Also if we register it keeps on working. Is it calling by thread anywhere inside? But i checked source code. nothing is there. How?
Events are dispatched from an EventListenerList, owned by the parent JComponent, using a convention outlined in the API and discussed here. Editors and Renderers are evoked by the owning view component.
Addendum: Can we create interface same as it is? How?
Yes, JFreeChart is a fairly accessible example. Although a chart is not itself a JComponent, it uses the same model for its own events.
In Java, anything which happens upon any windows component is dealt with by the Event Dispatcher Thread:
The event dispatching thread (EDT) is a background thread used in Java
to process events from the Abstract Window Toolkit (AWT) graphical
user interface event queue. These events are primarily update events
that cause user interface components to redraw themselves, or input
events from input devices such as the mouse or keyboard.
Whenever you click or do some event, it is the EDT which kick starts the action listener, which is why doing any Thread.sleep in your action listener will eventually freeze the UI for a period of time.
Since your class implements a given interface, your class will guarantee the EDT that it will have a series of methods which the EDT can use to do whatever it needs.
For more information on the EDT, please take a look at this Oracle document.
It's magic.
Event handling is taken care of for you by the AWT API. These events are then queue and dispatched to the various components (via a serious of steps). Each interested party then handles those requests that are of interest to them before passing them up the food chain till it reaches you.
The question is, should you care?
In some respects yes, but do you care how electricity works or just that you can turn on the light switch?
I'm sure there's better documentation, but you could take a look at http://docs.oracle.com/javase/1.3/docs/guide/awt/designspec/events.html for starters...
Swing calls your ActionListener automatically when the action occurs. The actual method call is located deep inside the source code of Swing.
I have started trying to create normal MVC Swing components. I have no problems with M and C, but V had thrown at me one problem which I cannot normally solve.
The problem is: Controller is main class of the component (MyComponent, for example), and it extends JComponent. View is ui delegate (MyCompanentUI) extended from ComponentUI class. All what delegate does is adds JTextField in MyCompanent and provides data binding between MyComponentModel and this field. It works just fine. But how I can bind events from JTextField to MyComponent?
If user wants to handle some events he adds listeners to MyComponent, but all real events (mouse, focus, keys, etc.) intercepted by JTextField, about which user does not really knows.
So is there any normal way to do this, except catching events and translate it to original component by hands? Or is there another way to create delegate and I just really do it all wrong?
UPD:
Thanks for your response, trashgod.
But I had something different in my mind. I was talking about something like "events inheritance", like in the case of "inheritsPopupMenu" method. So that then key, focus or mouse event happens to the component one does not process it itself, but directly transfer it to parent component. But it seems impossible, because I have noticed JSpinner has exactly the same issue - you cannot get almost any event notification from this very component.
If you are writing your own JComponent subclass and want to allow for custom UI delegates, I'd start with Kirill Grouchnikov's How to Write a Custom Swing Component.
If you are writing a composite that includes an existing JComponent subclass, such as JTextField, see if you can leverage the existing Action instances described in How to Use Key Bindings. ScrollAction is an example. You can learn the names of such actions from the component's source(s) or using #camickr's handy utility seen in the article Key Bindings.