Get access to Thumb/Handle/Knob of Swing's JSlider - java

Basically I want to display the current value pointed to by the slider handle when in motion (either via mouse or keyboard). I can easily get the current value by adding a new ChangeListener & overriding stateChanged method. But I cant seem to get the current location of the handle.
I can just bite the bullet and create a label at a constant place & update it continuously but I want to display the value just above (or below) the handle.

Not an good or very flexible solution but maybe you can implement your own SliderUI. E.g. using the already defined BasicUI you can access the field thumbRect which contains the values you need.
slider.setUI(new BasicSliderUI(slider) {
public void paintThumb(Graphics g) {
super.paintThumb(g);
g.setColor(Color.black);
g.drawString(Integer.toString(slider.getValue()), thumbRect.x, thumbRect.y + thumbRect.height);
}
});

If the Nimbus Look and Feel is an option, a live display of the value can be specified in the relevant UI default:
UIManager.getLookAndFeelDefaults().put("Slider.paintValue", true);

Related

Update GUI components after loading settings JAVA

I have an application with a GUI with sliders and comboboxes mainly. I use the sliders and combos to change values and parameters in various classes in the project. I'm trying to implement the possibility to save and load this parameters and I have done so using the preferences API.
I can save and load parameters, but when I load them I can see the changes in values, so that works, but the GUI does not update to reflect those new values. is there a way to tell the GUI to do so?
For instance I have a frequency slider that changes the frequency value in an oscillator. If I change the value with the slider, save it, change the value of the slider again and then load the saved value, I can hear it has changed but the slider didn't move.(makes sense as I haven't told it too). Can I bind the position of the slider with that frequency value somehow?
gui
//OSC1 slider
JSlider Osc1FreqSlider = new JSlider(SwingConstants.HORIZONTAL, MIN_OSC_FREQ, MAX_OSC_FREQ, NOTE_A_FREQ);
Osc1FreqSlider.setOpaque(false);
Osc1FreqSlider.setMajorTickSpacing(50000);
Osc1FreqSlider.setMinorTickSpacing(50);
Osc1FreqSlider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
settings.setOsc1Freq((float)source.getValue()/100);
}
});
settings class
public void setOsc1Freq(float freq) {
m_Osc1Freq = freq;
}
After setOsc1Freq( freq ) you have to do jSlider.setValue( freq ).
The way I do this in my own projects is that I never use free-standing primitive values like float freq; instead, I have an observable class with a getter and a setter, which issues an event when the value changes, and then I wrap every single one of my controls in another class which knows how to interact with such an observable. So, every time the value of the control changes, the value in the observable changes too, but also, every time my program changes the value of the observable, the control also takes notice and updates itself too.
I would think that it is practically impossible to write any kind of gui without this functionality, but apparently I seem to be contradicted by the existence of a myriad of gui frameworks out there that do not support this and force you to re-invent.
(Posted on behalf of the OP).
I solved my problem by splitting components declaration, moving them to another singleton class, creating accessor methods and then in the gui class I assigned the variables to the getters.

Java - Custom JSlider will not update

I have a custom component based on the JSlider. It's essentially the same thing only it has 2 thumbs, which I named a DualSlider.
I need to change the maximum value of the slider once in a while, so every time I do, I call updateUI to reflect this.
public void updateUI() {
this.setUI(new DualSliderUI(this));
this.updateLabelUIs();
}
However, the maximum value of the DualSlider when I try to use it is still set at the original value no matter how many times I try to change it while using my program. I can confirm with a few println statements that a new DualSliderUI is being made with the slider that has the new max value, but for whatever reason the original DualSliderUI I initialized the slider with is the one that is in use.
What other things do I have to make sure I do when I update a property so I can avoid this?
1) I can't see reason for usage updateUI() this should be done once time, only when you built this JSlider, never do that repeately
2) you have look at BoundedRangeModel, maybe

Can you explicitly set the background color of a SWT Text widget to the default color?

I have a SWT Text field in my UI. If the text field contains an unusual value (as determined by my specific use case) I will set the background color red, to get the users attention. If the value (the text) of the text field changes to a normal value, I would like to set the background color back to default, but I don't see that this is possible.
Is it possible? Can I explicitly change the background color of a SWT Text widget back to default?
Try passing null for the Color argument to setBackground:
text.setBackground(null);
I don't think there is a built-in method that gets the "original color". What I would suggest is keeping a field with the old value, and return it when needed:
class FlashingText extends Text{
//Enter needed ctors
private Color originalColor;
public void markForUser(){
originalColor = getBackground();
setBackground(Color.RED);
}
public void resetColor(){
setBackground(originalColor);
}
}
Notice this will work even if in the future you decide to change the Text's color for design purposes. Also notice giving an entity in your program an object is usually good design.

Java Swing: How to be notified if tool tip is about to become visible?

I have a lot of components that set tool tips with JComponent.setToolTipText(...). However, these tool tips change often based on many events. I could make a setToolTipText(...) call each time one of these events occur; but I would much prefer to simply have a tool tip listener that notifies me when a tip is about to show, so that I can update the tip, if needed. I can't find anyway to assign a listener to the tool tip, am I missing one?
*Note, my solution needs to be Java 1.4.2 compliant.
Actually found a decent solution: override JComponent.getToolTipText().
One disturbing nuance to this, this is the code from JComponent.setToolTipText():
public void setToolTipText(String text) {
String oldText = getToolTipText();
putClientProperty(TOOL_TIP_TEXT_KEY, text);
ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
if (text != null) {
if (oldText == null) {
toolTipManager.registerComponent(this);
}
} else {
toolTipManager.unregisterComponent(this);
}
}
So, if you override getToolTipText to return some dynamic value, it better return null the first time it is called, or your tool tip will not get registered with the ToolTipManager.
I am not sure there is an easy way to be notified of this event. However, it sounds like you might need to change your design. Having to update a large number of components with constantly changing tool tips seems odd and problematic. Maybe just add a generic MouseListener that determines the message for the current component at the current time. That will get you away from having to constantly change all components.
Override the JComponent's createToolTip() this will act as a listener, whenever a tooltip is about to be created, this method is called.

How to get a SWT Tray or TrayItem location

Any ideas how to get the location of the system tray (Tray) or item's on it (TrayItem) with SWT? Getting the bounds from the display only gives me the entire screen's bound. ie
item.getDisplay().getBounds();
will give me (0, 0, 1024, 1024) on my Windows box.
I'd also like to know if the system tray position (left, right, top, bottom) but can probably guess given the location. This is all so I can popup a message near the system tray.
This is a duplicate of this post but I want to offer a bounty (and so control what I consider a correct answer).
If you just want to display a shell near the tray item reacting to a user event (as is my case). You can get the pointer location when the event is triggered over the tray item:
trayItem.addSelectionListener (new SelectionListener () {
#Override public void widgetDefaultSelected (SelectionEvent aEvent) {
widgetSelected (aEvent);
}
#Override public void widgetSelected (SelectionEvent aEvent) {
if (mWindow.isVisible ()) {
Shell wnd = mWindow;
mWindow = new Shell (mDisplay);
wnd.close ();
}
else {
mWindow.setLocation (mDisplay.getCursorLocation ());
mWindow.open ();
}
}
});
You can find the whole source code here.
If you want to notify some other event (not generated by user input), I guess your best bet is to use a ToolTip as Sandman points out in the previous answer.
Good luck!!!
widget.getDisplay() always returns the display used for the specified widget, so that will never work.
I far as I can see for both Win32 and MacOS, you will not get the location before the first mouse event on the item itself ;-(
If you are willing to add some architecture dependent code, you can try the following...
For MacOS - though not tested:
sub-class TrayItem (remember to override checkSubClass())
use getLocation() to return the current location of the item
For Win32 - again not tested - you can try the same but this time override messageProc(...). One of the first messages will allow you to query the current location of the handle...
Guessing from the API, it looks like there is no such option (in contrast with, e.g. a ToolItem). :(
Thanks to those who tried to answer. However, as with the other post, I think its just not possible so I'm answering my own question in the negative :(
You can map from one coordinate system to another by using Display.map. You can map your item's 0,0 (Upper Left) into Display coordinates by doing:
Display.map(item, null, 0, 0)
Use null as the "to" control for mapping to the Display coordinate space.

Categories

Resources