I am working my way through the NeHe OpenGL examples, using the LWJGL for the OpenGL binding inside an Eclipse RCP application.
My OpenGL graphics are displayed inside the RCP canvas, not in a separate window.
Lesson 07 shows how to use the keyboard. If I try to do a:
Keyboard.create();
I get an error that the (OpenGL) "Display" has not been created.
If I create an OpenGL "Display" with org.lwjgl.opengl.Display.create(), then I get a new Window.
So how do I access the Keyboard without creating a new Window?
You cannot use the Keyboard without a Display, because of how LWJGL works behind the scenes. The best way is to just use AWT events. You can write your own input class, that could go something like this.
public class Input implements KeyListener {
private boolean aDown; //is the A key down?
//Ect, for all needed keys
public void keyPressed(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_A: aDown = true; break;
//and so on for all other needed keys.
}
}
public void keyReleased(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_A: aDown = false; break;
//and so on for all other needed keys.
}
}
public void keyTyped(KeyEvent ke) {} //Do nothing
public void isADown() {return aDown;}
}
Related
I'm trying to decide whether to use a switch or toggle for setting an alarm I'm my android application. On fairly new to android and don't know or quite understand all the ins and outs of the frame work. What would be the disadvantages of choosing to trigger the alarm with a switch over a toggle, or vice versa? Is there a slide toggle available in android framework?
The first thing you need to keep in mind is since which API do you want to compile your app?
Toggle Buttons are available since API 1 and Switches are only available since API 14.
Besides that is just a simple decision, which one is the best option for user interface/design
In my opinion Switches give a clear indication of what is currently selected.
Is there a slide toggle available in android framework?
Yes a switch can work as a slide toggle.
The code is very simple, you can basically use the same thought for these two buttons.
Here is an example of a Switch Button
btnSwitch = (Switch) findViewById(R.id.switch_1);
btnSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
if (isChecked) {
Log.i("Switch", "ON");
} else {
Log.i("Switch", "OFF");
}
}
});
Here's an example of a toggle Button
btnToggle = (ToggleButton) findViewById(R.id.toggle_1);
btnToggle.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Log.i("Toggle", "ON");
} else {
Log.i("Toggle", "OFF");
}
}
});
In a cross platform Xamarin app built with the MvvmCross framework I'm using a ToggleButton Widget in an Android .axml layout. I've bound the Checked property to a View Model property using a converter using the following binding syntax:
Checked MarketBuySellViewModel.Direction, Converter=DirectionBool, ConverterParameter='Sell'
Everything works well. On the iOS side, it appears you can use UIButton as a ToggleButton by using the Selected property. This implies that the following binding should achieve what I want on iOS:
set.Bind (SellButton).For(b => b.Selected).To (vm => vm.MarketBuySellViewModel.Direction).WithConversion("DirectionBool", "Sell");
I don't get any binding errors in the application output but the binding itself doesn't seem to work. Clicking the button doesn't set the Direction property and setting the direction to a different value does not set the Selected property on the UIButton.
Do I need to create a Custom Binding or am I simply setting up the binding incorrectly?
I also tried using a UISegmentedControl to achieve the same effect. Is binding to this control supported at all in MvvmCross? I don't see any reference to it in the source code. Does this mean I need to create custom bindings for it too?
For the UIButton, I don't believe there's any included Selected binding built into MvvmCross. Because of this - and because Selected doesn't have a simple paired event SelectedChanged, then I believe Selected binding should work one-way (from ViewModel to View) but not two-way.
There is a binding for the On of a UISwitch control and that's the control I've seen used most in these situations.
If you wanted to add a custom 2-way binding for Selected then I guess you'd have to do this using the ValueChanged event (but would need to check that is correct).
To do so, you'd just build a target binding something like:
public class MvxUIButtonSelectedTargetBinding : MvxPropertyInfoTargetBinding<UIButton>
{
public MvxUIButtonSelectedTargetBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
var view = View;
view.ValueChanged += HandleValueChanged;
}
private void HandleValueChanged(object sender, System.EventArgs e)
{
var view = View;
if (view == null)
return;
FireValueChanged(view.Selected);
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var view = View;
if (view != null)
{
view.ValueChanged -= HandleValueChanged;
}
}
}
}
and this could be registered in Setup in protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry) using something like:
registry.RegisterPropertyInfoBindingFactory(typeof(MvxUIButtonSelectedTargetBinding), typeof(UIButton),
"Selected");
Similarly, I don't believe anyone has added a two way UISegmentedControl binding yet - but would happily see one added.
Building a two way UISegmentedControl binding would be quite straight-forward - you'd just have to bind to the pair SelectedSegment and ValueChanged - with code similar to above.
Alternatively, you could switch to using a custom MySegmentedControl which had a nicer Value`ValueChanged` pair which would automatically work without a custom binding - e.g.:
public class MySegmentedControl : UISegmentedControl
{
// add more constructors if required
public int Value
{
get { return base.SelectedSegment; }
set { base.SelectedSegment = value; }
}
}
If any or all of these custom bindings are needed, then the Mvx project is happy to get these bindings added as issues or pull requests along with test/demo UIs in the https://github.com/slodge/MvvmCross-Tutorials/blob/master/ApiExamples/ApiExamples.Touch/Views/FirstView.cs project
Could be helpful to someone else, so i'm sharing my experience. I needed a two way binding for UISegmentedControl.SelectedSegment property to a ViewModel. The one way biding (ViewModel => View) works by default. I couldn't able to properly utilize the solution proposed by Stuart - to subclass the UISegmentedControl. I tried to ensure that the linker does not rip off the new custom control code, but this didn't help me a bit. So a perfectly viable solution is the one with MvxPropertyInfoTargetBinding. Here is the code working ok for me:
public class MvxUISegmentedControlSelectedSegmentTargetBinding : MvxPropertyInfoTargetBinding<UISegmentedControl>
{
public MvxUISegmentedControlSelectedSegmentTargetBinding(object target, PropertyInfo targetPropertyInfo)
: base(target, targetPropertyInfo)
{
this.View.ValueChanged += HandleValueChanged;
}
private void HandleValueChanged(object sender, System.EventArgs e)
{
var view = this.View;
if (view == null)
{
return;
}
FireValueChanged(view.SelectedSegment);
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.TwoWay; }
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (isDisposing)
{
var view = this.View;
if (view != null)
{
view.ValueChanged -= HandleValueChanged;
}
}
}
}
public class Setup : MvxTouchSetup
{
...
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
registry.RegisterPropertyInfoBindingFactory(typeof(MvxUISegmentedControlSelectedSegmentTargetBinding), typeof(UISegmentedControl), "SelectedSegment");
}
}
I've an UINavigationViewController with an UISegmentedControl in the navigation bar. I want to achieve a simple switching to different ViewControllers when users push on the segmented control.
I've tried a lot and nothing works... Considered sources:
MonoTouch Instantiating a ViewController programmatically for ContainerView
https://stackoverflow.com/search?q=viewcontroller+intptr+handle
And a lot of google research...
The whole project is storyboard based! Any solutions which targets NIB's aren't useful.
Adding a ContainerControl to my UINavigationViewController. But in this case I can only embed one controller. Creating a Embedded-Segue programmatically was not possible. Even more instantiating a UITableViewController in code which is designed in IB results in an empty view. Because I've to change the c'tor from MyTableViewController(IntPtr handle) : base(handle) to an empty constructor.
Can someone publish a working example how to use a UISegmentedControl to switch between different ViewControllers? I appreciate all your help very much.
Working solution:
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
CreateAndEmbed (TrDetailNavType.Info);
}
partial void segmentNavigationValueChanged (MonoTouch.UIKit.UISegmentedControl sender, MonoTouch.UIKit.UIEvent e)
{
CreateAndEmbed((TrDetailNavType)sender.SelectedSegment);
}
private void CreateAndEmbed(TrDetailNavType tab)
{
if (_currentViewController != null)
{
_currentViewController.View.RemoveFromSuperview ();
_currentViewController.RemoveFromParentViewController();
}
string id;
switch (tab)
{
case TrDetailNavType.Info:
id = "TagesRapportDetailInfoTableViewController";
break;
case TrDetailNavType.Lohn:
case TrDetailNavType.Material:
case TrDetailNavType.Inventar:
case TrDetailNavType.Fremdleistung:
case TrDetailNavType.Regie:
id = "TagesRapportDetailDummyViewController";
break;
}
_currentViewController = (UIViewController)Storyboard.InstantiateViewController (id);
_currentViewController.View.Frame = containerDetail.Bounds;
AddChildViewController (_currentViewController);
_currentViewController.DidMoveToParentViewController (this);
containerDetail.AddSubview (_currentViewController.View);
}
Wonder if somebody can help me with this. I am trying to open an embedded browser in an Eclipse RAP applications. All examples I have seen look something like:
link.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
try {
Browser b = new Browser(parent, SWT.NONE);
b.setText("<html><body>This is Unicode HTML content from memory</body></html>");
} catch (SWTError e) {
// Error handling here
}
}
});
That doesn't do anything (visually) though. When I replace the Browser with ExternalBrowser like so:
link.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
try {
int browserStyle = ExternalBrowser.LOCATION_BAR;
ExternalBrowser.open( "myPage", "http://www.stackoverflow.com", browserStyle );
} catch (SWTError e) {
// Error handling here
}
}
});
It works. Although not exactly as desired.
I am using Eclipse RCP 1.4.2 on OS X 10.8.2.
Any insight is highly appreciated.
When you create a new widget, you have to trigger a re-layout to make it visible. Depending on your layout, it may be sufficient to call parent.layout(). If the parent is also contained in a layout and shrunken to its preferred size, you will have to call layout() on its parent. If unsure, layout the top-level shell.
I encoutered a strange behaviour of handling mouse position by Swing when maximizing JFrame:
When I execute this very simple code...
public class Test {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("File");
menu.add(new JMenuItem("New"));
menubar.add(menu);
frame.setJMenuBar(menubar);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
... I can normally click File (first click - press,release) -> New (second click). But when I maximize JFrame and click on File - context menu disappears on mouse release immediately.
Moreover when I hold mouse button - to prevent disappearance - I must move my mouse much further to focus on New item.
The red dot represents area (more or less) where I must move my mouse to focus on New after pressing File and holding mouse button.
I've observed the same behaviour when using "right-click context menu" for example when right clicking on chart from JFreeChart.
I thought it was JDK problem because I used Oracle's JDK, but after installing OpenJDK I have the same results.
Did somebody observe this strange behaviour? Or am I missing something obvious?
I use:
1.7.0_147-icedtea (or 1.7.0_04 for java-7-oracle)
OpenJDK Runtime Environment (IcedTea7 2.0) (7~b147-2.0-0ubuntu0.11.10.1)
OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode)
Linux Mint 12 (lisa) GNOME 3.2.1
Yes - this is a bug in JDK7 as #nIcE cOw mentioned.
I've installed JDK6 and I couldn't reproduce this bug.
java version "1.6.0_23"
OpenJDK Runtime Environment (IcedTea6 1.11pre) (6b23~pre11-0ubuntu1.11.10.2)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
There is also a workaround when it is necessary to use the Oracle Java 7 (e.g. when using JavaFX). Just add the following lines of code to your window/frame class:
if (Arrays.asList("gnome-shell", "mate", "other...").contains(System.getenv("DESKTOP_SESSION"))) {
try {
Class<?> xwm = Class.forName("sun.awt.X11.XWM");
Field awt_wmgr = xwm.getDeclaredField("awt_wmgr");
awt_wmgr.setAccessible(true);
Field other_wm = xwm.getDeclaredField("OTHER_WM");
other_wm.setAccessible(true);
if (awt_wmgr.get(null).equals(other_wm.get(null))) {
Field metacity_wm = xwm.getDeclaredField("METACITY_WM");
metacity_wm.setAccessible(true);
awt_wmgr.set(null, metacity_wm.get(null));
}
}
catch (Exception x) {
x.printStackTrace();
}
}
This code snippet is based on a workaround from the Netbeans developers.
I would like to complement the solution given by problemzebra.
As it still happens for me with any swing application on Linux (using Cinnamon desktop), even on Java 6 (update 45)
The issue will reoccur every time I move the window or resize it, so you need to reapply the workaround every time the window changes. I created the following class and use it whenever I create a new window:
class LinuxWindowFix implements WindowStateListener {
private final String desktop;
private Field metacity_wm;
private Field awt_wmgr;
private boolean applyFix;
private static LinuxWindowFix instance = new LinuxWindowFix();
public static LinuxWindowFix getInstance() {
return instance;
}
private LinuxWindowFix() {
applyFix = false;
List<String> linuxDesktops = Arrays.asList("gnome-shell", "mate", "cinnamon"); //add more desktop names here.
desktop = System.getenv("DESKTOP_SESSION");
if (desktop != null && linuxDesktops.contains(desktop.toLowerCase())) {
try {
Class<?> xwm = Class.forName("sun.awt.X11.XWM");
awt_wmgr = xwm.getDeclaredField("awt_wmgr");
awt_wmgr.setAccessible(true);
Field other_wm = xwm.getDeclaredField("OTHER_WM");
other_wm.setAccessible(true);
if (awt_wmgr.get(null).equals(other_wm.get(null))) {
metacity_wm = xwm.getDeclaredField("METACITY_WM");
metacity_wm.setAccessible(true);
applyFix = true;
}
} catch (Exception ex) {
//ignore
}
}
}
#Override
public void windowStateChanged(WindowEvent e) {
try {
awt_wmgr.set(null, metacity_wm.get(null));
} catch (Exception ex) {
//ignore
}
}
public void apply(Window w) {
if (!applyFix) {
return;
}
w.removeWindowStateListener(this);
w.addWindowStateListener(this);
}
}
Simply call this for every window you create and it will work as expected.
LinuxWindowFix.getInstance().apply(myWindow);