The question:
In Swing, when my MouseWheelListener receives a MouseWheelEvent, how can I combine the multitude of parameters contained within that event to obtain a single signed integer representing the number of units to scroll by, taking into account the fact that the "event type" may be either MouseWheelEvent.WHEEL_UNIT_SCROLL or MouseWheelEvent.WHEEL_BLOCK_SCROLL ?
Background:
Anyone who has ever had to deal with Swing's MouseWheelEvent must have noticed that it is preposterously complicated: instead of a single parameter containing the amount by which to scroll, it offers 5 parameters: getScrollType(), getScrollAmount(), getWheelRotation(), getPreciseWheelRotation(), and getUnitsToScroll().
The "scroll type" appears to be crucial for this, however the documentation (Which nowadays can be found at Oracle - Class MouseWheelEvent) mentions but does not explain the value of WHEEL_BLOCK_SCROLL.
Adding insult to injury, Oracle's own "tutorial" on the mouse wheel listener Oracle: How to Write a Mouse-Wheel Listener completely fails to show what to do when WHEEL_BLOCK_SCROLL is received, and instead shows how to display "WHEEL_BLOCK_SCROLL" when that happens.
It appears that WHEEL_BLOCK_SCROLL is very seldom implemented, so it is quite unclear how to handle it, and how to even observe it happening. One of the very rare pieces
of code that you can find out there which attempts to do something meaningful with WHEEL_BLOCK_SCROLL is at Github / iconfinder / batik / sources / org / apache / batik / swing / JSVGScrollPane.java but the code is commented-out, so I cannot trust that it ever worked.
Perhaps events of type WHEEL_BLOCK_SCROLL can be triggered if you go to "Mouse" settings in Windows, and in the "Roll the mouse wheel to scroll" box select "One screen at a time" instead of "Multiple lines at a time", but I have not tried this yet. Here is an unanswered question about this on stackoverflow: How do I generate a java swing WHEEL_BLOCK_SCROLL event?
Just by looking at the documentation, and not having worked with MouseWheelEvents in practice, I suspect that the method getUnitsToScroll() performs exactly what you are asking for.
The documentation says:
This is a convenience method to aid in the implementation of the common-case MouseWheelListener - to scroll a ScrollPane or JScrollPane by an amount which conforms to the platform settings. (Note, however, that ScrollPane and JScrollPane already have this functionality built in.)
This method returns the number of units to scroll when scroll type is MouseWheelEvent.WHEEL_UNIT_SCROLL, and should only be called if getScrollType returns MouseWheelEvent.WHEEL_UNIT_SCROLL.
In case you hit a WHEEL_BLOCK_SCROLL, probably the page-up or page-down keys were pressed. In that case the amount to scroll is one page size, resembling the component's getHeight() value.
Related
I'm sorry this is probably way too basic to be on here, but it's a subject I've been struggling with for about a month now and I don't know where else to go (as far as I know there is no "noob overflow", lol).
I'm trying to create a class that would:
1. put an image on a window (a JFrame, JPanel or other container)
2. be able to support keyboard and mouse listeners
3. could have multiple instances in the same container
So anyway I've tried all the usual places - Google, YouTube, the official Java site (sorry forgot the URL) and of course here on Stack Overflow - but haven't been able to find anything even remotely similar to what I'm trying to do.
Of course, I've also considered the possiblity that maybe it can't be done at all. There doesn't seem to be any kind of standard "JImage" or "JGraphic" that works like JButton or JLabel, and for whatever reason graphics requires a completely different list of (extremely involved) processes and procedures. As an example, in this post: How to "really" draw images in a Java app - it took me 60+ lines of code and 2 classes to just come close. That project didn't work in the end because for some reason it would only let me create one instance (even it you created 2-4 in the main method, it would only display the last one you told it to add).
But anyway, assuming that I'm not trying to "re-invent the wheel" here and it is actually possible (in Java), does anyone have an idea as to how (or at least know of a better site to study it)? Unfortunately most of the sites I've visited tend to assume you know all the inner workings of images (I know what a pixel is but that's about it - Buffers, Rastars etc. are still beyond me). It would be absolutely outstanding if there were a site that would explain it in layman's terms, if such a site exists. Thanks in advance.
Just use a plain old JLabel.
Regarding your requirements:
put an image on a window (a JFrame, JPanel or other container).
You can give a JLabel an ImageIcon of the image of interest and it will display it. This can then be easily placed in any other container such as a JPanel or JFrame.
be able to support keyboard and mouse listeners
Any component that extends JComponent, such as a JLabel allows for use of MouseListener, MouseMotionListener and can listen for keyboard input via Key Bindings.
could have multiple instances in the same container
You can add as many as you'd like to any container. Just be cognizant and respectful of the layout managers in use.
Note: see the edit (save some time reading)
I'm trying to make my mind-mapping program respond to shortcuts like CTRL+RIGHT (reordering nodes) and TAB (insert child at next indent level). I have a JPanel that handles all of the keystrokes. It resides inside of a JTabbedPane that might be the cause for Key Bindings not working. I've chickened out and decided to just use KeyListener.
The problem is that with the aforementioned key combinations, Swing automatically shifts the focus to some other component. I'd rather not manually put setFocusable(false) everywhere. How can I disable these shortcuts altogether in such a way that the focus will not be shifted, and the relevant KeyEvents will still be sent to my JPanel?
Edit:
I used the following code:
for (int id : new int[] {KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS})
setFocusTraversalKeys(id, Collections.EMPTY_SET);
to disable the default traversal keys (particularly TAB.)
Now the issue is actually why CTRL+UP causes a loss of focus. When pressing CTRL+DOWN, for instance, it's fine. The component behaves as expected. But with CTRL+UP, it works as expected and then focus is shifted/lost somehow. Can anyone say what CTRL+UP means and how to disable it wherever it is? Google isn't helping.
KeyBinding are used for all KeyEvents implemented in Swing APIs, maybe there is/are conflict
is required to override required KeyBindings, change used Keys, set to null, e.i. depends of your requirements
list of KeyBindings by #camickr
I am working with an application that is experiencing painting issues on some users computers when the mouse passes over the tabs in a JTabbedPane. They also occasionally have similar issues on other interactive components like JButtons. I have only ever seen this error occur on mouse overs.
The application is being run with 1.6.0_20 and I have already tried the flag recommended in update 10 in case it was an issue with D3D (-Dsun.java2d.d3d=false).
Since I am a new user I cannot post a picture to illustrate this error. The best example I can think of is using Windows paint eraser on an image would create something similar to what I am seeing.
I appreciate any help you can provide.
Without an sscce that exhibits the problem you describe, it's hard to be specific, but this reminds me of the rendering artifact associated with setting the opaque property to true without completely rendering the area defined by a component's bounds. In particular, if you override paintComponent() and "do not honor the opaque property, you will likely see visual artifacts." Finally, the default opacity setting of some components varies by Look & Feel, so the effect may be platform dependent.
Sorry for the odd choice of words for the title, however, "border" seems to be the inappropriate term. While it is true that the visible line surrounding an icon in a JToggleButton can be made invisible by using setBorderPainted(false), the same is not true for JCheckBox and JRadioButton.
I can not use the JToggleButton and therefore need to use either the JCheckBox or JRadioButton (or some derivative of JToggleButton I am not aware of), but need the square or circle, respectively, to be non-visible when there is no icon on the button. Also, using setVisible(false) eliminates the button from the layout, however, I need the space to be reserved and not have the component layout change (using GroupLayout).
Any suggestions? Am I going to have to create a custom renderer? I will be looking at that in the mean time.
The route into this would be through customising the look at feel by changing some of the UI properties in the UImanager (the sort of thing that allows you to make simple tweaks with fonts and colours and presumably the images used for the checkboxes or radiobuttons) -- but it's many years since I last did that sort of thing and can't remember the details.
A little Googling turned up this project to inspect current property values, so might at least help with indicating the right part of the APIs to be looking at.
You have to choices here:
1) Customize Look and Feel as described in previous entry.
2) Create your own custom controls by inheriting from existing ones and overriding component painting.
I found a cheap and easy (read hack) for this. I created an empty transparent icon and used it when I didn't want any item to be displayed.
I'm trying to internationalise a Java applet and with that, support scripts which are written from right to left. I want to set up component orientations for all java components added to the view automatically.
My solution so far has to listen to all AWTEvent's using the windows mask:
c.getToolkit().addAWTEventListener(listener, AWTEvent.WINDOW_EVENT_MASK);
...and then setting the c/o on each window added, as well as adding component listeners to set c/o on any components added to the window at a later point.
My issue is that JInternalFrames are not handled by this solution, I want to be able to add another listener for these events, much like I have done for windows. Any ideas?
Or alternatively, are there any better approaches to handling script direction for all components in an applet?
Add a ContainerListener to the JDesktopPane. As a component is added to the desktop you can change its orientation.
Do you have a handle on all those JInternalFrames? If so, try the internal frame listener.
http://java.sun.com/javase/6/docs/api/javax/swing/event/InternalFrameListener.html
It notes that it's the analogue to the AWT WindowListener.
AWTEventListener on the current Toolkit will only give you events coming from the toolkit. Generally events generated by lightweight components will have been caused by mouse or key events.
Asking for all of something in a process is usually a very bad sign. A low-level piece of code is making policy for the whole program. A much better approach is to add listeners near to where you create the component, before it is "realised". This is repeated code, but then you probably already have repeated code. So factor out into a method. Then you have only one place to update, unless you have any cases where it doesn't apply which would have broken the global approach.