Get pressed keys in J2ME with GameCanvas - java-me

I would like to get whether (for example) the 3 key is pressed (KEY_NUM3).
I have tried getKeyStates but it only detects the game action keys.
How could I get the states of non-game action keys?
(I have overridden the keyPressed and keyReleased functions of Canvas and storing the key states in an array (I'm using a Vector for storing but I think could store them in an array too, if that's the problem), but this does not seem to be very nice)

in your keypressed use the keyCode passed in like so
protected void keyPressed(int keyCode)
{
//try catch getGameAction as can legally throw an exception
int gameAction = getGameAction(keyCode);
switch(gameAction)
{
case UP:
break;
case DOWN:
break;
case LEFT:
break;
}
switch(keyCode)
{
case KEY_NUM1:
break;
case KEY_NUM2:
break;
case KEY_NUM3;
break;
}
}

I suppose that can be
something like the code below
int key=getKeyStates();
// i mean keyStates();
if((key&down_pressed)!=0)
{
//do movements
}
but can be
if((key & Canvas.key_num3)!=0)
{
//do something
}
//you can set the super() to true in the constructor

Related

Unity Vuforia Google VR - Can't make onPointerEnter to GameObject change material for itself

I have two 3d buttons in my scene and when I gaze into any of the buttons it will invoke OnPointerEnter callback and saving the object the pointer gazed to.
Upon pressing Fire1 on the Gamepad I apply materials taken from Resources folder.
My problem started when I gazed into the second button, and pressing Fire1 button will awkwardly changed both buttons at the same time.
This is the script I attached to both of the buttons
using UnityEngine;
using UnityEngine.EventSystems;
using Vuforia;
using System.Collections;
public class TriggerMethods : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
{
Material _mat;
GameObject targetObject;
Renderer rend;
int i = 0;
// Update is called once per frame
void Update () {
if (Input.GetButtonDown("Fire1"))
TukarMat();
}
public void OnPointerEnter(PointerEventData eventData)
{
targetObject = ExecuteEvents.GetEventHandler<IPointerEnterHandler>(eventData.pointerEnter);
}
public void OnPointerExit(PointerEventData eventData)
{
targetObject = null;
}
public void TukarMat()
{
Debug.Log("Value i = " + i);
if (i == 0)
{
ApplyTexture(i);
i++;
}
else if (i == 1)
{
ApplyTexture(i);
i++;
}
else if (i == 2)
{
ApplyTexture(i);
i = 0;
}
}
void ApplyTexture(int i)
{
rend = targetObject.GetComponent<Renderer>();
rend.enabled = true;
switch (i)
{
case 0:
_mat = Resources.Load("Balut", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
case 1:
_mat = Resources.Load("Khasiat", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
case 2:
_mat = Resources.Load("Alma", typeof(Material)) as Material;
rend.sharedMaterial = _mat;
break;
default:
break;
}
}
I sensed some logic error and tried making another class to only manage object the pointer gazed to but I was getting more confused.
Hope getting some helps
Thank you
TukarMat() is beeing called on both buttons when you press Fire1. If targetObject is really becoming null this should give an error on first button since it's trying to get component from a null object. Else, it'll change both as you said. Make sure OnPointerExit is beeing called.
Also, it seems you are changing the shared material.
The documentation suggests:
Modifying sharedMaterial will change the appearance of all objects using this material, and change material settings that are stored in the project too.
It is not recommended to modify materials returned by sharedMaterial. If you want to modify the material of a renderer use material instead.
So, try changing the material property instead of sharedMaterial since it'll change the material for that object only.

How to stop onItemSelected() from firing off multiple times after a selection of an item was made?

I've seen another similar thread, but I wasn't able to resolve my issue with the given answers.
EXPLANATION OF MY GOALS:
I have 4 spinners, each has its own ArrayList of strings assigned to it via an adapter. All of these arrays contain the same values at the beginning.
I want to remove the selected value (eg. "item" in spinner1) from all the other spinners (remove "item" from spinner2, 3 and 4) when it is selected.
PROBLEM:
When I select an item for the first two or three times from different spinners (the number of selections needed to reproduce the problem varies) the onItemSelected() method gets called multiple times (the number of callings is greater than the number of actual -user- selections made).
QUESTION:
How to prevent the calling of onItemSelected(); at unnecessary times. I want it to be called only when the actual user makes a selection in one of the spinners and only call it once when that does happen.
If you want to try to help me out and you need more code / images of the problem on the device itself, please, say so.
Here is my whole onItemSelected() method:
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (inCorrection == false)
{
s1 = spinner1.getSelectedItemPosition();
s2 = spinner2.getSelectedItemPosition();
s3 = spinner3.getSelectedItemPosition();
s4 = spinner4.getSelectedItemPosition();
testcount++;
switch(parent.getId())
{
case R.id.v1_q1_s1:
if((position != AdapterView.INVALID_POSITION) && (spinner1.getSelectedItem().toString() != "Default---"))
{
findLists(myList2, myList3, myList4, spinner1.getSelectedItem().toString());
if(returnChecks(0) != "Default---")
{
myList2.add(returnChecks(0));
myList3.add(returnChecks(0));
myList4.add(returnChecks(0));
}
addChecks(0, (spinner1.getSelectedItem().toString()));
}
else
{
if(position != AdapterView.INVALID_POSITION)
{
myList2.add(returnChecks(0));
myList3.add(returnChecks(0));
myList4.add(returnChecks(0));
addChecks(0, (spinner1.getSelectedItem().toString()));
}
}
adapter1.notifyDataSetChanged();
adapter2.notifyDataSetChanged();
adapter3.notifyDataSetChanged();
adapter4.notifyDataSetChanged();
Toast.makeText(Vprasalnik1.this, myList1.toString()+"\n"+myList2.toString()+"\n"+myList3.toString()+"\n"+myList4.toString()+"\n"+checks.toString(), Toast.LENGTH_LONG).show();
break;
case R.id.v1_q1_s2:
if((position != AdapterView.INVALID_POSITION) && (spinner2.getSelectedItem().toString() != "Default---"))
{
findLists(myList1, myList3, myList4, spinner2.getSelectedItem().toString());
if(returnChecks(1) != "Default---")
{
myList1.add(returnChecks(1));
myList3.add(returnChecks(1));
myList4.add(returnChecks(1));
}
addChecks(1, (spinner2.getSelectedItem().toString()));
}
else
{
if(position != AdapterView.INVALID_POSITION)
{
myList1.add(returnChecks(1));
myList3.add(returnChecks(1));
myList4.add(returnChecks(1));
addChecks(1, (spinner2.getSelectedItem().toString()));
}
}
adapter1.notifyDataSetChanged();
adapter2.notifyDataSetChanged();
adapter3.notifyDataSetChanged();
adapter4.notifyDataSetChanged();
Toast.makeText(Vprasalnik1.this, myList1.toString()+"\n"+myList2.toString()+"\n"+myList3.toString()+"\n"+myList4.toString()+"\n"+checks.toString(), Toast.LENGTH_LONG).show();
break;
case R.id.v1_q1_s3:
if((position != AdapterView.INVALID_POSITION) && (spinner3.getSelectedItem().toString() != "Default---"))
{
findLists(myList2, myList1, myList4, spinner3.getSelectedItem().toString());
if(returnChecks(2) != "Default---")
{
myList2.add(returnChecks(2));
myList1.add(returnChecks(2));
myList4.add(returnChecks(2));
Toast.makeText(Vprasalnik1.this, "before: "+returnChecks(2), Toast.LENGTH_LONG).show();
}
addChecks(2, (spinner3.getSelectedItem().toString()));
Toast.makeText(Vprasalnik1.this, "after: "+returnChecks(2), Toast.LENGTH_LONG).show();
}
else
{
if(position != AdapterView.INVALID_POSITION)
{
myList2.add(returnChecks(2));
myList1.add(returnChecks(2));
myList4.add(returnChecks(2));
addChecks(2, (spinner3.getSelectedItem().toString()));
}
}
adapter1.notifyDataSetChanged();
adapter2.notifyDataSetChanged();
adapter3.notifyDataSetChanged();
adapter4.notifyDataSetChanged();
Toast.makeText(Vprasalnik1.this, myList1.toString()+"\n"+myList2.toString()+"\n"+myList3.toString()+"\n"+myList4.toString()+"\n"+checks.toString(), Toast.LENGTH_LONG).show();
break;
case R.id.v1_q1_s4:
if((position != AdapterView.INVALID_POSITION) && (spinner4.getSelectedItem().toString() != "Default---"))
{
findLists(myList2, myList3, myList1, spinner4.getSelectedItem().toString());
if(returnChecks(3) != "Default---")
{
myList2.add(returnChecks(3));
myList3.add(returnChecks(3));
myList1.add(returnChecks(3));
}
addChecks(3, (spinner4.getSelectedItem().toString()));
}
else
{
if(position != AdapterView.INVALID_POSITION)
{
myList2.add(returnChecks(3));
myList3.add(returnChecks(3));
myList1.add(returnChecks(3));
addChecks(3, (spinner4.getSelectedItem().toString()));
}
}
adapter1.notifyDataSetChanged();
adapter2.notifyDataSetChanged();
adapter3.notifyDataSetChanged();
adapter4.notifyDataSetChanged();
Toast.makeText(Vprasalnik1.this, myList1.toString()+"\n"+myList2.toString()+"\n"+myList3.toString()+"\n"+myList4.toString()+"\n"+checks.toString(), Toast.LENGTH_LONG).show();
break;
}
correctSelection();
}
}
At the end of the above code there is a function I call named correctSelection();, that corrects the selection of all spinners, because it doesn't work correctly otherwise - it looks like this:
void correctSelection()
{
inCorrection = true;
spinner1.setSelection(myList1.lastIndexOf(returnChecks(0)));
spinner2.setSelection(myList2.lastIndexOf(returnChecks(1)));
spinner3.setSelection(myList3.lastIndexOf(returnChecks(2)));
spinner4.setSelection(myList4.lastIndexOf(returnChecks(3)));
inCorrection = false;
}
/*it sets the position of all spinners to the last "saved"
(current) item selected, so it corrects the possible index offset that occurs otherwise
(returnChecks(); returns the last item selected from an array in a string format)
PS: To avoid the calling of onItemSelected() in case of programmatically setting the selection
of spinners, I've input a boolean flag (variable "inCorrection"), which is set to false before the
selections are made by "the application" and then set back to false when the code gets run.
*/
To prevent onItemSelected() from being called when you set up the spinner, you can do it like this:
spinner.setOnItemSelectedListener(null);
adapter.notifyDatasetChanged();
spinner.setSelection(0, false);
spinner.setOnItemSelectedListener(onItemSelectedListener);
Explanation:
The framework fires the onItemSelected event when a change in the selection has occurred. It detects a change by registering the current selected position and the previous selected position (mSelectedPostion and mOldSelectedPosition).
When you call notifyDatasetChanged the framework performs various checks to see if the previous selection can be found, so onItemSelected may or may not be called when the spinner is laid out.
By calling setSelection(0, false) these positions are set to 0, possibly detecting a change, but since onItemSelectedListener is null, onItemSelected wont be fired. Position 0 is selected because I guess the "Default---" value is the first position in the list. You can choose another position if you like.
When the spinner is later laid out there is no change, so onItemSelected wont be fired here either.
Note that this has been established by debugging on API level 19 (Android 4.4 KitKat). I don't know if it works on other versions, and I haven't been able to find anything in the documentation to support it.
You can stop the spinner from firing prior to the user making a selection via the optional animation field in the setSelection method. Be sure to order your code this way:
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, yourList);
spinner.setAdapter(spinnerAdapter);
spinner.setSelection(0, false); //stops spinner from firing prior to user selection
as explained by user1801374 , I made the fix for my case. Just make sure before and after selection index remains same in order to not to invoke the onItemSelected again.
private int spinnerIndex = 0;
spinner.setSelection(spinnerIndex, false);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{ public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
// Your code here
//I was detaching and reattaching one fragment which was calling the onItemSelected multiple times, recursively.
spinnerIndex = i;
spinner.setSelection(spinnerIndex, false);
return;
}
public void onNothingSelected(AdapterView<?> adapterView) {
// Your code here
return;
}
}

ClassCastException with handleMessage

Debugging bit of code for bluetooth connection receive string etc. However, seem to be getting a ClassCastException at the line of code
String read_Message = (String) msg.obj;
But if I was to use my previous bit of code and collect the bytes and place into a string runs but doesn't collect all the data in one string.
Have I not cast something or missed something cause I know I'm missing something but can't see it.
If any more code is required I will place up, everything else is working
Thanks for any help
// The Handler that gets information back from the BluetoothService
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case MESSAGE_STATE_CHANGE:
// if (D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1)
{
case BluetoothService.STATE_CONNECTED:
break;
case BluetoothService.STATE_CONNECTING:
//mTitle.setText(R.string.title_connecting);
break;
case BluetoothService.STATE_LISTEN:
case BluetoothService.STATE_NONE:
//mTitle.setText(R.string.title_not_connected);
break;
}
break;
case MESSAGE_WRITE:
//code to be entered here
break;
case MESSAGE_READ:
//Previous code
//byte[] read_Buf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
//String read_Message = new String(read_Buf, 0, msg.arg1);
String read_Message = (String) msg.obj;
if (mSmokeReadingArrayAdapter.isEmpty())
mSmokeReadingArrayAdapter.add("");
mAdapter_Text.set(0, mAdapter_Text.get(0).toString() + read_Message);
mSmokeReadingArrayAdapter.notifyDataSetChanged();
organiseString(read_Message);
break;
case MESSAGE_DEVICE_NAME:
//code to be entered here
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show(); // shows 'alert' messages
break;
}
}
};
Problem solved. It wa to do with the bluetooth service code that had been defined as a byte array rather than string

function return values c#

I am trying to get to grips with C# having not coded for many years and my previous experience being in ANSI C.
I have read a number of books and searched online but one aspect is evading me and I am hoping someone here can help.
In the past I would declare a function and if there was a possibility of something not happening within the function (i.e. file not found etc.) declare the return to be an integer. I would then return 0 if all was well and a value if not. The value would correspond to where the function failed to execute fully and I could branch accordingly from where I called it.
if(function1())
{
// all my error stuff, maybe a switch/case etc.
}
All the examples I have found in C# seem to avoid this technique and I was hoping to get some understanding here.
Thanks in anticipation.
(I know I am a fossil). :)
Exceptions are the approach you use in C# and similar languages.
It goes like this:
try
{
function();
}
catch(FileNotFoundException e)
{
// File not found
}
catch(UnauthorizedAccessException e)
{
// User doesn't have right to access file
}
// etc...
To make this work, function shouldn't return a status code but instead throw an exception in case of an error.
Please note that the exceptions I illustrated in the code block above are thrown by the framework if you try to access a file and one of those errors is happening. So you don't actually have to do this yourself.
Furthermore, in C# there is no implicit conversion from integral values to bool, i.e. if(function()) is invalid, if function returns an int. You would need to write it like this:
if(function() != 0)
{
// all your error stuff
}
There's nothing to stop you doing this (though there are better ways of handling the errors - exceptions for example).
If you do want to carry on with this approach, the biggest problem you are having is that in C# you can't treat an integer as a boolean so your if test won't compile. What you need is:
if (function1() != 0)
{
}
But to check the value you'd need:
int result = function1();
switch (result)
{
case 1:
// Handle this case
break;
case 2:
// Handle this case
break;
default:
// All OK
break;
}
It would be better to return an enumerated type for each error case so that you don't have magic numbers, but exceptions are the way to go:
try
{
function1();
}
catch (SpecificException1 e1)
{
// Handle this case
}
catch (SpecificException2 e2)
{
// Handle this case
}
What you shouldn't have is a general exception handler:
catch (Exception e)
{
}
This just hides other potential problems.
If you want to follow that pattern of checking return value instead of managing errors, you better use enumarations than plain numbers.
For example:
public enum ResultType
{
Error = 0,
Success,
Waiting
}
public ResultType function()
{
if (still_waiting)
return ResultType.Waiting;
if (error_has_occured)
return ResultType.Error;
return ResultType.Success;
}
public void Main()
{
ResultType result = function();
switch (result)
{
case ResultType.Success:
MessageBox.Show("all is good");
break;
case ResultType.Waiting:
MessageBox.Show("still waiting...");
break;
case ResultType.Error:
MessageBox.Show("error has occurred");
break;
}
}
Behind the scenes, it's still using numbers but you put some meaning to each number.
if(function()==1)
{
}
int function()
{
int returnVal =0;
// do stuff
// if true return returnVal =1 else set returnVal =0;
return returnVal;
}

Event when a particular Slider is changed

I am writing a C++ MFC Dialog based Application and my program has lots of sliders. I want the program to call a function depending on which Slider is being changed by the user. I tried using GetPos() but not much success so far. Any easier way of doing this?
Message Map:
BEGIN_MESSAGE_MAP(CSerialPortDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
//ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
ON_BN_CLICKED(IDC_READ_COMM, OnBnClickedReadComm)
ON_WM_CLOSE()
ON_BN_CLICKED(IDC_WRITE, OnBnClickedWrite)
//ON_CBN_SELCHANGE(IDC_SENSORS, OnCbnSelchangeSensors)
//ON_CBN_SELCHANGE(IDC_SENSOR_LIST, OnCbnSelchangeSensorList)
ON_BN_CLICKED(IDC_GO, OnGo)
ON_WM_TIMER()
ON_BN_CLICKED(IDC_KILL_TIMER, OnBnClickedKillTimer)
ON_BN_CLICKED(IDC_READ_TIMER, OnBnClickedReadTimer)
ON_BN_CLICKED(IDC_WRITE_COMM, OnBnClickedWriteComm)
ON_BN_CLICKED(IDC_TERMINATE, OnBnClickedTerminate)
ON_BN_CLICKED(IDC_RUN, OnBnClickedRun)
ON_CONTROL(NM_CLICK,IDC_BOOM_SLIDER, Write_Boom)
ON_CONTROL(NM_CLICK,IDC_PITCH_SLIDER, Write_Pitch)
END_MESSAGE_MAP()
...
Slider controls send WM_HSCROLL or WM_VSCROLL notifications when they are scrolled, horizontally or vertically. Catch them in your dialog and there you can call your desired function, depending on who sent the notification.
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//...
ON_WM_HSCROLL()
//...
END_MESSAGE_MAP()
//////////////////////////
// nSBCode: The operation performed on the slider
// nPos: New position of the slider
// pScrollBar: The scrollbar (slider ctrl in this case) that sent the notification
void CMyDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CSliderCtrl* pSlider = reinterpret_cast<CSliderCtrl*>(pScrollBar);
// Check which slider sent the notification
if (pSlider == &c_Slider1)
{
}
else if (pSlider == &c_Slider2)
{
}
// Check what happened
switch(nSBCode)
{
case TB_LINEUP:
case TB_LINEDOWN:
case TB_PAGEUP:
case TB_PAGEDOWN:
case TB_THUMBPOSITION:
case TB_TOP:
case TB_BOTTOM:
case TB_THUMBTRACK:
case TB_ENDTRACK:
default:
break;
}
//...
}
`
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//...
ON_WM_HSCROLL()
//...
END_MESSAGE_MAP()
void CMyDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
CSliderCtrl *ACSliderCtrl = (CSliderCtrl *)pScrollBar;
int nID = ACSliderCtrl->GetDlgCtrlID();
int NewPos = ((CSliderCtrl *)pScrollBar)->GetPos();
CWnd *ACWnd = GetDlgItem(nID);
switch (nID)
{
default:
break;
case IDC_SLIDER1:
m_edit1.Format( "%d", NewPos );
UpdateData(FALSE);
break;
}
CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}
I figured it out, I think. What you call a slider is commonly called a "Scrollbar". You're probably looking for the WM_VSCROLL message. As noted there, "lParam: If the message is sent by a scroll bar, this parameter is the handle to the scroll bar control."
See also CWnd::OnVScroll
You do have different ON_CONTROL macro's for the different controls? Because it's then just a matter of specifying different methods as the third argument to ON_CONTROL

Resources