I've extended a JList to provide two separate functionalities, toolTipText for items, and right-click options. Both work separately, but when I try to use them together, the MouseMoved events aren't being recognized? Below are the guts of my new listener methods. How should I be negotiating these various events?
public class JListTT extends javax.swing.JList {
public JListTT() {
super();
addMouseListener(new ttListener());
...
class ttListener extends MouseAdapter {
public void mouseMoved(MouseEvent e) {
String nodeID = bldItemNodeID();
theList.setToolTipText(nodeID);
}
public void mousePressed(MouseEvent ev) {check(ev); }
public void mouseReleased(MouseEvent ev) {check(ev); }
public void mouseClicked(MouseEvent ev) {check(ev); }
public void check(MouseEvent ev) {
if (ev.isPopupTrigger()) {
theList.setSelectedIndex(theList.locationToIndex(ev.getPoint()));
menu.show(theList, ev.getX(), ev.getY());
}
}
}
You add the ttListener object as a MouseListener, but I don't see you adding the ttListener object as a MouseMotionListener. For example:
ttListener myMouseadapter = new ttListener();
addMouseListener(myMouseadapter);
addMouseMotionListener(myMouseadapter);
I did not test this myself, but looking at the javadoc of JList the tooltip functionality is available out of the box. The javadoc of JList#getTooltipText clearly states
Overrides JComponent's getToolTipText method in order to allow the
renderer's tips to be used if it has text set.
So if your ListCellRenderer returns a Component in the getListCellRendererComponent method which has a tooltip it will be displayed by the JList without the need of a listener.
there's not necessarily a need for a low-level approach as a custom mouse-/motionListener:
as to a per-cell tooltip, see #Robin's answer
as to a context menu, JComonent has a property componentPopupMenu: using that will cope with opening the menu on keyboard short-cut automatically
"not necessarily" because you seem to rely on the cell being selected on right click. If so, you would still need a MouseListener to trigger the selection (after decade long debates, Swing doesn't - which seems to be unusual in current native apps ;-)
You can achieve it by using mouseDragged
YourClass extends JPanel implements MouseListener{
......
#Override
public void mouseDragged(MouseEvent e) {
//code go here
}
}
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 am using an Icon with Java (Swing) JButton. Is it possible to change the icon when I take my mouse arrow over it?
I saw somewhere on Youtube that it is possible, but am unable to recall it.
You can take advantage of the JButton API which provides this kind of support.
Take a look at JButton#setRolloverIcon and JButton#setRolloverSelectedIcon
You will need to implement MouseListener like this:
public class YourClass extends JFrame implements MouseListener {
#Override
public void mouseEntered(MouseEvent e) { }
#Override
public void mouseExited(MouseEvent e) { }
#Override
public void mouseClicked(MouseEvent e) { }
#Override
public void mousePressed(MouseEvent e) { }
#Override
public void mouseReleased(MouseEvent e) { }
}
Add your function where needed.
You can override the mouseEntered() function by implementing a MouseListener and add the code to change the icon in that function.
If you're using an abstract button, you can just use setRolloverIcon() to set an image which will appear on rollOver.
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'm puzzled with a strange mouse listener behavior.
First, I defined an interface :
public interface GeniusField {
public void setEdited(Boolean b);
public void addMouseListeners();
public void addKeyListeners();
public String getStringValue();
}
then, I implement this interface :
public class GeniusComboField extends JComboBox implements GeniusField {
public GeniusComboField() {
super();
//blabla
addMouseListeners();
addKeyListeners();
}
#Override
public void addMouseListeners() {
System.out.println("ADD LISTENTER");
this.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
System.out.println("mouse mouse");
}
});
}
}
And for some reason, nothing is triggered when I click on my combobox (but I get the "ADD LISTENER" output).
I don't see what is happening.
Can someone help?
In Java Swing JComboBox don't receive the mouse events. It's the components within that do it. Try something like:
for (int i=0; i<this.getComponentCount(); i++) {
this.getComponent(i).addMouseListener(this);
}
Then make your class implements MouseListener.
Or you can override the method to add object to your combobox and call your addMouseListener() method. Like that each object will have a listener.
JComboBox is a compound component, which means it's made up of two or more other components.
You shouldn't register listeners for low-level events on compound components because they wont capture them properly.
You need to implement ActionListener to get it to work.
public class GeniusComboField extends JComboBox implements ActionListener, GeniusField {
. . .
}
More information about this is available in the swing trail of the Java tutorial.
I tried this code. it seems to work just fine. Problem may be where your adding this combo box. The mouse listener will be for the combo box itself, not the items in it.
Somebody has to implement MouseListener( may be GeniusComboField ).
something like this.
public class GeniusComboField extends JComboBox implements GeniusField, MouseListener
I want to show a small popup menu when you right-click a tab, now this is working fine but when you right click it also selects that tab which is unwanted.
So my idea was to make a new class, extend JTabbedPane and recode those mouse events. Problem is that I have no idea where to start, I was browsing its source but I can't find what part is handeling the mouseEvents.
Tabs.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent me) {
if(me.getButton()==3){
int tabNr = ((TabbedPaneUI)Tabs.getUI()).tabForCoordinate(Tabs, me.getX(), me.getY());
Component clickedTab = EventsConfig.window.MainTabs.getComponentAt(tabNr);
newMenu(clickedTab, me.getX(), me.getY());
}
}
});
Beware: dirty hack ahead! The only reason I recommend it, is that I consider the behaviour (select on right press) a bug in the BasicTabbedPaneUI's Handler.
The basic idea is to grab the listener installed by the ui, remove it, wrap into a custom listener which delegates everything except a right pressed to the original and add that to the pane:
private void installMouseListenerWrapper(JComponent tabbedPane) {
MouseListener handler = findUIMouseListener(tabbedPane);
tabbedPane.removeMouseListener(handler);
tabbedPane.addMouseListener(new MouseListenerWrapper(handler));
}
private MouseListener findUIMouseListener(JComponent tabbedPane) {
MouseListener[] listeners = tabbedPane.getMouseListeners();
for (MouseListener l : listeners) {
if (l.getClass().getName().contains("$Handler")) {
return l;
}
}
return null;
}
public static class MouseListenerWrapper implements MouseListener {
private MouseListener delegate;
public MouseListenerWrapper(MouseListener delegate) {
this.delegate = delegate;
}
#Override
public void mouseClicked(MouseEvent e) {
delegate.mouseClicked(e);
}
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) return;
delegate.mousePressed(e);
}
#Override
public void mouseReleased(MouseEvent e) {
delegate.mouseReleased(e);
}
#Override
public void mouseEntered(MouseEvent e) {
delegate.mouseEntered(e);
}
#Override
public void mouseExited(MouseEvent e) {
delegate.mouseExited(e);
}
}
then you have to add JPopupMenu (or JToolTip on MouseHoverOver ) to the JTabbedPane
A possible workaround is to set your custom tab component for each tab - see JTabbedPane#setTabComponentAt(...). Add a mouse handler to your custom tab component and redispatch left click events to the tabbedPane as described at http://www.jyloo.com/news/?pubId=1315817317000.
The custom tab component can be a simple JLabel (used for the tab title) or a container for multiple components. Depending on your requirements you can e.g. add an arrow button which will open a popup menu by left clicking the related button.
This article will helpful for removing unwanted tab selection when you click right mouse button.
Stop right click Event on JTabbedPane
I liked to add more about removing Mouse Listeners.
Try to override the method rather than removing it. It's better for future code updates.
The problem is BasicTabbedPaneUI's have inner class called Handler. That handler class override Mouse Listener.
To stop right click tab selection and show pop up menu; we need to override this method in BasicTabbedPaneUI,
protected MouseListener createMouseListener() {
return getHandler();
}
To get better look and feel we should override SynthTabbedPaneUI class.
SynthTabbedPaneUI is extends BasicTabbedPaneUI.
So our inner class is like this,
private class SynthTabbedPaneUIWrapper extends SynthTabbedPaneUI
{
private MouseAdapter menuAdapter;
private MouseAdapter getMenuAdapter()
{
if (menuAdapter == null)
{
menuAdapter =
new MouseAdapter()
{
#Override
public void mouseReleased(final MouseEvent e)
{
//implement to stop right click tab selection
//implement to show pop up menu
}
};
}
}
#Override
protected MouseListener createMouseListener()
{
return getMenuAdapter();
}
}
After that we can set our custom UI object into TabbedPane.
tabbedPane.setUI(new SynthTabbedPaneUIWrapper());