I was checking for an event that indicates if the Combo display list is open, but did not see anything.
I thought of a mouse down/up event hook, but I quickly realized that a user presses and releases the mouse to display the list. Also, one can use a keyboard.
I saw this article, which said to use the getListVisible() method, however that would either some sort of timer. A mouse up event is not quite accurate for implementing the check and a timer seems like major overkill for a simple task.
cboServers = new Combo(this.cmptLogHtsControl, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
cboServers.addMouseListener(new MouseAdapter()
{
#Override
public void mouseDown(MouseEvent arg0)
{
}
#Override
public void mouseUp(MouseEvent arg0)
{
}
});
gridData = new GridData(GridData.FILL, GridData.FILL, true, true);
gridData.widthHint = 300;
cboServers.setLayoutData(gridData);
this.cboServers.addSelectionListener(new SelectionAdapter()
{
#Override
public void widgetSelected(SelectionEvent arg0)
{
}
});
Am I missing something? Thoughts?
Since the popup is done by the native control there probably isn't any way to see this.
Looking at the implementation of Combo on Mac OS X getListVisible() is done using events which are specific to OS X and are not exposed in the SWT API.
Related
Seen this somewhere in StackOverflow. Just want to know how it works...
public void mouseClicked(MouseEvent e){
int x = e.getX();
int y = e.getY();
}
x and y are coordinates and can be shown to screen using JLabel, but the method name is mouseClicked. How does java know the mouse has been clicked?
(Hope this makes sense)...
The method mouseClicked is likely from java.awt.event.MouseListener interface (https://docs.oracle.com/javase/7/docs/api/java/awt/event/MouseListener.html)
A listener is a type of callback that follows the observer pattern, something happens, you get notified.
You can attach listener to items that support it. For example:
MouseListener listener = new MouseListener() { /* see example code below */ };
JLabel label = new JLabel("This is a clickable lable");
label.addMouseListener(listener);
See the following answer to get more info and reference to reading articles.
https://stackoverflow.com/a/17415300/132121
#transformer here is an empty implementation of the MouseListener you would create in Java code.
MouseListener listener = new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
// This is the method where you would get your callback
// whenever somebody clicked on the view that has this listener
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
};
This is an event handler. In order for it to work, it has to be "attached" to something in the front end (most likely a button, but it could be another UI element too).
Exactly how this works depends on which UI framework is being used, but since this is Java I assume it's most likely AWT. You can find more details in tutorials, e.g. here.
Incidentally, how significant the name is depends on which UI framework this is from. In Android, WPF, and ASP.NET, for example, the name of event handlers could theoretically be anything, it's mostly just a matter of convention (not actual requirement) what you call it. (Obviously, you have to be consistent with the name, though). As pointed out in the comments, though, in AWT this name is actually likely significant due to the class that contains it implementing an interface.
I added a JPanel to a JRadioButton - so that I may display whatever I want in the radio button.
This all worked as expected. But to allow for text wrapping, I used a JTextArea and added it to the JPanel contained within the radio button.
Now I have an issue where, if the user clicks on the JTextArea, then the JTextArea consumes the mouseEvent and as a result there is no response from the radio button (it doesn't 'select').
Is there a way get the JTextArea to ignore the mouse click, so that the parent may handle it instead?
I tried add the JTextArea's listeners to the radioButton instead.
I also tried to remove its listeners completely, but both these attempts failed.
Anyone have any suggestions?
Strong beware
Most JSomething are not meant to be used as containers even though it's possible - the outcome of doing it anyway is more or less visually and behaviourally undetermined!
That said, did it recently, to implement something similar to a Windows task dialog. If the requirement includes keeping the button clickable (and why else would you mis-use it as a container :-) the main problem (layout apart) is to make all added components completely mouse-transparent. Which is more difficult than can be expected. The minimum is to not allow adding of mouseListeners and disable the acceptance of mouseEvents:
final JTextArea area = new JTextArea("replacement ..") {
#Override
public synchronized void addMouseListener(MouseListener l) {
LOG.info("adding here ...?");
}
#Override
public synchronized void addMouseMotionListener(
MouseMotionListener l) {
}
#Override
public synchronized void addMouseWheelListener(
MouseWheelListener l) {
}
#Override
public void addNotify() {
disableEvents(AWTEvent.MOUSE_EVENT_MASK |
AWTEvent.MOUSE_MOTION_EVENT_MASK |
AWTEvent.MOUSE_WHEEL_EVENT_MASK);
super.addNotify();
}
};
Plus make sure it's not focusable
area.setEditable(false);
area.setFocusable(false);
area.setRequestFocusEnabled(false);
Plus unregister dragging and tooltips
ToolTipManager.sharedInstance().unregisterComponent(area);
area.setDragEnabled(false);
Nevertheless, there might still be surprises ahead, f.i. call the following twice (that is disable and enable again), which will internally re-enable mouseEvent:
area.setAutoscrolls(!area.getAutoscrolls());
So at the end of the day, we might get away with it - but never be entirely certain that we succeeded.
What about this? Create and add your own MouseListener to TextArea
JPanel p = new JPanel();
JTextArea t = new JTextArea("line \n line");
t.addMouseListener(new MyMouseListener());
p.add(t);
jRadioButton1.add(p);
jRadioButton1.addMouseListener(new MyRadioButtonMouseListener());
And in the MyMouseListener Dispatch event
private class MyMouseListener implements MouseListener {
#Override
public void mouseClicked(MouseEvent e) {
Component source = (Component) e.getSource();
source.getParent().getParent().dispatchEvent(e); // 2x getParent() because JTextArea->JPanel->JRadio
}
.
.
.
}
And finally RadioButtonMouseListener
private class MyRadioButtonMouseListener implements MouseListener {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("CLICK ON RADIOBUTTON !!");
}
.
.
.
}
I mean, like, pressing 'F5' in web browser will refresh the web page regardless of where the focus is. How do i do this in Java with GUI app? I can do 'addKeylistener' to all components but I'm sure that's not the proper way.
You can use Swing's input and action map mechanism:
component.getRootPane().getInputMap(JRootPane.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0), "refresh");
component.getRootPane().getActionMap().put("refresh", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
// Code here
}
});
The best solution for that kind of task is to register a listener into standard KeyboardFocusManager, like I recently explained in this answer.
Another option is to use a menubar for your application. Then Refresh just becomes a menu item on a menu and you can assign F5 as an accelerator to the menu item. Behind the scenes it will do the key bindings for you.
This is a good approach because now you have a self docummenting GUI. User can invoke refresh by searching the menu for various options. Advanced users will eventually learn the accelerator key and and not even use the mouse. Like all GUI design you should be able to invoke a function using either the keyboard or the mouse.
You may add an AWTEventListener to the java.awt.Toolkit
AWTEventListener listener = new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent ev) {
if (ev instanceof KeyEvent) {
KeyEvent key = (KeyEvent) ev;
if (key.getID() == KeyEvent.KEY_PRESSED && KeyEvent.getKeyText(key.getKeyCode()).equals("F5")) {
System.out.println(ev);
// TODO something meaningfull
key.consume();
}
}
}
};
Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.KEY_EVENT_MASK);
for my app I need the space key to call a function independent from the focused widget, everywhere in the app but only if the according tab is opend. I found that one can add a filter to the display, like this:
getShell().getDisplay().addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event arg0) {
if( arg0.character == 32 ) { /**SPACE*/
if( mainTabs.getSelection().equals(analyseSoundFilesTab)) {
soundController.playButtonClickHandler();
}
}
}
});
That works fine most of the time, but if I give a button the focus via the "tab" or "shift tab", its kinda strange - the space bar will than activate a "button pressed", as if one clicks the button with the mouse. Im a bit stuck now, I don't know how to avoid this...
For the buttons, I have implemented a SelectionListener.
Regards.
You can use TraverseListener and disabled press event detection using doin field. Here is a sample code:
display.addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event e) {
if (e.character == 32) {
System.out.printf("Space detected %s\n", e);
}
}
});
Button b1 = new Button(shell, SWT.PUSH);
b1.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent se) {
System.out.printf("Button pressed %s\n", se);
}
});
b1.addTraverseListener(new TraverseListener() {
#Override
public void keyTraversed(TraverseEvent te) {
System.out.printf("Traverse detected %s\n", te);
te.doit = true;
}
});
If addTraverseListener() didn't exist, your space button was detected after filter, so you would see "Space detected..." and after that "Button pressed...". Now that you set te.doit = true, you say to SWT to do space bar traversal (which does nothing actually) instead of firing key listener. You may optionally check te.detail to only prevent mnemonic traversals.
Choosing the 'Space key' is the real problem, because it is a general feature in most (all?) OS's that pressing space is equal to selecting the widget that has focus.
A way out would be using subclassed Button widgets that ignoring Space.
But it would confuse a lot of users, just because they expect that a focussed button is selected when they hit space and do not expect some other action.
Using standalone SWT Scrollbars is something of a hack (using this workaround), but it can be done. Here's a snippet:
ScrolledComposite scrolledComposite = new ScrolledComposite(
parent, SWT.V_SCROLL);
ScrollBar scrollbar = scrolledComposite.getVerticalBar();
Shell tip = new Shell(UserInterface.getShell(), SWT.ON_TOP
| SWT.NO_FOCUS | SWT.TOOL);
// ..stylize and fill the tooltip..
Now what I'm trying to do is monitor when the user is interacting with the scrollbar. In particular, I want to know when the user is dragging the scrollbar—and when it has been released—in order to display an Office 2007-style tooltip revealing which page the position of the scrollbar corresponds with.
Presently, I have the following code which displays the tooltip:
scrollbar.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent event) {}
public void widgetSelected(SelectionEvent event) {
tip.setVisible(true);
}
}
It would seem logical then to have the tooltip disappear when the mouse button is released:
scrollbar.addListener(SWT.MouseUp, new Listener() {
public void handleEvent(Event event) {
tip.setVisible(false);
}
});
However, neither scrollbar nor scrolledComposite seem to respond to the SWT.MouseUp event when the user interacts with the scrollbar.
I presently have a workaround that hides the tip after a timeout, but I'm not satisfied with this. Any insights would be most appreciated!
Scrollbar's javadoc said this:
When widgetSelected is called, the
event object detail field contains one
of the following values: SWT.NONE -
for the end of a drag. SWT.DRAG.
SWT.HOME. SWT.END. SWT.ARROW_DOWN.
SWT.ARROW_UP. SWT.PAGE_DOWN.
SWT.PAGE_UP. widgetDefaultSelected is
not called.
So my suggestion is get your tooltip to appear and disappear is to check for the event.detail type.
public void widgetSelected(SelectionEvent event) {
tip.setVisible(event.detail != SWT.NONE);
}
scrollBar.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent e) {
}
public void widgetSelected(SelectionEvent e) {
if (e.detail == SWT.NONE) {
// end of drag
System.out.println("Drag end");
}
else if (e.detail == SWT.DRAG) {
// drag
System.out.println("Currently dragging");
}
}
});
Hope this will help you... But I can see a problem with mousewheel use that throws multiple drag end events...
Paul,
try using addMouseEvent method from a Scrollable object. For example:
Scrollable scrollable = scrollbar.getParent();
scrollable.addMouseListener(new MouseListener () {
void mouseDoubleClick(MouseEvent e) { ... }
void mouseDown(MouseEvent e) { ... }
void mouseUp(MouseEvent e) { ... }
});
Actually, I don't know if this approach will work. But, it's an attempt.
Good luck!