[英]Listener inside a loop won't allow to change an outsider boolean flag
Following my previous post here , I wrote a listener : 继我以前的帖子在这里 ,我写了一个监听器:
@Override
public void keyTyped(KeyEvent keyEvent)
{
PolygonFiller polyFiller = new PolygonFiller();
char key = keyEvent.getKeyChar();
final boolean runForever = true;
switch(key)
{
/**
* Fill the polygons
*/
case FILL_POLYGON:
{
if (greenLightForFilling == true)
{
while (runForever)
{
fillPolygon(polyFiller);
KeyListener listener = new KeyListener()
{
public void keyPressed(KeyEvent keyEvent)
{
char keyOther = keyEvent.getKeyChar();
if (keyOther == 'F' || keyOther == 'f')
// can't use break;
runForever = false;
}
@Override
public void keyReleased(KeyEvent arg0) {}
@Override
public void keyTyped(KeyEvent arg0) {}
};
}
}
break;
} // end FILL_POLYGON
case FILL_POLYGON_LOWERCASE:
{
if (greenLightForFilling == true)
{
fillPolygon(polyFiller);
}
break;
}
/**
* save all polygons in a .scn file
*/
case SAVE_POLYGONS :
{
if (greenLightForFilling == true)
{
saveWorkspace();
}
break;
} // end SAVE_POLYGONS
case SAVE_POLYGONS_LOWERCASE:
{
if (greenLightForFilling == true)
{
saveWorkspace();
}
break;
}
/**
* Delete everything & load all polygons from .scn file
*/
case LOAD_POLYGONS:
{
loadWorkspace();
break;
}
case LOAD_POLYGONS_LOWERCASE:
{
loadWorkspace();
break;
}
default: break;
} // end switch
}
The goal : 目标 :
break from the loop , when I get a second f
or F
(I already got one f
/ F
when I entered to loop) . 当我得到第二个f
或F
时中断循环(进入循环时我已经得到一个f
/ F
)。
Do I need to attach the second listener to something ? 我是否需要将第二个侦听器附加到某物上?
But I can't change the runForever
to false , since it's written outside . 但是我无法将runForever
更改为false,因为它是在外部编写的。
Even if I change it to final
, I can't change its value to false
either . 即使我将其更改为final
,也不能将其值更改为false
。
Any way around this ? 可以解决吗?
Note : I already have a key-listener for entering the switch-case!! 注意 :我已经有一个用于输入开关盒的按键监听器!!
EDIT: 编辑:
// Hot-keys hit by the user - used for keyboard listening
private static final char FILL_POLYGON = 'F';
private static final char SAVE_POLYGONS = 'S';
private static final char LOAD_POLYGONS = 'L';
private static final char FILL_POLYGON_LOWERCASE = 'f';
private static final char SAVE_POLYGONS_LOWERCASE = 's';
private static final char LOAD_POLYGONS_LOWERCASE = 'l';
@Override
public void keyTyped(KeyEvent keyEvent)
{
PolygonFiller polyFiller = new PolygonFiller();
char key = keyEvent.getKeyChar();
final Settable runForever = new Settable();
switch(key)
{
/**
* Fill the polygons
*/
case FILL_POLYGON:
{
if (greenLightForFilling == true)
{
KeyListener listener = new KeyListener()
{
public void keyPressed(KeyEvent keyEvent)
{
char keyOther = keyEvent.getKeyChar();
if (keyOther == 'F' || keyOther == 'f')
runForever.set(false);
}
@Override
public void keyReleased(KeyEvent arg0) {}
@Override
public void keyTyped(KeyEvent arg0) {}
};
this.addKeyListener(listener);
while (runForever.get())
{
fillPolygon(polyFiller);
}
}
break;
} // end FILL_POLYGON
...
}
Final variables cannot be changed, but if they represent a mutable object, you can change the content of that object. 最终变量不能更改,但是如果它们表示可变对象,则可以更改该对象的内容。
For example, if you make a Settable
class, and use its instance instead of boolean
, you could do this: 例如,如果创建一个Settable
类,并使用其实例而不是boolean
,则可以这样做:
class Settable {
private boolean flag;
public boolean get() {return flag;}
public boolean set(boolean val) { flag = val; }
}
Now, use a final
instance of Settable
in your code; 现在,在代码中使用Settable
的final
实例; use set(...)
instead of the assignment, and get()
instead of a direct access: 使用set(...)
代替赋值,并使用get()
代替直接访问:
final Settable runForever = new Settable();
runForever.set(true);
...
while (runForever.get()) {
...
if (keyOther == 'F' || keyOther == 'f') runForever.set(false);
...
}
please did you read comment by @kleopatra in your previous post, not good idea to ignore that 请在上一篇文章中阅读@kleopatra的评论吗,不要忽略它
not never, not wrong direction, use KeyBindings and with Swing Action instead of KeyListener 永远不会,也不是错误的方向,请使用KeyBindings和Swing Action而不是KeyListener
accepted answer by @dasblinkenlight solved nothing in Swing, Swing and Java2D, use KeyBindings and with Swing Action, @dasblinkenlight接受的答案未解决Swing,Swing和Java2D中的任何问题,使用KeyBindings和Swing Action,
for example 例如
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class FullScreen {
private static final long serialVersionUID = 1L;
private JButton button = new JButton("Close Meeee");
private JPanel myPanel = new JPanel();
private JFrame frame = new JFrame();
public FullScreen() {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
myPanel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
};
myPanel.setFocusable(true);
myPanel.add(button);
frame.add(myPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setUndecorated(true);
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke("ENTER"), "clickENTER");
frame.getRootPane().getActionMap().put("clickENTER", updateBol());
frame.pack();
frame.setVisible(true);
updateCol().setEnabled(false);
updateDol().setEnabled(false);
}
private Action updateBol() {
return new AbstractAction("updateBol") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("updateCol is " + updateBol().isEnabled());
System.out.println("updateBol is " + updateCol().isEnabled());
System.out.println("updateDol is " + updateDol().isEnabled());
updateCol().actionPerformed(e);
updateDol().actionPerformed(e);
}
};
}
private Action updateCol() {
return new AbstractAction("updateCol") {
private static final long serialVersionUID = 1L;
private Boolean _enabled = false;
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("updateCol is " + updateCol().isEnabled());
if (updateCol().isEnabled()) {
} else {
}
}
public void setEnabled(Boolean bol) {
_enabled = bol;
}
@Override
public boolean isEnabled() {
return _enabled;
}
};
}
private Action updateDol() {
return new AbstractAction("updateDol") {
private static final long serialVersionUID = 1L;
private Boolean _enabled = false;
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("updateDol is " + updateDol().isEnabled());
if (updateCol().isEnabled()) {
} else {
}
}
public void setEnabled(Boolean bol) {
_enabled = bol;
}
@Override
public boolean isEnabled() {
return _enabled;
}
};
}
public static void main(String[] args) {
Runnable doRun = new Runnable() {
@Override
public void run() {
FullScreen fullScreen = new FullScreen();
}
};
SwingUtilities.invokeLater(doRun);
}
}
You can make final array of boolean of size 1 to store your flag. 您可以将大小为1的布尔值的最终数组存储为标志。 Even if array is final, it's elements are not, so you can modify array's elements from anonymous classes. 即使array是final,它的元素也不是,所以您可以从匿名类中修改array的元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.