So, to give a bit of context, I finally got tired of having to research for the ALT codes of certain symbols and sub/superscript numbers, and never getting it right, I suppose this mapping error have something to do with de keyboard version I'm using, but to be honest, I don't care, and to solve this problem I created a program in Java that will print all the alt codes going from Alt0000 to Alt9999 on a separate notepad window via keyPress but, I'm having problems on printing all of them, somehow it erases the text multiple times during the run, and after a while it starts printing nonsensical things.
As requested in a comment bellow, here's a print of the nonsensical things:
Nonsensical Things
And for adding more details, the program runs fine for the first 100-ish codes, them it erases some of the codes and run fine until de 6000-ish codes, which is where it starts printing only the pre texts that indicate the codes and don't breaking any lines, a further more down the line it also erases the progress, and keeps with de "nonsensical things" as I am calling it.
If someone could give me some tips on how to do/fix this I would very much appreciate.
Since I'm not an expert programmer I'm also accepting tips on how to improve my code.
Thanks. :)
This is my code:
package randomProjects;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.*;
public class SimulateKeyPress {
public static void main(String[] args) throws InterruptedException {
int[] keyEvents = {KeyEvent.VK_NUMPAD0,
KeyEvent.VK_NUMPAD1,
KeyEvent.VK_NUMPAD2,
KeyEvent.VK_NUMPAD3,
KeyEvent.VK_NUMPAD4,
KeyEvent.VK_NUMPAD5,
KeyEvent.VK_NUMPAD6,
KeyEvent.VK_NUMPAD7,
KeyEvent.VK_NUMPAD8,
KeyEvent.VK_NUMPAD9};
try {
Robot robot = new Robot();
// click on notepad window positioned at the rigth of the IDE
robot.mouseMove(1000,400);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
// run trhought the thousand units
for(int um = 0; um <= 9; um++) {
// run trhought the hundreds
for(int c = 0; c <= 9; c++) {
// run trhought the dozens
for(int d = 0; d <= 9; d++) {
// run trhought the units
for(int u = 0; u <= 9; u++) {
// write the pressed keys
// alt+####
robot.keyPress(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_A);
robot.keyPress(KeyEvent.VK_L);
robot.keyRelease(KeyEvent.VK_L);
robot.keyPress(KeyEvent.VK_T);
robot.keyRelease(KeyEvent.VK_T);
robot.keyPress(KeyEvent.VK_ADD);
robot.keyRelease(KeyEvent.VK_ADD);
robot.keyPress(keyEvents[um]);
robot.keyRelease(keyEvents[um]);
robot.keyPress(keyEvents[c]);
robot.keyRelease(keyEvents[c]);
robot.keyPress(keyEvents[d]);
robot.keyRelease(keyEvents[d]);
robot.keyPress(keyEvents[u]);
robot.keyRelease(keyEvents[d]);
robot.keyPress(KeyEvent.VK_TAB);
// write the respective ALT CODE result
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(keyEvents[um]);
robot.keyPress(keyEvents[c]);
robot.keyPress(keyEvents[d]);
robot.keyPress(keyEvents[u]);
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(keyEvents[um]);
robot.keyRelease(keyEvents[c]);
robot.keyRelease(keyEvents[d]);
robot.keyRelease(keyEvents[u]);
// Break line
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
//Thread.sleep(100);
}
}
}
}
} catch (AWTException e) {
e.printStackTrace();
}
}
}
I've also found this related queries, but had no luck in finding an answer to my problem:
ALT-Codes in Java
How to detect Windows alt-code input without relying on keypress?
How to simulate keyboard presses in java?
Related
I'm trying to create a simple sequence that basically consists on a JLabel's text being set to a value using an array and a for cycle. However it waits a certain time, before it changes.
My code looks something like this:
private String[] images = {"ball_00.bmp",
"ball_01.bmp",
"ball_02.bmp",
"ball_03.bmp",
"ball_04.bmp",
"ball_05.bmp",
"ball_06.bmp",
"ball_07.bmp",
"ball_08.bmp",
"ball_09.bmp",
"ball_10.bmp"};
public void runGif(){
for(int x = 0; x < this.images.length; x++) {
try {
System.out.println(images[x]);
this.lbl_image.setText(images[x]);
this.panel_CENTER.add(lbl_image);
this.lbl_image.setVisible(false);
this.lbl_image.setVisible(true);
System.out.println("I'm waiting");
Thread.sleep(CurrentSpeed);
System.out.println("I'm back");
}
catch(Exception e) {e.getStackTrace();}
System.out.println(x);
}
}
However I'm getting no output and the only thing I see on my JFrame is the label displaying "GIF", which is the default text that I set it to.
I don't know what migth be causing this issue, and would be very grateful if someone could help me.
Thank you for your attention in advance!
I'm trying to write a logic in memory game that when I click on cards and they are not a pair (different ID), program should swap them back after 1s. If they are same, then leave them as they are.
The problem is that when I first click and the card appears, after second clicking on another (different) card it doesn't appear and swap the first card after 1s. someone knows why the second card does not appear after clicking?
Btw when the pair is correct, everything works fine, here is my fragment of the code responsible for that logic in listener:
final int copy = i;
card2.addActionListener((e) -> {
card2.setIcon(new ImageIcon(icons[copy].getAbsolutePath()));
if(firstClick == null)
{
firstClick = (Card)e.getSource();
}
else
{
Card secondClick = (Card)e.getSource();
if(firstClick.getID() != secondClick.getID())
{
try
{
Thread.sleep(1000);
} catch (InterruptedException e1)
{
//e1.printStackTrace();
}
firstClick.setIcon(new ImageIcon(background.getAbsolutePath()));
secondClick.setIcon(new ImageIcon(background.getAbsolutePath()));
firstClick = null;
}
else
firstClick = null;
}
});
While method actionPerformed is executing, the GUI cannot react to mouse and keyboard events, so basically your code is "freezing" your GUI for one second. I believe that the class javax.swing.Timer is what you need and at first glance it looks like the duplicate question that MadProgrammer referred to may help you.
I am trying to make a NXT Robot that has attached the Ultrasonic Sensor. It has to drive until the distance is 15, and then the engines have to stop. After it stops it has to turn, but it doesn't work.
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
for (int i = 0; i < 5; i++) {
try {
Motor.B.rotate(-1500 , true);
Motor.C.rotate(-1500 , true);
} catch (Exception E){}
while ( ultra.getDistance() < 15 ) {
Motor.B.backward();
Motor.C.backward();
}
LCD.clear();
LCD.drawString("Distance : "+ultra.getDistance(), 0, 0);
}
Button.waitForAnyPress();
}
}
My old code, which also didn't work:
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
try {
Motor.B.rotate(-720);
Motor.C.rotate(-720);
} catch (Exception E){}
for (int i = 0; i < 5; i++)
{
LCD.drawString("Distance : "+ultra.getDistance(), 0, i);
Thread.sleep(2000);
int maxDistance = ultra.getDistance();
if (maxDistance < 15){
Motor.B.stop();
Motor.C.stop();
}
}
Button.waitForAnyPress();
}
}
Assumptions
Okay, from the looks of things, your code is probably not doing what you want. (In the future, when writing a question on Stack Overflow, please clarify in detail what the expected behavior is, as well as what erroneous behavior you're seeing. Those are usually the first two questions we would ask of you, anyway.)
First of all, you're going to want to ensure that your NXT kit has been set up properly, with your two motors on B and C, and your sensor on S1. If this is so, continue reading.
Code Interpretation
The motor commands:
try {
Motor.B.rotate(-1500, true);
Motor.C.rotate(-1500, true);
} catch (Exception E) {}
look like they're valid motor commands... but wait! You're using a two-wheeled robot, with the motors connected to two wheels that point in opposite directions? But you're using the same distance and direction for your motor's limit angle! If your wheels oppose each other, then this will do nothing but make the robot spin in a circle.
NOTE: Since your motors are configured properly, as written in your comments, ignore this part.
If you change the direction of one of the motors by changing the positive to a negative, then you'll have them both working in unison to move your robot forward (or backwards, if you change the wrong one!)
Also, keep in mind that passing true as the second argument in
Motor.B.rotate(-1500, true);
Motor.C.rotate(-1500, true);
makes this function in a very specific fashion, according to the Javadoc (emphasis mine):
If immediateReturn is true, method returns immediately and the motor stops by itself.
If any motor method is called before the limit is reached, the rotation is canceled.
The first sentence means that this does what we want it to: It tells our motor to find the right limit angle by itself, but don't make our program wait for it. However, the second sentence means that if any other motor commands are called, it will stop moving to the given limit angle. Yeah, that's right. Those next few lines make us stop moving the motors and do what they say instead.
Now, this code is problematic for two reasons:
while (ultra.getDistance() < 30) {
Motor.B.backward();
Motor.C.backward();
}
First, these commands will IMMEDIATELY stop our previous two motor commands from executing, which basically means the motors will jump straight to going "backwards" and looping until the distance sensor reads greater than or equal to 30. This is actually what we want, but we need a bit more...
Second, after your sensor reads the distance greater than 30, your motors are never told to stop! So even when your program is showing you the distance, and waiting for your button to be pressed, it'll still be moving!
A Solution
Okay, there's a few things that need to change:
Your initial motor command is being blocked out by the later commands that tell it to move to the correct position.
Your motors don't stop when they're supposed to.
Below is your code, edited to address each of these issues. I've included notes where I've made changes to show you what I've changed.
import lejos.nxt.*;
public class test {
public static void main(String [] args) throws InterruptedException {
UltrasonicSensor ultra = new UltrasonicSensor(SensorPort.S1);
for (int i = 0; i < 5; i++) {
// No initial motor movement (because it did nothing anyway)
// We change this to approach from either direction.
while (ultra.getDistance() != 30) {
// Check whether it's behind or ahead of it.
// Assuming that B- and C- increase distance, and B+ and C+ decrease it (depends on robot configuration).
// This is called a feedback loop, by the way.
if (ultra.getDistance() < 30) { // Move forward (distance+)
Motor.B.backward();
Motor.C.backward();
} else { // Move backward (distance-)
Motor.B.forward();
Motor.C.forward();
}
}
// We only get here when the distance is right, so stop the motors.
Motor.B.stop();
Motor.C.stop();
LCD.clear();
LCD.drawString("Distance : "+ultra.getDistance(), 0, 0);
}
Button.waitForAnyPress();
}
}
Now, this code isn't perfect; it may have a tendency to oscillate between forward and backward on slippery surfaces (which may turn it slightly to the left or right due to differences in applied torque), or if the sensor misses the correct position and the robot overshoots it.
This code also doesn't wait until the robot stabilizes at the given position, just until the sensor first reports the correct one. Again, this may result in sliding around a bit if the wheels don't have decent traction, the motors are set to smooth acceleration, or if the motors run at too high of a speed.
To correct these flaws, you'd need a more advanced type of feedback loop which accounts for acceleration and slip, and you'd need to wait until the robot stabilizes at the correct position for a short period of time before stopping the motors.
However, this should get you moving in the right direction, so to speak.
EDIT Corrected drive motor directionality, as specified in the comments.
Two different versions of code I'm using, as noted, the first one works fine, without any problems what so ever, the second one, the only thing that doesn't happen is the updating of the image (have verified through step debugging and debug printing to verify all values and conditionals by hand)
/* properly updates dice[] JLabel icons */
for (int i = 0; i < game.getToRoll(); i ++){
//sets rolled dice to actual values
dice[i].setIcon(dicePic[(game.getDice(i).getFaceValue())]);
}
/* loops properly, generates properly, does not update icons */
Die x = new Die();
int animate = 0;
while(animate < 10){
for (int i = 0; i < 6; i++ ){
x.roll();
if (i <= (game.getToRoll() -1))
dice[i].setIcon(dicePic[x.getFaceValue()]);
else
dice[i].setIcon(dicePic[0]);
}
panel[1].repaint();
panel[1].validate();
animate++;
try{
Thread.sleep(100);
}
catch(Exception e){
e.printStackTrace();
}
}
I've been looking around for some kind of idea of what it is that's causing the problem, and I've not run into anything other than that "sometimes repaint and validate will fix things that don't work."
As stated above, debug is giving me the greenlight on code flow working entirely as expected, just null image icons in the second example.
The problem is the Thread.sleep(100); The icon does change but you don't see the change because you blocked the UI thread.
So the rule is: never sleep the EventDispatchThread!
My advice is to use a Timer:
new javax.swing.Timer(200, new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
//do an icon change
}
}).start();
I've been trying to do some kind of autoclicker and have the following code in java:
import java.awt.event.*;
import java.awt.*;
class keyStroke {
public void Execute() throws AWTException {
int n = 0;
while(n < 100){
Robot r = new Robot();
r.delay(1000);
r.keyPress(KeyEvent.VK_1);
r.keyRelease(KeyEvent.VK_1);
++n;
}
}
}
It works pretty fine clicking the key 1, but, it doesn't work in some games.
It looks to be working only on chatbox and accessing to it (enter key), but aside from that, nothing else works (like using a skill or moving).
Then, I decided to also try in C++, with the following code
#include <iostream>
#include <windows.h>
#include <cstdlib>
using namespace std;
void SendKey (char Vk){
char VkKey = VkKeyScan(Vk);
keybd_event(VkKey, 0, 0, 0);
keybd_event(VkKey, 0, KEYEVENTF_KEYUP, 0);
}
int main(){
while(true){
SendKey('1');
Sleep(1000);
}
}
And the same thing happens.
What am U doing wrong? If the keypress doesn't work for this case I have to find something else?
I know from experience that some game input doesn't use an event based structure. Some games only check once every frame if a key is pressed. This means that your chance of pressing the key at that exact moment are zero.
Scripting utilities such as the logitech keyboard scripting tool face a similar problem and there it helps to have a delay between press and release.
Aside: chat windows usually have to use an input event as typing would be almost impossible if key presses are only registered once per frame.