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.
Related
I'm making a math flashcard application that takes 20 answers and randomizes the question each time.
My Problem: The for loop does not wait until the button is pressed. I need to find a way to wait for the ActionListener to be executed before it goes through the loop again.
Please bear with me as I am quite new to Java.
Here is my current code:
for(int i = 0; i < 20; i++){
Random numberOne = new Random();
Random numberTwo = new Random();
firstNumberInt = numberOne.nextInt(12) + 1;
secondNumberInt = numberTwo.nextInt(12) + 1;
firstNumber = Integer.toString(firstNumberInt);
secondNumber = Integer.toString(secondNumberInt);
firstNumberPrint.setText(firstNumber);
secondNumberPrint.setText(secondNumber);
answerBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
String answerString = answerField.getText();
try {
int answer = Integer.parseInt(answerString);
} catch(NumberFormatException e){
error.setText("Number Cannot Be A Word");
}
}
});
}
The ActionListener should be outside the loop and the loop should be within it.
Not the opposite.
answerBtn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
// Loop somewhere inside here
String answerString = answerField.getText();
try {
int answer = Integer.parseInt(answerString);
} catch(NumberFormatException e){
error.setText("Number Cannot Be A Word");
}
}
});
The code inside the overridden method inside the ActionListener class is being invoked every time the Component is interacted.
Instead of hard coding 64 buttons to create a board did a 2D array and I need to get the array coordinates. This is the code I tried using and the error I got.
code:
public void mousePressed(MouseEvent e)
{
JButton[][] clicked = (JButton[][])e.getSource();
int x = clicked.length;
int y = clicked[0].length;
board[x][y].setIcon(selected);
}
Error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JButton cannot be cast to [[Ljavax.swing.JButton;
I figured out how to not hard code each option use a for loop for the action listener and use variables.
Solution:
public void mousePressed(MouseEvent e)
{
JButton clicked = (JButton)e.getSource();
for(int x = 0; x<8; x++)
{
for(int y = 0;y<8;y++)
{
if(clicked == board[x][y])
{
occupied[x][y] = true;
board[x][y].setIcon(selected);
}
}
}
}
The idea of my program is to select one name from a list that saved before in other JFrame. I'd like to print in the label all names one after the other with small delay between them, and after that stop at one of them. The problem is that lbl.setText("String"); doesn't work if there is more than one setText code.
Here is the part of my code :
public void actionPerformed(ActionEvent e)
{
if (RandomNames.size != 0)
{
for (int i = 0; i < 30; i++)
{
int rand = (int)(Math.random() * RandomNames.size);
stars.setText(RandomNames.list.get(rand));
try
{
Thread.sleep(100);
}
catch (InterruptedException err)
{
err.printStackTrace();
}
}
int rand2 = (int)(Math.random() * RandomNames.size);
stars.setText(RandomNames.list.get(rand2));
RandomNames.list.remove(rand2);
RandomNames.size = RandomNames.list.size();
}
if (RandomNames.list.size() == 0)
{
last.setText("\u062A\u0645 \u0638\u0647\u0648\u0631 \u062C\u0645\u064A\u0639 \u0627\u0644\u0623\u0633\u0645\u0627\u0621 \u0627\u0644\u062A\u064A \u0641\u064A \u0627\u0644\u0642\u0627\u0626\u0645\u0629 !");
}
}
Don't use a loop or Thread.sleep. Just use a javax.swing.Timer. The following will cause 30 iterations occurring every 1000 milliseconds. You can adjust the code in the actionPerformed accordingly to what you wish to happen every so many milliseconds.
int count = 0;
...
Timer timer = new Timer(1000, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
if (count == 30) {
((Timer)e.getSource()).stop();
} else {
int rand = (int) (Math.random()* RandomNames.size);
stars.setText(RandomNames.list.get(rand));
count++;
}
}
});
timer.start();
If you want you can just set up the Timer in the constructor, and start() it in the actionPerformed of another button's listener.
See more at How to use Swing Timers
Basically, what I have are 2 arrays. One array of JButtons 26 long, one array of Strings with each letter of the alphabet, and a for loop to create a button for each letter of the alphabet and insert it into the JButton array:
JButton[] buttons = new JButton[26];
String letters[]{"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
for(int i = 0; i < buttons.length; i++){
buttons[i] = new JButton(letters[i]);
panel.add(buttons[i]);
}
What I want to do is create an event for all the buttons. Whenever a button is pressed, whatever letter it coincides with will be set as the value for a String called guess.
So far I understand that I need to do something like this:
x.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
//Insert what I want to happen
}
});
My problem is with where I wrote x. I am not sure what to put there. I need this to work for all 26 buttons in the array...
Sorry if this seems obvious/simple. I am obviously new to java and I just don't understand how JButtons work and how to do this.
Define an ActionListener like shown below.
ActionListener aListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event){
//find the actioncommand and do what is required.
}
};
Associate this ActionListener to every button.
for(int i = 0; i < buttons.length; i++){
buttons[i] = new JButton(letters[i]);
buttons[i].setActionCommand(letters[i]);
buttons[i].addActionListener(aListener);
panel.add(buttons[i]);
}
Just test the actionCommand which is a String value and compare it with a the letter, and do something.
x.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
if (e.getActionCommand().equals("A")
// do something
else if (e.getActionCommand().equals("B")
// do soemthing
...
...
}
});
I prefer to use a switch though for cases like this.
public void actionPerformed(ActionEvent e){
String letter = e.getActionCommand();
switch(letter) {
case "A" : do something; break;
case "B" : do something; break;
case "C" : do something; break;
...
...
}
}
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.