How to get a SWT Tray or TrayItem location - java

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.

Related

Deselect JToggleButton if file exists

as I mentioned in a post before, I'm porting my program to Java, to make it available for Mac OS and Linux users.
At the start of the program, I'd like to check if adb is installed to the system using this code:
private void checkADBExists()
// Checks if adb binaries exist and sets jTogglebutton1 correspondingly...
{
File adb = new File("/usr/bin/adb");
if (!adb.exists())
{
jToggleButton1.isSelected();
} else {
jToggleButton1.isSelected()= false;
}
}
Here's my problem:
If the file doesn't exist, the JToggleButton isn't selected, even though it should be and I get an error deselecting it.
Any help is much appreciated.
Thanks in advance,
Beats
Many of Swing's core components follow a simple getter/setter pattern.
That is, you can "get" a property value and "set" a property value (note, not all getters have a corresponding setter though).
In the case of a boolean property, the convention is to use "is" instead of "get", it just rolls off the tongue better.
So, in your case, all you are doing is getting the value if the selected property, not really what you want to do.
Instead use jToggleButton1.setSelected(true) or jToggleButton1.setSelected(false) based on your needs
You might like to take a look at How to Use Buttons, Check Boxes, and Radio Buttons for some more details
JToggleButton().isSelected() return a value not a variable. By JToggleButton().isSelected() = false, you are trying to assign a value to a value, it doesn't make sense, much like writing a statement 2 = 2;. use JToggleButton.setSelected(true) to set the toggle button as selected and JToggleButton.setSelected(false) to deselect.

How to re-size application components based on client's resolution?

I am having one GWT Web application, It is running perfectly in the full window size
browser but when I re-size the window, it will not looking good, all the components are not on there respective place.
So whenever I changed the window size or If I will run the application on tab or mobile device, I want to make changes to all the component's sizes.
Is there any another way available?
How can I achieve this?
You can use something like gwt-bootstrap (it can change view depending on viewport size and user-agent). But basically you could (and I think should) use #media selectors of CSS when you are creating your components.
You can handle all resize event via GWT and do manual resize of each component, but this is not very good idea because of performance of your app.
try
public static Window getWindow(Component c)
{
while (c != null)
{
if (c instanceof Window) break;
c = c.getParent();
}
return (Window)c;
}
public static int getResolution(Component c)
{
return getWindow(c).getBounds();
}
so it should be something like this
Rectangle bounds getScreenResolution(this);
Dimension resolution = new Dimension(bounds.width,bounds.height);
placed in component you want to resize.
then combine this with resize listener
getWindow(this).addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent e)
{
Rectangle bounds = getScreenResolution(this);
setPrefferedSize(new Dimension(bounds.width,bounds.height));
}
}
You can use Window.getClientHeight and Window.getClientWidth - while this doesn't return the real screen size in pixel, it returns the size of the area your GWT application can use, so it also respects the current size of the browser window.
You can listen to changes to the browser window size using Window.addWindowResizeListener.
Maybe this also solves your problem for mobile devices. If you really need to know if and what mobile device your application is running on, your best chance would be the User-Agent string, which you can obtain with Window.Navigator.getUserAgent(). You can also make a new property if you want to use deferred binding, like this:
<define-property name="mobile.user.agent" values="mobilesafari, none"/>
<property-provider name="mobile.user.agent"><![CDATA[
var ua = navigator.userAgent.toLowerCase();
if (ua.indexOf("webkit") != -1 && ua.indexOf("mobile") != -1) {
return "mobilesafari";
}
// Additional checks go here
return "none";
]]></property-provider>
You may also take a look at the LayoutPanel, which natively supports width and height in percents.
Another option would be to use CSS instead of GWT code and let the browser handle the resizing. While this isn't always a viable option, one should opt to go for it, if possible.
Is it pure GWT or are you using SmartGWT components?
If you are using SmartGWT you should be able to use Layout classes to better manage components.
Its not wise to hard code component sizes using Canvas.setWidth(int) and Canvas.setHeight(int) methods.
See how layouts can help resize components dynamically in this example.

Control Impress presentation window from openoffice API

I'm currently attempting to use the openoffice API to display a powerpoint presentation from Java - I've got a fair way in that I've managed to open a presentation and display it. However, there's a couple of things that I'd like to be able to do I can't figure out with the API as it stands:
I don't want the main Impress window to appear, just the presentation window. Now, I can start it minimized no problem with a property, but then the actual presentation window is minimised as well, which I don't want. I can also grab the window and call setVisible(false) on it, but it's still visible for a second or so while it's loading.
I want to be able to control the monitor which the presentation appears on (I'm using it in a multi-monitor setup.) I thought I might be able to grab the Window of the presentation and move it around that way as I need to, but I can't see how - for the main window I can do something like:
XModel xModel = UnoRuntime.queryInterface(XModel.class, xDrawDoc);
xModel.getCurrentController().getFrame().getContainerWindow().blah();
...but I haven't yet found a way to get the presentation Window. I'd like to be able to set the bounds of the window directly (x, y, width, height) rather than just being constrained by positioning on a single monitor.
I can live with the first point, the critical one I need to solve for my use case is the second.
Any ideas on the above? I'm an experienced Java programmer but new to UNO.
Seems the second point can be solved, ish, with the display property:
public void start() {
try {
xPresentation.setPropertyValue("Display", 1);
}
catch (Exception ex) {
ex.printStackTrace();
}
xPresentation.start();
}
Note however a few of things - firstly the display index is base 1, not 0. Secondly, trying to set the properties in an array and passing them to xPresentation on creation didn't seem to have any effect - it only worked for me setting the property later as above. Thirdly, it doesn't allow fine grained control over the window as I wanted, just control of the display the presentation appears on.

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

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);

Mac L&F problems: Differing behavior of JTextField.requestFocus()

I have a problem with JTextField.requestFocus() behavior that appears to be different on Mac OS X.
Here is my situation: I have a dialog with a JList and a JTextField. The user is supposed to write a boolean expression in the text field, and the list contains the names of all the variables that might be entered in the expression. Because the user is expected to continue entering the expression after clicking on a variable from the list, the program helpfully calls JTextField.requestFocus(). This way you can e.g click "pvalue" from the list and then type " < 0.05" without the need to click on the textfield in between.
This all works fine on my development machine (Linux), but I got a bug report from a Mac user that clicking on the list actually selects all text in the text field, making it easy to accidentally overwrite what was entered before.
I suspected this is a problem with the Mac look-and-feel, after some searching it seems that indeed there is a "Quaqua.TextComponent.autoSelect" property for the mac look-and-feel that seems to be related to this problem: http://www.randelshofer.ch/quaqua/guide/jtextcomponent.html
My general question is:
Can you suggest a workaround for this problem?
In case that is too broad, an answer to these subquestions would already be a big help:
A possible solution could be to change the property "Quaqua.TextComponent.autoSelect". How do I do that?
I'm not even sure what "Quaqua" is. It looks like it is a customized look and feel. What is the default look and feel for Mac OS X? Does it have a property similar to Quaqua.TextComponent.autoSelect?
Is there a possibility to tweak look and feel for a single component instance only? If so, how?
Is it possible to set the Mac look and feel on my Linux development machine so that I can actually confirm this bug (all the above is really based on hunches and suspicions)? If so, how?
Seems this is a bug of Mac OS. JTextFields select their contents when they gain focus though keyboard tab cycling. If the insertion point is in the middle of the text, the insertion point will remain and the entire text will not be selected.
As a workaround you can override this behavior with the following, it works fine for me:
textfield.setCaret(new DefaultCaret()).
More details you can refer to this and this.
To modify the default behaviour, you can set the system property to false before initializing the UI components: System.setProperty("Quaqua.TextComponent.autoSelect", "false"); To modify a single component, you can use JTextField#putClientProperty("Quaqua.TextComponent.autoSelect", Boolean.FALSE);.
You can find other MacOS L&F specific properties here:
Quaqua Look & Feel - User Guide
A workaround might be (and I haven't tested this) to make the JList that inserts the variable names unfocusable. That way the focus will remain in the text field when you click on an item in the list. I'd recommend to use setRequestEnabled(false) on the JList, so that they are still focusable if you tab to them, but clicking them with the mouse will not focus them.
Sorry to add to an old question, but I just came across this problem and used the following code, which seems a little more complete than the previous example:
// JTextField linkedText
final int
startBefore = linkedText.getSelectionStart(),
endBefore = linkedText.getSelectionEnd();
linkedText.requestFocus(); // this was the original code line!
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
linkedText.setSelectionStart(startBefore);
linkedText.setSelectionEnd(endBefore);
}
});
This appears to protect the current cursor position or selection. (Note: This code must already run in the event dispatch thread, but you need invokeLater anyway or it doesn't work.)
I have an 'is Mac' function, so I did this inside a test for that, but it probably doesn't do any harm to do it on all platforms.
I noticed when looking through the JavaDocs that requestFocus() "is discouraged because its behavior is platform dependent." You should use requestFocusInWindow() instead and see if the same problem occurs with it.
requestFocusInWindow is part of the Focus subsystem, introduced in Java 1.4.
On a side note, the default Apple Look and Feel has at least one property in the apple.laf namespace: apple.laf.useScreenMenuBar
Edit: According to Sun, the Macintosh look and feel is only available on Macs.
While using requestFocusInWindow() is indeed encouraged over requestFocus(), it still produces the same problematic behavior on Macs (e.g., highlighting of full text field).
One workaround I got to work was to explicitly set the cursor position after requesting focus:
JTextField.requestFocusInWindow();
JTextField.setCaretPosition(JTextField.getDocument().getLength() - 1);
Note the "-1" is necessary, otherwise it will continue to highlight the entire field.
I'm curious to know if this solution is platform independent. Does this screw up the desired Linux or Windows behavior?
Mac will select the contents of the text field when the field gains focus. You can restore the state of the text field if you listen for the focus change event.
// JTextField linkedText
// Cache the state of the JTextField prior to requesting focus
final int
startBefore = linkedText.getSelectionStart(),
endBefore = linkedText.getSelectionEnd();
linkedText.requestFocus(); // this was the original code line!
// Use a focus listener to listen for the focus change and then
// reset the selected text to protect the cursor position
linkedText.addFocusListener ( new FocusListener()
{
public void focusGained( FocusEvent event ) {
linkedText.setSelectionStart( startBefore );
linkedText.setSelectionEnd( endBefore );
}
public void focusLost( FocusEvent event ) {
// do nothing
}
} );
Thank you for sharing your ideas. I had the same problem on my java application where on my windows system there wasn't a problem, but on my Mac OS X Yosemite I couldn't change the input. The focus wouldn't stay on the JTextField. Thanks to this thread I was able to fix my problem.
If you change the look and feel of the buttons and input boxes you maintain the focus and you can type again. The reset of the frame stays in the standard Mac OS look.
This is my code that I use in my java main methode. If you want to fix the problem past the try-catch code in your main methode.
public class Venster extends JFrame {
public static void main(String[] args) {
//Change L&F for mac
//Mac JTextField Bug Fix
try {
// Set cross-platform Java L&F (also called "Metal")
UIManager.setLookAndFeel(
UIManager.getCrossPlatformLookAndFeelClassName());
} catch (UnsupportedLookAndFeelException e) {
System.out.println("L&F not supported" + e.getMessage());
} catch (ClassNotFoundException e) {
System.out.println("Fout: " + e.getMessage());
} catch (InstantiationException e) {
System.out.println("Fout: " + e.getMessage());
} catch (IllegalAccessException e) {
System.out.println("Fout: " + e.getMessage());
}
//The app
JFrame frame = new JFrame();
frame.setSize(1000, 520);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("10 More Bullets by Frank Peters");
frame.setContentPane(new SpeelVeld());
frame.setVisible(true);
frame.setLocationRelativeTo(null); //start app in center
}
}
Soure:
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

Categories

Resources