【问题标题】:How can I read a variable from an inner class in Java?如何从 Java 的内部类中读取变量?
【发布时间】:2017-03-02 09:47:58
【问题描述】:

我设计了这个方法来显示一个带有滑块的窗口,我需要返回该值。您能告诉我如何检索 JSlider 值吗?目前我收到错误消息:“从内部类引用的局部变量必须是最终的或有效的最终”?

private static int displayFontPanel(JFrame w){
    JFrame window = new JFrame("Font Settings");
    window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout());
    int fontSize = 14;
    window.setSize(400, 200);
    window.setLocationRelativeTo(w);
    JSlider fntSize = new JSlider(8,40,20);
    fntSize.addChangeListener(new ChangeListener() {
        public void stateChanged(ChangeEvent evt) {
            fontSize = ((JSlider)evt.getSource()).getValue();
        }
    });
    fntSize.setLabelTable( fntSize.createStandardLabels(8) );
    fntSize.setPaintLabels(true);
    panel.add(fntSize, BorderLayout.CENTER);
    window.setContentPane(panel);
    window.setVisible(true);
    return fontSize;
} 

【问题讨论】:

  • 错误已经告诉你该怎么做。变量必须是 final 才能在内部类中访问
  • 使它最终导致我另一个错误:无法为最终变量sliderValue sliderValue = ((JSlider)evt.getSource()).getValue(); 分配一个值;

标签: java class final anonymous-inner-class


【解决方案1】:

我会使用 AtomicInteger 而不是 int:

    private static int displayFontPanel(JFrame w){
      JFrame window = new JFrame("Font Settings");
      window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      JPanel panel = new JPanel();
      panel.setLayout(new BorderLayout());
      final AtomicInteger fontSize = new AtomicInteger(14);
      window.setSize(400, 200);
      window.setLocationRelativeTo(w);
      JSlider fntSize = new JSlider(8,40,20);
      fntSize.addChangeListener(new ChangeListener()   {
        public void stateChanged(ChangeEvent evt) {
            fontSize.set(((JSlider)evt.getSource()).getValue());
        }
      });
      fntSize.setLabelTable( fntSize.createStandardLabels(8) );
      fntSize.setPaintLabels(true);
      panel.add(fntSize, BorderLayout.CENTER);
      window.setContentPane(panel);
      window.setVisible(true);
      return fontSize.get();
}

【讨论】:

  • 哇!从来没有听说过这个,但是工作并且看起来更正统。
【解决方案2】:

将方法签名改为

public void stateChanged(final ChangeEvent evt) {

之后你就可以做到了

((JSlider) evt.getSource()).getValue()

这个答案比我更好地解释了为什么变量需要是最终的:https://stackoverflow.com/a/4732617/3061857

【讨论】:

  • 我做了更改,但这并没有解决任何问题。如何从 stateChanged 方法中获取 getValue?这是我的问题:错误:从内部类引用的局部变量必须是最终的或有效的最终 fontSize = ((JSlider)evt.getSource()).getValue();
【解决方案3】:

代码错误是否真的与滑块有关,而不是fontSize?如果是后者,那么您必须稍微“欺骗”系统。闭包中引用的变量必须是最终的,即 - 在以下代码中未更改。

但如果你稍微作弊,将fontSize 声明为数组 (final int[] fontSize = new int[1]) 并修改其内容,一切都应该正常,如下所示:

fntSize.addChangeListener(new ChangeListener()   {
    public void stateChanged(ChangeEvent evt) {
        fontSize[0] = ((JSlider)evt.getSource()).getValue();
       }
    });

【讨论】:

  • 是的,它成功了。谢谢!但是为什么要这么复杂呢?!没有其他解决方案来解决这个问题吗?
猜你喜欢
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多