Using GUI buttons to scale shapes, if statement needed - java

I have been given a GUI which creates a random bunch of shapes, the user then has the choice to scale them up or down with the + or the - button. However, when I click either of those buttons it calls the scale method:
public void scale(boolean sign) {
shapes.scale(10,false);
}
How do I make it so the + button would scale it up, and the - button would scale it down? I know it's something to do with an if statement somewhere but I am really struggling.
Thanks for your help.

You don't need an if statement here.
You need different actionPerformed methods like:
plusB.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
scale(true); // Assuming it scales up for true, and down for false.
}
});
minusB.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
scale(false);
}
});

Related

How does this Code show that the Mouse has clicked?

Seen this somewhere in StackOverflow. Just want to know how it works...
public void mouseClicked(MouseEvent e){
int x = e.getX();
int y = e.getY();
}
x and y are coordinates and can be shown to screen using JLabel, but the method name is mouseClicked. How does java know the mouse has been clicked?
(Hope this makes sense)...
The method mouseClicked is likely from java.awt.event.MouseListener interface (https://docs.oracle.com/javase/7/docs/api/java/awt/event/MouseListener.html)
A listener is a type of callback that follows the observer pattern, something happens, you get notified.
You can attach listener to items that support it. For example:
MouseListener listener = new MouseListener() { /* see example code below */ };
JLabel label = new JLabel("This is a clickable lable");
label.addMouseListener(listener);
See the following answer to get more info and reference to reading articles.
https://stackoverflow.com/a/17415300/132121
#transformer here is an empty implementation of the MouseListener you would create in Java code.
MouseListener listener = new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
// This is the method where you would get your callback
// whenever somebody clicked on the view that has this listener
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
};
This is an event handler. In order for it to work, it has to be "attached" to something in the front end (most likely a button, but it could be another UI element too).
Exactly how this works depends on which UI framework is being used, but since this is Java I assume it's most likely AWT. You can find more details in tutorials, e.g. here.
Incidentally, how significant the name is depends on which UI framework this is from. In Android, WPF, and ASP.NET, for example, the name of event handlers could theoretically be anything, it's mostly just a matter of convention (not actual requirement) what you call it. (Obviously, you have to be consistent with the name, though). As pointed out in the comments, though, in AWT this name is actually likely significant due to the class that contains it implementing an interface.

I cannot seem to .setText more than twice

I am currently making a quiz game. I have managed to set the game up as follows -
The user clicks the start button.
From here this opens a text file and retrieves each question and saves them to a string.
It then adds these strings to an Arraylist.
I then have display the first element of the array to a Label (this is the first question).
From here I have managed to make a method that checks the label text and set the text of 4 buttons to 4 different buttons.
If the user selects the correct answer it adds +1 to a score integer and then moves onto the next question(askQues2();). If the user selects the wrong answer it just moves on to the next question(askQues2();).
Once it starts the next question(askQues2();) it changes all of the values that I have told it to. i.e LabelQuestion and the 4 different answer buttons.
If the user selects the correct answer it adds +1 to a score integer and then moves onto the next question(askQues3();).
THIS IS WHERE THE PROBLEM IS
When I chose an answer during the second question, it does not run the 3rd question method.
CODE
public void askQues1 (){
String askQues1 = questions.get(0);
LabelQuestion.setText(askQues1);
ButAnsA.setText("Gillard");
ButAnsB.setText("Howard");
ButAnsC.setText("Rudd");
ButAnsD.setText("Abbott");
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
Score += 1;
askQues2();
}
});
ButAnsB.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues2();
}
});
ButAnsC.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues2();
}
});
ButAnsD.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues2();
}
});
}
public void askQues2(){
String askQues2 = questions.get(1);
LabelQuestion.setText(askQues2);
ButAnsA.setText("1999");
ButAnsB.setText("2004");
ButAnsC.setText("2007");
ButAnsD.setText("2010");
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues3();
}
});
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues3();
}
});
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
askQues3();
}
});
ButAnsA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent a){
Score += 1;
askQues3();
}
});
}
public void askQues3(){
String askQues3 = questions.get(2);
LabelQuestion.setText(askQues3);
ButAnsA.setText("Broncos");
ButAnsB.setText("Knights");
ButAnsC.setText("Storm");
ButAnsD.setText("Dragons");
}
I can tell that it does not load the 3rd method because the question label or answer buttons change.
I have tried multiple options that I have found on the internet. None of them have fixed this problem.
If you require more information. Please let me know. Like I said it is my first time posting a question so I 'm not familiar with standards.
Thanks.
You're adding actionListener to the buttons. I don't think a button can detect more than 2 actions judging by your problem.
Try setting an onClickListener() to the buttons instead.
Code:
ButAnsA.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
askQues3();
}
});
NOTE: There's a difference between adding and setting listeners. By setting a listener every time, you're only replacing the previous one. But by adding a listener you're increasing the number of listeners on the particular widget.
Your askQues2() method is adding action listeners to ButAnsA 4 times, and no new listeners to the other buttons.
You appear to be adding new listeners to the same buttons with every call, which is generally suboptimal. Since you said you are reading the questions and possible answers from a file, you'd be better off including which is the right answer in the file and having a single listener for all buttons.
pseudocode:
doAction(ActionEvent e)
int buttoncode=0
switch (e.getSource())
case ButAnsA:buttoncode=1;
case ButAnsB:buttoncode=2;
case ButAnsC:buttoncode=3;
case ButAnsD:buttoncode=4;
if (questions.get(questnum).rightAnswer == buttoncode)
score++;
questnum++
updateQuestionText()
updateButtonText()

Can I call ActionPerformed method from an Event Handler class for JButton?

I have a JButton titled "select"
In the class that creates that JButton and other classes, I want to use an if condition with ActionPerformed method.
Something like(pseudo-code)
if(_selectListener.actionPerformed(ActionEvent)) { //i.e., if select Button is clicked,
//do something
}
Is this possible?
I want to call this method because I have to handle a situation in which a player should be able to choose something by clicking "select" button, or another "scroll" button, and I want to control it using something similar to a bunch of if statements like the one above.
If it is possible, what is the syntax for it? What is the argument ActionEvent?
Thank you!
The easiest and cleanest way is to add a dedicated, specific action listener to each button. That way, when the actionPerformed() method is called, you're sure that the associated button has been clicked, and don't need to test which button has been clicked:
selectButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// handle click on select button
}
});
scrollButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// handle click on scroll button
}
});
Another way is to use a common ActionListener, and use the getSource() method of ActionEvent to know which component triggered the event. Compare the result with each potential button to determine which is the one that has been clicked:
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == selectButton) {
// handle click on select button
}
else if (e.getSource() == scrollButton) {
// handle click on scroll button
}
}
What is the argument ActionEvent?
The answer is in the documentation. Read it.
no you cant call, if needs boolean expression/value, but this method returns void.

Remove the listener for defaultButton in java

i have a Jframe application with the defaultbutton set to btnClose_ (Close Button: this button closes the window).
I have 2 textfields that must also fire an event when user clicks the Enter key on the textfields. What happens is that when I press the Enter key while the cursor is on the textfield, the event on the Close button is fired causing the window to close.
Is it possible to remove the listener of the default button if the Enter key is pressed on the textfield? Here's my code for the textfield listener
/**
* Receives the two textfield instance
*/
private void addFilterListener(JTextField txf) {
txf.addKeyListener(new KeyAdapter() {
/**
* Invoked when a key has been pressed.
*/
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
ActionListener al = btnClose_.getActionListeners()[0];
btnClose_.removeActionListener(al);
btnFilter_.doClick();
e.consume();
btnClose_.addActionListener(al);
}
}
});
}
private JButton getBtnClose(){
if(btnClose == null){
btnClose.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
getWindow().dispose();
}
});
}
return btnClose;
}
}
Where to start?
The first thing that springs out at me is the bad variable names. txf? What's wrong with proper words? textField or field, say. Or much better, a name descriptive of its purpose, not what it is.
Secondly, the first comment is wrong (not uncommon) and the second comment is redundant (already specified in the KeyListener interface, you don't need to try and half-heartedly specify it again).
Next up, low level key listeners tend not to work so well on Swing components (JComboBox being the most notorious example - it typically is implemented with child components). In general you can use JComponent.registerKeyboardAction (the API docs says this is obsolete but not deprecated, and to use more verbose code). For text components, you often want to play with the document (typically through DocumentFilter). In this particular case, looks like you just want to add an ActionListener.
Now doClick. It's a bit of an evil method. For one thing it blocks the EDT. It is probably the easiest way to make it look as if a button is pressed. From a programming logic point of view, it's best to keep away from modifying Swing components, when you can keep everything in your abstracted code.
Removing and adding listeners from components is generally a bad idea. Your code should determine what to do with an event including whether to ignore it. Do that at an appropriate point when handling the event. Don't duplicate state unnecessarily.
A potential issue is that the code seems to assume that there is precisely one action listener. There could be others. The code is not robust under unexpected behaviour. Set your components up at initialisation time, and you shouldn't need to refer to them again.
As far as I understood your question, you want that buttonClick should not get fired if Enter is pressed .
This won't fire doClick() if enter is pressed
if (e.getKeyCode() != KeyEvent.VK_ENTER) {
btnFilter_.doClick();
}
In the ActionListener of the close button, assuming you can change its code, don't close if one of the text fields have the focus.
public void actionPerformed(ActionEvent e) {
if (field1.hasFocus() || field2.hasFocus())
return; // don't close if text field has focus
frame.dispose();
}
If you can not change the ActionListener of the close button, add a FocusListener to the text fields. If one of them gets the focus, remove the default button. If the text field lost the focus, reset the default button.
FocusAdapter listener = new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
frame.getRootPane().setDefaultButton(null);
}
#Override
public void focusLost(FocusEvent e) {
frame.getRootPane().setDefaultButton(close);
}
};
field1.addFocusListener(listener);
field2.addFocusListener(listener);
This should be better than depending on the listeners being called in the correct sequence - it is of no avail to remove the listener if it was already called...

Right click on JButton

I am trying to write a Minesweeper clone in Java for fun. I have a grid of JButtons whose labels I will change to represent the danger count, flags, etc.
My problem is, I don't know how to get a right click on a JButton to depress the button. I've done the following:
button.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
boolean mine = field.isMine(x, y);
if (e.isPopupTrigger()) {
button.setText("F");
}
else {
if (mine) {
button.setText("X");
}
}
}
});
This doesn't seem to be working at all; the "F" is never shown, only the "X" part. But more importantly, this does nothing for depressing the button.
EDIT: Macs have popup trigger happen on mousePress, not mouseClick.
EDIT: Here's the solution I worked out based off of accepted answer:
button.addMouseListener(new MouseAdapter(){
boolean pressed;
#Override
public void mousePressed(MouseEvent e) {
button.getModel().setArmed(true);
button.getModel().setPressed(true);
pressed = true;
}
#Override
public void mouseReleased(MouseEvent e) {
//if(isRightButtonPressed) {underlyingButton.getModel().setPressed(true));
button.getModel().setArmed(false);
button.getModel().setPressed(false);
if (pressed) {
if (SwingUtilities.isRightMouseButton(e)) {
button.setText("F");
}
else {
button.setText("X");
}
}
pressed = false;
}
#Override
public void mouseExited(MouseEvent e) {
pressed = false;
}
#Override
public void mouseEntered(MouseEvent e) {
pressed = true;
}
});
add(button);
Minesweeper clone http://grab.by/1y9z
Button can't be pressed by right click. Add such a lines to you mouse listener
mousePressed:
if(isRightButtonPressed) {underlyingButton.getModel().setPressed(true));
mouseReleased:
if(needReset) {underlyingButton.getModel().setPressed(false));
or do there whatever want.
I wouldn't use isPopupTrigger but directly check for the right button:
button.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
boolean mine = field.isMine(x, y);
if (e.getButton() == MouseEvent.BUTTON2) {
button.setText("F");
}
...
Just a small addition: the simplest way to check for the right button is SwingUtilities.isRightMouseButton
As you have mentioned that checking for "mousePressed" solved your issue. And the Javadoc of isPopupTrigger would explain the need for this:
public boolean isPopupTrigger()
...
Note: Popup menus are triggered differently on different systems. Therefore, isPopupTrigger should be checked in both mousePressed and mouseReleased for proper cross-platform functionality.
Also see the section on The Mouse Listener API in the Java Swing tutorial.
MouseEvent has some properties
static int BUTTON1
static int BUTTON2
static int BUTTON3
among others. Check those when your event fires.
EDIT
public int getButton()
Returns which, if any, of the mouse buttons has changed state.
The button being visibly depressed on right click isn't part of the "normal" behavior of buttons. You may be able to fake it using JToggleButtons, or simply changing the button's background color and maybe border while the right mouse button is being held down.
If you are certain that the event is properly being triggered (debug FTW!) and that the button.setText("F") is happening, then perhaps you simply need to repaint.
Repaint the button.
http://java.sun.com/javase/6/docs/api/javax/swing/JComponent.html#repaint(java.awt.Rectangle)
This works for me fine on Mac:
import java.awt.event.*;
import javax.swing.*;
public class ButtonTest extends JFrame {
JButton button;
public ButtonTest() {
button = new JButton("W");
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getButton() == 3) { // if right click
button.setText("F");
button.getModel().setPressed(false);
// button.setEnabled(true);
} else {
button.setText("X");
button.getModel().setPressed(true);
// button.setEnabled(false);
}
}
});
this.add(button);
this.setVisible(true);
}
public static void main(String[] args) {
new ButtonTest();
}
}
You might as well check for e.getButton() == 2 but I don't know when this one is triggered on Macs.

Categories

Resources