Apply .addKeyListener to array of JTextFields - java

I wrote the code below. It checks input from a JTextField and ensures the user is typing in numbers. If not the box flashes red and the invalid character is removed.
The tipArray[] is an array of JTextFields that I add to the JFrame with a loop.
How can I apply the following code to every possible array (tipArray[0], tipArray[1] ....tipArray[6])?
tipArray[6].addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
char keyChar = e.getKeyChar();;
char[] badCharArray = "abcdefghijklmnopqrstuvwxyz-`~!##$%^&*()[,]{}<>_+=|\"':;?/ ".toCharArray();
for (int i = 0; i < badCharArray.length; i++) {
if (badCharArray[i] == keyChar) {
tipArray[1].setBackground(Color.RED);
}
}
}
#Override
public void keyReleased(KeyEvent e) {
if (tipArray[6].getBackground() == Color.RED) {
if (tipArray[6].getText() != "0"){
String removeLastLetter = tipArray[1].getText().substring(0, tipArray[6].getText().length()-1);
tipArray[6].setText(removeLastLetter);
tipArray[6].setBackground(Color.WHITE);
}
}
}
});
The loops I have tried dont work:
for (int i = 0; i <= 6; i++) {
tipArray[i].addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
char keyChar = e.getKeyChar();;
char[] badCharArray = "abcdefghijklmnopqrstuvwxyz-`~!##$%^&*()[,]{}<>_+=|\"':;?/ ".toCharArray();
for (int x = 0; x < badCharArray.length; x++) {
if (badCharArray[x] == keyChar) {
tipArray[i].setBackground(Color.RED);
}
}
}
#Override
public void keyReleased(KeyEvent e) {
if (tipArray[i].getBackground() == Color.RED) {
if (tipArray[i].getText() != "0"){
String removeLastLetter = tipArray[i].getText().substring(0, tipArray[i].getText().length()-1);
tipArray[i].setText(removeLastLetter);
tipArray[i].setBackground(Color.WHITE);
}
}
}
});
}
^The above results in all of the variable i's after line "if (badCharArray[x] == keyChar) {" having a syntax error.

Change your counter in the for loop in the second one to be a different variable (z instead of i perhaps). You have a duplicate variable the way it is now (two i's). Also, it is recommended you use a DocumentListener, not KeyListener, for checking for invalid characters, as KeyListeners sometimes fail.

Related

Dragging over JButtons/JLabels

I'm trying to make the game Dots and I have already figured out a way to generate random dots using an int[][]. I've also created a method to remove dots if they are next to each other and have the same colour when selected. My playfield is 7 by 7 and is filled with JButtons (which could also be JLabels). Now I need to find a way to drag over a few dots and select them if they are the same colour as the initial dot, but whenever I try to do something like that, I always end up either selecting the initial dot itself and send that button's coordinates whenever I move the mouse, or select the x and y values for the pointer on the screen.
Here is the relevant code:
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
final int finalJ = j;
final int finalI = i;
playField[i][j].addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
try {
while (true) {
dotsController.beginZet(finalI, finalJ);
}
} catch (DotsException e1) {
e1.printStackTrace();
}
}
});
playField[i][j].addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
try {
dotsController.doeZet();
} catch (DotsException e1) {
e1.printStackTrace();
}
}
});
}
}

Java JButtons doesnt appear on the JFrame

Here's the significant fragment of JFrame HidingOperationView:
hideBtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0){
currentPixelInImageToHide.setVisible(true);
pixelOfToHideTable.setVisible(true);
nextStep.setVisible(true);
doAll.setVisible(true);
SteganographyOperationsUtil.hidingOperation(
getSelectedFirstImageModel(), copyOfToHide, posterisation);
}
});
nextStep.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0){
SteganographyOperationsUtil.key=1;
}
});
doAll.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0){
SteganographyOperationsUtil.key2=1;
}
});
key and key2 are my controlers in the class SteganographyOperationsUtil, when to wait within the loop:
int key = 1
int key2 = 0
Key controled by the button 'next step', so the loop would go only once forward, show the results in the JTables and wait for another click.
Key2 controled by the button 'doAll', which allows the loop run till the end without stopping.
in the hiding operation:
for (int x = 0; x < hiding.getWidth(); ++x) {
for (int y = 0; y < hiding.getHeight(); ++y) {
if(temp < header.length()){
...
}else{
while (key!=1){
sleep(100);
}
key=key2;
...
if (key2 == 0){
throwToTable(HidingOperationView.pixelOfToHideTable,
colorOfToHideBinary);
}
}
}
}
The problem is that the buttons that control the loop doesn't appear at all,
they only do, when i comment the line:
SteganographyOperationsUtil.hidingOperation( getSelectedFirstImageModel(), copyOfToHide, posterisation);
Maybe it's not best way to control the loop, but i have no clue, how to do it otherwise.

I'm getting an IndexOutOfBoundsException with my arraylist, what am I doing wrong?

This class is in a program for a game I'm writing that is basically Space Invaders. I'm getting Exceptions for some reason and I don't see why I should be getting them.
Here's the class in question, but I can post all the code if necessary:
public class GamePanel extends JPanel {
Launcher launcher1;
Background bground1;
Shot shot;
public ArrayList<Shot> shots;
public int numShots;
public static int counter;
public GamePanel() throws IOException {
super();
this.shots = new ArrayList<>();
this.numShots = 0;
launcher1 = new Launcher();
bground1 = new Background();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bground1.background, 0, 0, getWidth(), getHeight(), null);
g.drawImage(launcher1.baldEagleImage, launcher1.getLxCoord(), launcher1.lyCoord, null);//paint the launcher
while (counter == 1) {
for (int i = 0; i < shots.size(); i++) {
g.drawImage(shots.get(i).mcDShotImage, shots.get(i).staticXLauncherCoord, shots.get(i).getSyCoord(), null);
}
}
}
public void move(GamePanel gamePanel) {
launcher1.moveX();
if (numShots > 0) {
moveShot();
}
repaint();
}
public void moveShot() {
for (int i = 0; i < numShots; i++) {//loop to move all the shots
if (shots.get(i).getSyCoord() > 10) { // THIS IS THE ISSUE, but I don't know why
counter = 1;
shots.get(i).moveY();
repaint();
} else {
counter = 0;
shots.remove(i);
repaint();
}
}
}
public void createShots() {
try {
for (int j = 0; j < numShots; j++) {
shots.add(new Shot());
}
} catch (IOException | IndexOutOfBoundsException e) {
System.out.println("caught an exception" + e);
}
}
}
The problem is in this piece of code:
} else {
counter = 0;
shots.remove(i);
repaint();
}
You remove an item from shots without adjusting numShots, causing an index out of bounds exception in one of subsequent iterations.
To fix this, either add numShots-- in the else branch, or use the built-in size() method that returns the count of elements in a list instead: unlike numShots which you need to maintain, shots.size() never gets "out of sync" with the actual count.
In the above line of code what is apparent is the issue is numShots is > shots.size() (because you also remove shots.
Since I couldn't where you are incrementing the numShots, in this piece of code one simple (albeit not sure from your logic perspective) change your for loop as below:
for (int i = 0; i < shots.size(); i++)

JFrame issues with the action statements and specific methods

I am working a program that runs through a JFrame I have created and I am just having a few problems calling on certain methods in my code. The issues I am running a method that outputs something based upon evaluation, I keep getting nullpointers at the same spots.
JButton btnDealCards = new JButton("Deal Cards");
btnDealCards.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
displayYourHand.setText("");
output = "";
couples = 0;
for (int i = 0; i < hand.length; i++) {
Card1 dealt = dealHand();
if (dealt != null) {
hand[i] = dealt;
displayYourHand.setText(displayYourHand.getText()
+ hand[i].toString() + "\n");
} else {
displayYourHand.setText("NOT ENOUGH CARDS TO DEAL");
status.setText("Shuffle cards to continue");
return;
}
}
// totalHand();
// pairs();
// twoPair();
// threeOfAKind();
}
});
btnDealCards.setBounds(336, 192, 98, 26);
contentPane.add(btnDealCards);
JButton btnShuffleCards = new JButton("Shuffle Cards");
btnShuffleCards.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
shuffle();
displayYourHand.setText("The Deck Has Been Shuffled");
}
});
btnShuffleCards.setBounds(314, 229, 147, 23);
contentPane.add(btnShuffleCards);
}
public void shuffle() {
for (int first = 0; first < deck.length; first++) {
int second = randomNumbers.nextInt(52);
Card1 temp = deck[first];
deck[first] = deck[second];
deck[second] = temp;
}
btnDealCards.setEnabled(true);
}
public Card1 dealHand() {
if (currentCard < deck.length)
return deck[currentCard++];
else {
btnDealCards.setEnabled(false);
return null;
}
}
public void pairs() {
for (int k = 0; k < faces.length; k++)
if (numbers[k] == 2) {
output += "" + ("Pair of " + faces[k] + "'s ");
couples++;
}
status.setText(output);
}
The first is my actionlistener and actionperformer and the next three are the actions I wish to preform that spit out the nullpointers. The issues are always the lines after the for loop such as the "status.setText(output);" or "btnDealCards.setEnabled(true);". I am thinking I need to turn these statements into return statements but that is my only idea. Thanks in advance!
The variables that are being dereferenced on the lines that are throwing the NullPointerException (NPE) are null. For instance, the status variable is null if you're getting a NPE on this line:
status.setText("Shuffle cards to continue");
and the displayYourHand variable is null if this line throws a NPE:
displayYourHand.setText("The Deck Has Been Shuffled");
and likewise the btnDealCards variable is null if this line throws a NPE:
btnDealCards.setEnabled(true);
My bet: you may be shadowing the variable by re-declaring it in a constructor or init method when you try to create the object, leaving the class field null. The key will be to look at the code where you think that you're initializing these variables and see why you're not in fact initializing them.

How to character and Numeric values restrict in TextField Java

I have two questions regarding character and numeric values limitation. I have listening to focus lost events and validating Name (character) and Contact (numeric) TextFields.
1. How do I restrict numeric data less then 3 digits and not allow more then 13 digits.
Below is the coding of my contact TextField for numeric:
private void txt_contactFocusLost(java.awt.event.FocusEvent evt) {
if (txt_contact.getText().equals("")) {
} else {
String contact = txt_contact.getText();
Pattern pt6 = Pattern
.compile("^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]+$");
Matcher mh6 = pt6.matcher(contact);
boolean matchFound6 = mh6.matches();
if (!(matchFound6)) {
JOptionPane.showMessageDialog(null,
"* Enter the Numaric Values only *");
txt_contact.setText("");
txt_contact.requestFocus();
}
}
}
2. How do I restrict character data less then 3 character and not allow more then 30 characters.
private void txt_nameFocusLost(java.awt.event.FocusEvent evt) {
if (txt_name.getText().equals("")) {
error2.setText("Enter Full Name");
txt_name.setText("");
} else {
String name = txt_name.getText();
Pattern pt1 = Pattern.compile("^[a-zA-Z]+([\\s][a-zA-Z]+)*$");
Matcher mh1 = pt1.matcher(name);
boolean matchFound1 = mh1.matches();
if (!(matchFound1)) {
JOptionPane.showMessageDialog(null,
"* Enter the Character Values only *");
txt_name.setText("");
txt_name.requestFocus();
} else {
error2.setText("");
}
}
}
You can do something easier:
NumberFormat numF = NumberFormat.getNumberInstance();
numF.setMaximumIntegerDigits(13);
numF.setMinimumIntegerDigits(3);
JFormattedTextField THE_FIELD = new JFormattedTextField(numF);
(The same idea for characters)
Now, only numbers are allowed, with the specified length range.
Read more about it: NumberFormat and JFormattedTextField
in the pattern you can use the statement {n,m} n- to m- times
Duo to this you can build your pattern like this
for your charackter comparison
Pattern pt6=Pattern.compile("[a-zA-Z]{3,30}"); // it says, it should be 3-30 non Digits
for the numbers it is
Pattern pt6=Pattern.compile("\\d{3,13}"); // it says, it should be 3-13 Digits
For String
public boolean validateString(String data){
char [] chars = data.toCharArray();
if(chars.length < 3 || chars.length >13)
return false;
return true;
}
For Number
public boolean validateNumber(int number){
String data = number+"";
return validateString(data);
}
I'm using this one. very simple and easy
use the method that you need or both then call where you need pass your JTextField as parameter done...
public static void setNumericOnly(JTextField jTextField){
jTextField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if ((!Character.isDigit(c) ||
(c == KeyEvent.VK_BACK_SPACE) ||
(c == KeyEvent.VK_DELETE))) {
e.consume();
}
}
});
}
public static void setCharacterOnly(JTextField jTextField){
jTextField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if ((Character.isDigit(c) ||
(c == KeyEvent.VK_BACK_SPACE) ||
(c == KeyEvent.VK_DELETE))) {
e.consume();
}
}
});
}

Categories

Resources