循环内的监听器不允许更改局外布尔标志

在我之前的post之后,我写了一个听众:

@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 } 

目标

  1. 当我得到第二个fF (当我进入循环时我已经有一个f / F时,从循环中断开。

  2. 我需要将第二个听众附加到某个东西上吗?

但我无法将runForever更改为false,因为它是在外面写的。

即使我将其更改为final ,我也无法将其值更改为false

有什么方法吗?

注意 :我已经有一个用于输入开关盒的按键监听器!!

编辑:

 // 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 ... } 

最终变量不能更改,但如果它们代表可变对象,则可以更改该对象的内容。

例如,如果你创建一个Settable类,并使用它的实例而不是boolean ,你可以这样做:

 class Settable { private boolean flag; public boolean get() {return flag;} public boolean set(boolean val) { flag = val; } } 

现在,在代码中使用Settablefinal实例; 使用set(...)代替赋值,并使用get()而不是直接访问:

 final Settable runForever = new Settable(); runForever.set(true); ... while (runForever.get()) { ... if (keyOther == 'F' || keyOther == 'f') runForever.set(false); ... } 
  • 请你在上一篇文章中阅读@kleopatra的评论,不好意思忽略它

  • 从来没有,没有错误的方向,使用KeyBindings和Swing Action而不是KeyListener

  • @dasblinkenlight接受的答案在Swing,Swing和Java2D中没有解决任何问题,使用KeyBindings和Swing Action,

例如

 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); } } 

您可以创建大小为1的最终布尔数组来存储您的标志。 即使数组是最终的,它的元素也不是,所以你可以从匿名类中修改数组的元素。