I am working on a pause key in my little school project, but for some reason it refuses to work. Using this code :
public void keyTyped(KeyEvent me) { //ESCAPE PLS WORK ...
code = me.getKeyCode();
System.out.println(code);
}
For some reason "code" always stays zero. I tried to put it in different voids(pressed/released etc), but it still does not work. What could be the reason?
Here's what the javadoc says about getKeyCode()
Returns: the integer code for an actual key on the keyboard. (For KEY_TYPED events, the keyCode is VK_UNDEFINED.)
And the value of VK_UNDEFINED is zero.
The javadoc also says:
public static final int KEY_TYPED
The "key typed" event. This event is generated when a character is entered. In the simplest case, it is produced by a single key press. Often, however, characters are produced by series of key presses, and the mapping from key pressed events to key typed events may be many-to-one or many-to-many.
So maybe you are looking at the wrong kind of key events. Maybe should be looking at the KEY_PRESSED or KEY_RELEASED events rather than the KEY_TYPED events.
Why not try the keyPressed() method again as in the example below:
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
switch( code ) {
case KeyEvent.VK_UP:
// handle up
System.out.println(code);
break;
case KeyEvent.VK_DOWN:
// handle down
break;
case KeyEvent.VK_LEFT:
// handle left
break;
case KeyEvent.VK_RIGHT :
// handle right
break;
}
}
Note that you must expect an integer.
I have a variable, x.
I want to call a method m() only if x is one of two possible values.
When calling m(), I want to pass an argument to it, whose value depends on the value of x.
Is there a way to do this in Java without checking the value of x more than once, and calling/writing m() in one place only (i.e. not in multiple branches of an if statement)?
One solution I'm entertaining:
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
y = null;
break;
}
if (y != null) m(y);
But I can't help but feel this is technically checking x twice, just obscuring this fact by adding a "proxy" for the second check.
(To clarify why the constraints are what they are: when reading code, I have a hard time understanding logic that branches a lot when there is a high degree of duplication between branches - it becomes a game of "spot the difference" rather than simply being able to see what is happening. I prefer to aggressively refactor such duplication away, which is a habit that serves me well in Ruby, JS, and other languages; I'm hoping I can learn to do the same for Java and make code easier for me and others to understand at a glance.)
I'm not sure of what you want to do, but you can maybe use a Map to get the 'y' parameter from 'x'
Map<Integer, String> map = new HashMap<>();
map.put(1, "foo");
map.put(2, "bar");
if (map.containsKey(x)) {
m(map.get(x));
}
Use "goto" or equivalent:
void do_m_if_appropriate() {
// x and y are assumed to be eg. member variables
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
return; // this is the "goto equivalent" part
}
m(y);
}
Above is pretty elegant. If necessary, it's also trivial to change it to return true or false depending on if it called m(), or just y or null.
You can also do tricks with loop constructs, though some might say this is abuse of the loop construct, and you should comment it accordingly:
do { // note: not a real loop, used to skip call to m()
switch (x) {
case 1:
y = "foo";
break;
case 2:
y = "bar";
break;
default:
continue; // "goto equivalent" part
}
m(y);
} while(false);
Here's a solution with Optionals (my Java syntax might be slightly incorrect). Note that to you, the code looks like so, but implementation wise, it's similar to the example you posted (i.e. checks whether y is an exceptional value).
switch (x) {
case 1:
y = Optional<String>.of("foo");
break;
case 2:
y = Optional<String>.of("bar");
break;
default:
y = Optional<String>.empty();
break;
}
y.map((m's class)::m);
result = y.orElse( <value result should take if x was invalid> );
Actually it may be better to modify m() to return an Optional and just return empty if y is not valid, but I assume you want to do this check caller-side.
Why not
switch (x) {
case 1:
y = "foo";
m(y);
break;
case 2:
y = "bar";
m(y);
break;
}
I implemented my own custom keyboard for an application that simply maps buttons with text to a key, then sends it to the EditText.
When a button is pressed, I eventually call this method, passing in the EditText to add the character to, and the character to append.
public void keypadPress(EditText etInput, char character) {
etInput.dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, getKeyEvent(character)));
}
getKeyEvent looks like this:
public static int getKeyEvent(char c) {
switch (c) {
case '0':
return KeyEvent.KEYCODE_0;
case '1':
return KeyEvent.KEYCODE_1;
case '2':
return KeyEvent.KEYCODE_2;
case '3':
return KeyEvent.KEYCODE_3;
case '4':
return KeyEvent.KEYCODE_4;
case '5':
return KeyEvent.KEYCODE_5;
case '6':
return KeyEvent.KEYCODE_6;
case '7':
return KeyEvent.KEYCODE_7;
case '8':
return KeyEvent.KEYCODE_8;
case '9':
return KeyEvent.KEYCODE_9;
case '-':
return KeyEvent.KEYCODE_MINUS;
case '.':
return KeyEvent.KEYCODE_PERIOD;
case ',':
return KeyEvent.KEYCODE_COMMA;
case 'x':
return KeyEvent.KEYCODE_X;
default:
return -1;
}
}
The EditText type input is set to 'number'. Also, this works completely perfect in Android 4.0+, however whenever I click my 'x' button, it will get mapped to an '8' on API 8 (and maybe below). I've debugged it, and it returns KeyEvent.KEYCODE_X (or 52), but what shows up in the EditText is the number 8. I am completely clueless and would appreciate any form of help.
Also, the first time that I open the screen with this keypad implementation, whenever I click a button for the first time, I get this warning...
10-04 01:16:29.804: W/KeyCharacterMap(8716): Can't open keycharmap file
10-04 01:16:29.804: W/KeyCharacterMap(8716): Error loading keycharmap file '/system/usr/keychars/touchscreen-keypad.kcm.bin'. hw.keyboards.0.devname='touchscreen-keypad'
10-04 01:16:29.804: W/KeyCharacterMap(8716): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
and then after that it's warning free.
Found the Answer:
I also have the digits property set to "0123456789,.-x" which, even though I tried changing inputType to "text", causes it to map KEYCODE_X to '8'. If the editText has either inputType number, or the digits property set, keycodes that aren't numbers will end up incorrect even if you manually dispatch the event. This only happens on API 8 and below as far as I can tell. On Android 4.0+, you can allow letters even though the inputType is "number".
I've created a terminal emulator using a library, connect to a serial device with another library and this returns data to my terminal. I can see in the log that every time I write a character in the terminal and sent it over serial, the following three characters are returned along with the correct one. ☐[J. When writing to the terminal these characters do now show up. They are handled in this code in some way but I'm not sure which part, perhaps doEscRightSquareBracket:
private void process(byte b, boolean doUTF8) {
// Let the UTF-8 decoder try to handle it if we're in UTF-8 mode
if (doUTF8 && mUTF8Mode && handleUTF8Sequence(b)) {
return;
}
// Handle C1 control characters
if ((b & 0x80) == 0x80 && (b & 0x7f) <= 0x1f) {
/* ESC ((code & 0x7f) + 0x40) is the two-byte escape sequence
corresponding to a particular C1 code */
process((byte) 27, false);
process((byte) ((b & 0x7f) + 0x40), false);
return;
}
switch (b) {
case 0: // NUL
// Do nothing
break;
case 7: // BEL
/* If in an OSC sequence, BEL may terminate a string; otherwise do
* nothing */
if (mEscapeState == ESC_RIGHT_SQUARE_BRACKET) {
doEscRightSquareBracket(b);
}
break;
case 8: // BS
setCursorCol(Math.max(0, mCursorCol - 1));
break;
case 9: // HT
// Move to next tab stop, but not past edge of screen
setCursorCol(nextTabStop(mCursorCol));
break;
case 13:
setCursorCol(0);
break;
case 10: // CR
case 11: // VT
case 12: // LF
doLinefeed();
break;
case 14: // SO:
setAltCharSet(true);
break;
case 15: // SI:
setAltCharSet(false);
break;
case 24: // CAN
case 26: // SUB
if (mEscapeState != ESC_NONE) {
mEscapeState = ESC_NONE;
emit((byte) 127);
}
break;
case 27: // ESC
// Starts an escape sequence unless we're parsing a string
if (mEscapeState != ESC_RIGHT_SQUARE_BRACKET) {
startEscapeSequence(ESC);
} else {
doEscRightSquareBracket(b);
}
break;
default:
mContinueSequence = false;
switch (mEscapeState) {
case ESC_NONE:
if (b >= 32) {
emit(b);
}
break;
case ESC:
doEsc(b);
break;
case ESC_POUND:
doEscPound(b);
break;
case ESC_SELECT_LEFT_PAREN:
doEscSelectLeftParen(b);
break;
case ESC_SELECT_RIGHT_PAREN:
doEscSelectRightParen(b);
break;
case ESC_LEFT_SQUARE_BRACKET:
doEscLeftSquareBracket(b); // CSI
break;
case ESC_LEFT_SQUARE_BRACKET_QUESTION_MARK:
doEscLSBQuest(b); // CSI ?
break;
case ESC_PERCENT:
doEscPercent(b);
break;
case ESC_RIGHT_SQUARE_BRACKET:
doEscRightSquareBracket(b);
break;
case ESC_RIGHT_SQUARE_BRACKET_ESC:
doEscRightSquareBracketEsc(b);
break;
default:
unknownSequence(b);
break;
}
if (!mContinueSequence) {
mEscapeState = ESC_NONE;
}
break;
}
}
This is not a problem with the terminal as it is filtering it. But now I want to write the returned data into an editText and the odd characters are being written. What are they, how do I stop them? They must be some normal case of something that can happen as the terminal filters them out? You can see it here when I am typing exit and it should be mirrored on the right:
Esc-[-J is an ANSI escape code, it instructs the terminal to clear the screen from the cursor down. The problem with filtering them out is that among these commands many change how the visible text is constructed: they can move the cursor, erase parts, etc. So, just filtering them out may not give the desired result. But in this case it just seems like a precaution to make sure that the area where you normally type is cleared.
What I consider the best solution, but quite probably overkill in your case, is to integrate a VT100 interpreter in your program (for example this one) that converts a stream of text and command codes into a memory view of the screen, and save that memory. It will be a perfect representation of what the sending program would like to see on the screen at any time.
Why doesn't the compiler automatically put break statements after each code block in the switch? Is it for historical reasons? When would you want multiple code blocks to execute?
Sometimes it is helpful to have multiple cases associated with the same code block, such as
case 'A':
case 'B':
case 'C':
doSomething();
break;
case 'D':
case 'E':
doSomethingElse();
break;
etc. Just an example.
In my experience, usually it is bad style to "fall through" and have multiple blocks of code execute for one case, but there may be uses for it in some situations.
Historically, it's because the case was essentially defining a label, also known as the target point of a goto call. The switch statement and its associated cases really just represent a multiway branch with multiple potential entry points into a stream of code.
All that said, it has been noted a nearly infinite number of times that break is almost always the default behavior that you'd rather have at the end of every case.
Java comes from C and that is the syntax from C.
There are times where you want multiple case statements to just have one execution path.
Below is a sample that will tell you how many days in a month.
class SwitchDemo2 {
public static void main(String[] args) {
int month = 2;
int year = 2000;
int numDays = 0;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
numDays = 31;
break;
case 4:
case 6:
case 9:
case 11:
numDays = 30;
break;
case 2:
if ( ((year % 4 == 0) && !(year % 100 == 0))
|| (year % 400 == 0) )
numDays = 29;
else
numDays = 28;
break;
default:
System.out.println("Invalid month.");
break;
}
System.out.println("Number of Days = " + numDays);
}
}
I think it is a mistake. As a language construct it is just as easy to have break as the default and instead have a fallthrough keyword. Most of the code I have written and read has a break after every case.
You can do all sorts of interesting things with case fall-through.
For example, lets say you want to do a particular action for all cases, but in a certain case you want to do that action plus something else. Using a switch statement with fall-through would make it quite easy.
switch (someValue)
{
case extendedActionValue:
// do extended action here, falls through to normal action
case normalActionValue:
case otherNormalActionValue:
// do normal action here
break;
}
Of course, it is easy to forget the break statement at the end of a case and cause unexpected behavior. Good compilers will warn you when you omit the break statement.
Why doesn't the compiler automatically put break statements after each code block in the switch?
Leaving aside the good desire to be able to use the identical block for several cases (which could be special-cased)...
Is it for historical reasons? When would you want multiple code blocks to execute?
It's mainly for compatibility with C, and is arguably an ancient hack from the days of old when goto keywords roamed the earth. It does enable some amazing things, of course, such as Duff's Device, but whether that's a point in its favor or against is… argumentative at best.
The break after switch cases is used to avoid the fallthrough in the switch statements. Though interestingly this now can be achieved through the newly formed switch labels as implemented via JEP-325.
With these changes, the break with every switch case can be avoided as demonstrated further :-
public class SwitchExpressionsNoFallThrough {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int value = scanner.nextInt();
/*
* Before JEP-325
*/
switch (value) {
case 1:
System.out.println("one");
case 2:
System.out.println("two");
default:
System.out.println("many");
}
/*
* After JEP-325
*/
switch (value) {
case 1 ->System.out.println("one");
case 2 ->System.out.println("two");
default ->System.out.println("many");
}
}
}
On executing the above code with JDK-12, the comparative output could be seen as
//input
1
// output from the implementation before JEP-325
one
two
many
// output from the implementation after JEP-325
one
and
//input
2
// output from the implementation before JEP-325
two
many
// output from the implementation after JEP-325
two
and of course the thing unchanged
// input
3
many // default case match
many // branches to 'default' as well
So you do not have to repeat code if you need several cases to do the same thing:
case THIS:
case THAT:
{
code;
break;
}
Or you can do things like :
case THIS:
{
do this;
}
case THAT:
{
do that;
}
In a cascade fashion.
Really bug/confusion prone, if you ask me.
As far as the historical record goes, Tony Hoare invented the case statement in the 1960s, during the "structured programming" revolution. Tony's case statement supported multiple labels per case and automatic exit with no stinking break statements. The requirement for an explicit break was something that came out of the BCPL/B/C line. Dennis Ritchie writes (in ACM HOPL-II):
For example, the endcase that escapes from a BCPL switchon statement was not present in the language
when we learned it in the 1960s, and so the overloading of the break keyword to escape
from the B and C switch statement owes to divergent evolution rather than conscious change.
I haven't been able to find any historical writings about BCPL, but Ritchie's comment suggests that the break was more or less a historical accident. BCPL later fixed the problem, but perhaps Ritchie and Thompson were too busy inventing Unix to be bothered with such a detail :-)
Java is derived from C, whose heritage includes a technique known as Duff's Device .
It's an optimization that relies on the fact that control falls through from one case to the next, in the absence of a break; statement. By the time C was standardized, there was plenty of code like that "in the wild", and it would have been counterproductive to change the language to break such constructions.
As people said before, it is to allow fall-through and it is not a mistake, it is a feature.
If too many break statements annoy you, you can easily get rid of them by using return statements instead. This is actually a good practice, because your methods should be as small as possible (for the sake of readability and maintainability), so a switch statement is already big enough for a method, hence, a good method should not contain anything else, this is an example:
public class SwitchTester{
private static final Log log = LogFactory.getLog(SwitchTester.class);
public static void main(String[] args){
log.info(monthsOfTheSeason(Season.WINTER));
log.info(monthsOfTheSeason(Season.SPRING));
log.info(monthsOfTheSeason(Season.SUMMER));
log.info(monthsOfTheSeason(Season.AUTUMN));
}
enum Season{WINTER, SPRING, SUMMER, AUTUMN};
static String monthsOfTheSeason(Season season){
switch(season){
case WINTER:
return "Dec, Jan, Feb";
case SPRING:
return "Mar, Apr, May";
case SUMMER:
return "Jun, Jul, Aug";
case AUTUMN:
return "Sep, Oct, Nov";
default:
//actually a NullPointerException will be thrown before reaching this
throw new IllegalArgumentException("Season must not be null");
}
}
}
The execution prints:
12:37:25.760 [main] INFO lang.SwitchTester - Dec, Jan, Feb
12:37:25.762 [main] INFO lang.SwitchTester - Mar, Apr, May
12:37:25.762 [main] INFO lang.SwitchTester - Jun, Jul, Aug
12:37:25.762 [main] INFO lang.SwitchTester - Sep, Oct, Nov
as expected.
It is an old question but actually I ran into using the case without break statement today. Not using break is actually very useful when you need to combine different functions in sequence.
e.g. using http response codes to authenticate user with time token
server response code 401 - token is outdated -> regenerate token and log user in.
server response code 200 - token is OK -> log user in.
in case statements:
case 404:
case 500:
{
Log.v("Server responses","Unable to respond due to server error");
break;
}
case 401:
{
//regenerate token
}
case 200:
{
// log in user
break;
}
Using this you do not need to call log in user function for 401 response because when the token is regenerated, the runtime jumps into the case 200.
Not having an automatic break added by the compiler makes it possible to use a switch/case to test for conditions like 1 <= a <= 3 by removing the break statement from 1 and 2.
switch(a) {
case 1: //I'm between 1 and 3
case 2: //I'm between 1 and 3
case 3: //I'm between 1 and 3
break;
}
because there are situations where you want to flow through the first block for example to avoid writing the same code in multiple blocks but still be able to divide them for mroe control. There are also a ton of other reasons.
You can makes easily to separate other type of number, month, count.
This is better then if in this case;
public static void spanishNumbers(String span){
span = span.toLowerCase().replace(" ", "");
switch (span){
case "1":
case "jan": System.out.println("uno"); break;
case "2":
case "feb": System.out.println("dos"); break;
case "3":
case "mar": System.out.println("tres"); break;
case "4":
case "apr": System.out.println("cuatro"); break;
case "5":
case "may": System.out.println("cinco"); break;
case "6":
case "jun": System.out.println("seis"); break;
case "7":
case "jul": System.out.println("seite"); break;
case "8":
case "aug": System.out.println("ocho"); break;
case "9":
case "sep": System.out.println("nueve"); break;
case "10":
case "oct": System.out.println("diez"); break;
}
}
I am now working on project where I am in need of break in my switch statement otherwise the code won't work. Bear with me and I will give you a good example of why you need break in your switch statement.
Imagine you have three states, one that waits for the user to enter a number, the second to calculate it and the third to print the sum.
In that case you have:
State1 - Wait for user to enter a number
State2 - Print the sum
state3 - Calculate the sum
Looking at the states, you would want the order of exaction to start on state1, then state3 and finally state2. Otherwise we will only print users input without calculating the sum. Just to clarify it again, we wait for the user to enter a value, then calculate the sum and prints the sum.
Here is an example code:
while(1){
switch(state){
case state1:
// Wait for user input code
state = state3; // Jump to state3
break;
case state2:
//Print the sum code
state = state3; // Jump to state3;
case state3:
// Calculate the sum code
state = wait; // Jump to state1
break;
}
}
If we don't use break, it will execute in this order, state1, state2 and state3. But using break, we avoid this scenario, and can order in the right procedure which is to begin with state1, then state3 and last but not least state2.
Exactly, because with some clever placement you can execute blocks in cascade.