Minesweeper flags java - java

I'm pretty new in programming, but i need to program the game Minesweeper.
basically the game is running, but there are some parts that wont work at all.
The first problem are the flags. My Minesweeper is able to set flag by right clicking on a field, but everytime i do a left-click on a field with a flag, the field will override the flag.
Field after a right click
Flagged field after a left click
Is there any way to set the flag "absolute" or final or something?
Here is the code:
#Override
public void mouseClicked(MouseEvent arg0) {
if (SwingUtilities.isRightMouseButton(arg0)) {
setFlag();
} else if (SwingUtilities.isLeftMouseButton(arg0)) {
checkMine();
}
public void setFlag() {
button.setEnabled(false);
button.setText(flag);
button.setBackground(Color.LIGHT_GRAY);
}
public void checkMine() {
button.setEnabled(false);
display();
check = false;
if (value == 0)
log.emptyCells();
if (value == -1)
log.fail();
if (value == -3)
log.lucky();
}
I hope that someone here can help me.
tanks :)

When you are using methods with button, you are never specifying which button you are disabling. I recommend adding a JButton parameter to your methods so you can change them.
Also, the check boolean is never initialized as a boolean, unless it's an instance variable you are using, in which case you need to edit your post to include your instance variables.

Related

removeEvent ItemListener (removeItemListener) from within itemStateChanged doesn't work (StackOverfowError)

I have the following code, I cannot use setEnabled(false), because I need to set the background- and foregroundcolor.
public class RadioButton extends JRadioButton implements ItemListener {
public RadioButton(String text)
{
super(text);
addItemListener(this);
}
public void itemStateChanged(ItemEvent e) {
synchronized (this) {
removeItemListener(this);
if (e.getStateChange() == ItemEvent.SELECTED) {
System.out.println("item is selected true [changed]");
setSelected(false);
} else if (e.getStateChange() == ItemEvent.DESELECTED) {
System.out.println("item is selected false [changed]");
setSelected(true);
}
addItemListener(this);
}
}
}
This should be a radio button, that can't be changed. Hoever if I try testing the code, it gives me an endless loop printing
item is selected true [changed]
once...
...and then always
item is selected false [changed]
until there is a Java StackOverflowError.
How can this be? Is the disabling of the ItemListener not working?
If you can then please also show me, how to pack this into a lamda function. I got a illegal self reference-error, when trying to put this into a lamda function.
Please correct me, if the title is not correct.
As MadProgrammer pointed out, disabling the AbstractButton (aka RadioButton or Checkbox) can be archieved by setting the ButtonModel to a custom one always returning a constant value.
MainClass:
radioButtonOrCheckbox.setModel(new ButtonCustomModel(true));
ButtonCustomModel:
public class ButtonModel implements javax.swing.ButtonModel {
protected boolean state;
public ButtonModel(boolean state)
{
this.state = state;
}
#Override
public boolean isSelected() {
return state;
}
#Override
public boolean isEnabled() {
return true;
}
// other methods of ButtonModel-interface
[...]
}
I cannot use setEnabled(false), because I need to set the background- and foregroundcolor
This is probably just purely a personal thing, but I have a distinct dislike or UI's which don't conform to establish norms and user expectations.
So, when a button shouldn't be interacted with, it should be disabled. This is a convention that a user understands immediately.
I change the background-color and foreground-color for the evaluation-radiobuttons and -checkboxes.
Okay, so you want to decorate the buttons in some way, fair enough
It is clear from context that they are not meant to be checked by the user
To you perhaps, I'd probably be madly trying to click it, but I'm just that kind of user ;)
Okay, so with just a little but of paying around with the UIManager's default values, it's possible to take more control over how some elements are rendered, for example...
UIManager.put("RadioButton.disabledText", Color.BLUE);
JRadioButton rb = new JRadioButton("Test");
rb.setOpaque(true);
rb.setBackground(Color.RED);
rb.setForeground(Color.BLUE);
rb.setEnabled(false);
add(rb);
UIManager.put("CheckBox.disabledText", Color.RED);
JCheckBox cb = new JCheckBox("Test");
cb.setOpaque(true);
cb.setBackground(Color.BLUE);
cb.setForeground(Color.RED);
cb.setEnabled(false);
add(cb);
Now, this is just a quick hack.
For me, I might consider doing something different to highlight the correct answer, maybe fading or removing the other questions or use a LineBorder to highlight the correct answer or use a JLabel and nice big green tick or red cross, as some simple idea off the top of my head.

error: local variables referenced from an inner class must be final or effectively final

I am working with swings. This is the code I used to make a frame for logout which would return a int value and using that value other operation could be performed in the previous function. But I am getting an error. How should I solve it?
public int logout()
{
int s=0;
JFrame main=new JFrame("Logout");
Dimension d=Toolkit.getDefaultToolkit().getScreenSize();
main.setSize(d.width/2,d.height/3);
main.setLayout(new FlowLayout());
JButton yes=new JButton("Yes");
main.add(yes); main.setVisible(true);
yes.addActionListener(new ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent e)
{
s=1;
main.setVisible(false);
}
});
return s;
}
What do you expect your program to do?
The code you wrote, tries to do:
Create a "logout" frame with a "yes" button.
Return from the logout() method with the value of the s variable.
When later the user presses the "yes" button, you prepared an action listener to then set the s variable to 1 - but that can't work, as you already returned from the logout() method, and the variable s no longer even exists.
So, be happy that the compiler told you about a problem.
I suppose you want to wait for the user's logout approvement. Then use JOptionPane methods (the Java tutorials will help you how to do that correctly).
And by the way: get into the habit of formatting and indenting your code properly. It wasn't fun reading your code.
Use the JOptionPane class to create a confirm dialog by using one of the showConfirmDialog() method to show a confirm dialog. Please read the Java tutorial How to Make Dialogs on how to create such dialogs. The source code should look something like this:
int choice = JOptionPane.showConfirmDialog(your_main_frame,
"Do you want to logout?",
"Logout?",
JOptionPane.YES_NO_OPTION);
if (choice == JOptionPane.YES_OPTION) {
// "Yes" clicked
} else {
// "No" clicked
}

Getting character to jump in JavaFX

I have tried using a KeyListener to make the character rise which just simply didnt do anything. Is there a better way to do this? If not, does anyone know why the KeyListener isn't working? I would really appreciate some help. Also, I call this method in a Timeline so the bird does not just fall 1 pixel and will not rise by one either
Here is the code for the KeyListener (The bird falling part works fine by the way):
public static void birdJump() {
birdView.relocate(100, fall++);
if(fall > 201)
birdView.setRotate(50);
FlappyBird.root.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (event.getCode().equals(32)) {
birdView.relocate(100, fall--);
if(fall > 199)
birdView.setRotate(-50);
}
}
});
}
Thanks!
Read the documentation: event.getCode() does not return an int (or a number of any kind), so event.getCode().equals(32) cannot possibly be true.
You want
if (event.getKeyCode() == KeyCode.SPACE) {
// ...
}
In addition to what James_D said, I think it's because you use the KeyEvent on a Layout that does not have the focus by default since it belongs to the Scene, to remedy it you have to give it the focus :
root.setFocusTransversale(true); /* Enable focus on the layout */
root.requestFocus(); /* give the focus to the layout */
I hope this will solve your problem !

Cursor Change by MouseMove Event doesn't work

i've got some problem with my Mouse Cursor. I set it inside my MouseMotion Event of a JPanel with this.setCursor(), but it dosen't changed.
After getting out ouf the Window for example on my Desktop and go back inside , the cursor will be changed by any motion.
The Code of the mouse Event of the JPanel is this:
public void mouseMoved(MouseEvent e) {
this.requestFocusInWindow();
this.requestFocus();
this.cL.doMouseMoved(e);
}
The Code of the Method doMouseMoved is this:
public void doMouseMoved(MouseEvent e) {
this.lastMouseEvent = e;
this.sList.setCurrentElements(e.getPoint());
this.setMovedCursor(e);
}
An finally this is the code of the method setMovedCursor:
public void setMovedCursor(MouseEvent e) {
java.awt.Cursor cu = new java.awt.Cursor(java.awt.Cursor.SW_RESIZE_CURSOR);
view.setCursor(cu);
}
(I know that this isn't the best way)
I hope everyone can help me.
Sorry for any mistakes, it's my first post at stackoverflow.
if (sList.getCurrentShapeType() == "rec") {
Not sure if it will fix your problem but don't use "==" to compare objects.
Instead you should be using the equals(...) method.
if ("rec".equals(sList.getCurrentShapeType()) {
Note: I changed the order of the test so you don't have to worry about the getCurrentShapeType() method returning a null value.
else if (k.getBorderByPoint(e.getPoint()) == 4)
Also, I don't know what your getBorderByPoint() method does but why are you comparing it to an integer value. We have no idea what "4" means. Don't use "magic numbers. Instead create variables like: CURSOR_NORTH. Or better yet why not just return the cursor from that method so you don't have to check the value twice.

Getting ENTER to work with a JSpinner the way it does with a JTextField

First, to make my job explaining a bit easier, here's some of my code:
JSpinner spin = new JSpinner();
JFormattedTextField text = getTextField(spin);
text.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
// Do stuff...
}
});
...
private JFormattedTextField getTextField(JSpinner spinner) {
JComponent editor = spinner.getEditor();
if (editor instanceof JSpinner.DefaultEditor) {
return ((JSpinner.DefaultEditor )editor).getTextField();
} else {
System.err.println( "Unexpected editor type: "
+ spinner.getEditor().getClass()
+ " isn't a descendant of DefaultEditor" );
return null;
}
}
So as you can see, I got that far. And indeed, when I type in a value into the text field component of the spinner (JFormattedTextField), and THEN press ENTER, it works.
What I want now is to be able to have the text field respond to ENTER without having to manually type in a new value (which sorta defeats the purpose of making a spinner out of it). How do I do that?
I know this is not the action listener...but maybe this can work for you?
text.addKeyListener( new KeyAdapter() {
#Override
public void keyReleased( final KeyEvent e ) {
if ( e.getKeyCode() == KeyEvent.VK_ENTER ) {
System.out.println( "enter pressed" );
}
}
} );
I just ran into an issue relating to this, myself. In my case, I had a JSpinner with a SpinnerNumberModel setup so I could input numerical ID values, and then retrieve them from a remote database. This worked all well and good with a JButton as my trigger for the query, but I wanted to be able to switch focus to the field via Tab, and hit enter, and also be able to change the value by entering an ID with numerical keys, then hit enter.
The one that was giving me the most issues was manually entering the ID with numerical keys, then pressing enter. When I would do this, the query would still happen, but it was querying the previous ID rather than the one I just entered, so I'd have to hit enter again to query the new ID (see code)
((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
queryData();
}
}
});
and the query method:
private void queryData() {
int minVal = Integer.parseInt(minRng.getValue().toString());
queryDataBase(minVal);
}
In order to fix this, all I had to do was force the query to wait to run until the spinner updated its value, which was easily done by using SwingUtilities.invokeLater() to force it to the end of the EDT queue, like so:
((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
queryData();
}
});
}
}
});
Thanks to the invokeLater() the query now happens on the new value rather than the previous one, when pressing enter, as the JSpinner has then updated its value to the newly input one.
I'm assuming the reason for this is that the value entered is not officially applied to the JSpinner until you hit enter, which also fires the key listener for the query. The KeyEvent for the custom [query] key listener appears to be the first one in the queue, so it runs its code first, and THEN the KeyEvent for applying the value to the JSpinner from the internal JFormattedTextField, which is why it queries the old value. SwingUtilities.invokeLater() just puts the query itself at the end of the queue, so it allows the other KeyEvent to finish its code before running the query.
Edit:
Another way to achieve this is to request the value directly from the JFormattedTextField rather than the JSpinner, as this should also return the newly entered value since the JFormattedTextField contains the value you typed in, but it hasn't yet been passed to the JSpinner, which appears to be where the issue lies.
private void queryData() {
JFormattedTextField tf = ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField();
int minVal = Integer.parseInt(tf.getText());
queryDataBase(minVal);
}
The only problem with this method is that you then have to catch any NumberFormatExceptions, when parsing the value, where the SwingUtilities.invokeLater() approach allows the spinner model to remove any invalid characters, automatically, and continue with the query.
Anyway, I'm still somewhat inexperienced with Java, so if my understanding of this is incorrect, please let me know in the comments.
I think what you are asking is that when we manually edit the JSpinner shown value, it doesn't actually change it but only show as it.
The reason is that JSpinner use something called editor and has a value. The editor is responsibe for showing the current value and also, changing it (but only using arrow buttons)
If we want to edit it by ourselves then we need to use
spinner.commitEdit();
Have a look into this for further knowledge,
https://docs.oracle.com/javase/7/docs/api/javax/swing/JSpinner.html

Categories