【问题标题】:Cannot refer to non Final Variable (Array) [closed]不能引用非最终变量(数组)[关闭]
【发布时间】:2013-03-28 12:35:12
【问题描述】:

以下程序应该接收 4 位颜色代码电阻的用户输入,然后继续在 JFrame 中打印它(目前已为 BufferedReader 和 JFrame 设置)但是,我知道我不能简单地在将外部方法转化为内部方法。例如,我试图在输入通过后在动作监听器中打印 array3,但是我得到了那个错误。

我试图在 main 方法中将某些变量设置为 final,在互联网上搜索了各种页面,但仍然找不到解决我的具体问题的方法。我之前确实在这里问过这个问题,但是,它会导致更多的混乱,因为试图用自己的方法重写我的代码 JFrame 会导致近乎混乱,因此我不得不返回到我的原始代码。我想知道如何获取该用户输入并将其传递给 JFrame 下面的那些方法,因为我现在正在尝试的方法肯定行不通。

import java.io.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Arrays;
import javax.swing.JFrame;

public class test extends JFrame
{
  public static void main (String [] args) throws IOException
  {
    BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in));

    //calling variables
    String input;
    int numInput;

    JLabel l = new JLabel("Hello and welcome to the Program");
    l.setAlignmentX(0);
    l.setAlignmentY(0);

    //calling arrays
    int [] array = new int [5];
    int [] array2 = new int [3];
    String [] array3 = new String [3];
    String[] colours = {"black", "brown", "red", "orange", "yellow", "green", "blue", "violet", "gray", "white"};
    String[] tollerance = {"red", "gold", "silver", "no band"};



    JFrame f = new JFrame("Hello JFrame");
    f.setSize(500,500);
    //f.getContentPane().setBackground(Color.CYAN);
    f.add(l);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
    f.setLocationRelativeTo(null);
    //JTextField t = new JTextField(16);

    /*SodaMachine machine = new SodaMachine(); //class name
     JButton cokeButton = new JButton();
     cokeButton.addActionListener(new ActionListener() {
     public void actionPerformed() {
     machine.dispenseCoke();
     }
     }); */



     JPanel p = new JPanel ();
     JButton b = new JButton("Press me") ;
     b.setAlignmentX(0);
     b.setAlignmentY(0);

     test x = new test();
     b.addActionListener(new ActionListener(){
     public void actionPerformed (ActionEvent e) {
     JOptionPane.showMessageDialog(null,"In the following program you (The user!) will input a number of a resistor value \nThe program will pass the information into methods and then proceed to print out \nThe coorelating colors (Press the button to be asked for input)");
     int number = Integer.parseInt(JOptionPane.showInputDialog("Please enter the resistor value"));

     JOptionPane.showMessageDialog(null, "The Colors are : " + array3[i]);

     } 

     });

     p.add(b);
     p.add(l);
     //p.add(t);
     f.add(p);


     System.out.println("Hello and welcome to the Program (Press any key to con't)");
     input = myInput.readLine ();

     System.out.println("In the following program you (The user!) will input a number of a resistor value");
     System.out.println("The program will pass the information into methods and then proceed to print out");
     System.out.println("The coorelating colors (Press any key to be asked for input)");
     input = myInput.readLine();

     System.out.println("Enter a resistor value (Note that resistors can only acount to 4 decimal places");
     input = myInput.readLine ();
     numInput = Integer.parseInt (input);


     //colours for values
     array2 = values(array, input, colours);
     for(int i = 0 ; i < 3; i++){
     array3[i] = digitColours(array2[i], colours);
     System.out.println(array3[i]);// prints colours for values
     }

     //prints 4th colour for multiplier
     System.out.println(decimalPlaces(input, colours));
     //tollerance band
     System.out.println(tollerance(input, tollerance));

     } 

     public static int[] values (int [] digit, String num, String[] colours)
     {

     String holder;
     double numHolder;
     int lengthOfInput;
     int holder2;

     //Rounding of the input
     lengthOfInput = num.length() - 3;
     numHolder = Double.parseDouble(num);
     numHolder = numHolder/(Math.pow(10,lengthOfInput));
     numHolder = (int)(Math.round(numHolder)+0.5);

     // first three digits
     for(int i = 0; i < 3; i++){
     holder = num.substring(i,i+1);
     digit[i] = Integer.parseInt(holder);
     }

     return new int[] {digit[0], digit[1], digit[2]} ;// return
     }

     public static String digitColours(int decimalPlace, String[] colours){
     //calling additional variables
     String answer;
     answer = colours[decimalPlace];
     return answer;
     }


     //method to find the multiplier
     public static String decimalPlaces(String input, String[] colours){
     //calling additional variables
     int length = input.length();
     String answer;

     length = length - 3;
     answer = colours[length];

     return answer;
     }

     public static String tollerance(String num, String[] tollerance){

     String holder;
     int holder2;
     double perError;

     //tollerance
     holder = num.substring(3,4);
     perError = Double.parseDouble(holder);
     holder2 = Integer.parseInt(num);
     // checks to see if above 5
     if(perError < 5){
     perError = perError/holder2 * 100;
     }
     else if(perError > 5){
     perError = 10 - perError;
     perError = perError/holder2 * 100;
     }

     //changing for colour
     if(perError <= 2){
     perError = 0;
     }else if(perError <= 5){
     perError = 1;
     }else if(perError <= 10){
     perError = 2;
     }else if(perError <= 20){
     perError = 3;
     }

     return tollerance[(int)perError];
     }
     } 

【问题讨论】:

  • 很抱歉,您的班级声称正在重构。
  • 顺便说一句,问题是你不能在局部方法内部类中使用方法变量,至少它被声明为final
  • Aqua's answer to your previous question 很好地解释了编译错误。许多尝试使用 Swing 的 Java 程序员都会遇到此错误消息。我强烈建议您将代码缩减为SSCCE。像这样的基本编译器错误问题,无休止地被问到,除非以一种有可能帮助未来遇到类似问题的程序员的一般方式提出,否则不会有广泛的用处。
  • 链接不提供示例代码?
  • 代码示例应该是你的。

标签: java arrays swing jbutton actionlistener


【解决方案1】:

您的短期问题是您尝试使用内部类中方法的局部非最终变量。这可以通过使用 final 变量或类字段来解决(这里,因为它被用于静态方法,所以它必须是静态的)。

但是话虽如此,你的总体问题再次是你已经把所有东西都塞进了静态主方法(或任何类型的静态方法)事情)。您绝对需要创建可用于创建对象的类。我相信我们之前已经讨论过这个问题。


编辑

我改变了主意——你的“模型”,你决定显示什么颜色字符串的代码可能只包含静态方法。它可能有一个看起来像这样的方法:

public class ResistorColorsUtility {
   // create a String array, ALL_COLORS, as a constant that the methods 
   // of this class can use.
   private static final String[] ALL_COLORS = { "black", "brown", "red",
         "orange", "yellow", "green", "blue", "violet", "gray", "white" };

   public static String[] getColorsForValue(int value) {
      // code in here will create an array of Strings for the value given and
      // return it 

      // here use value int to find all the appropriate colors
      // create String array called result to hold the color Strings
      String[] result = ......; // you've got to create this code!

      return result; // return the result
   }

   // it will likely have other public methods that the GUI could use

   // and other private methods that it will only use internally 
   // and will not be used by other classes
}

GUI 具有用于输入和显示结果的字段,以及用于确定用户何时想要查看结果的按钮。 main 方法只是让程序运行,这里创建一个 JFrame 来放置主 GUI 代码的 JPanel,然后显示该 JFrame。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

// A very simple GUI to illustrate a point
public class ResistorGui extends JPanel {
   private JButton findColorButton = new JButton("Find Colors");
   private JTextField valueInputField = new JTextField(2);
   private JTextField resultField = new JTextField(15);

   public ResistorGui() {
      // user shouldn't be able to edit result field
      resultField.setEditable(false);
      resultField.setFocusable(false);

      findColorButton.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            // all program logic is in here

            // get value String from valueInputField
            // translate to int
            // call utility method from ResistorColorsUtil class!
            // display result in resultField
         }
      });

      add(new JLabel("Value:"));
      add(valueInputField);
      add(findColorButton);
      add(new JLabel("Result:"));
      add(resultField);
   }


   // all main does is to display the GUI, that's it
   public static void main(String[] args) {
      ResistorGui mainPanel = new ResistorGui();

      JFrame frame = new JFrame("ResistorGui");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }
}

【讨论】:

  • 我不完全确定如何创建这些类,创建新对象。
  • @SD:通常事情的顺序是在尝试编写包括 GUI 在内的复杂程序之前首先学习如何创建类和对象。你可以在这里了解它们:Lesson: Object-Oriented Programming Concepts
  • 我实际上只是设法让程序给我不同的错误,这似乎更容易通过简单地为 jframe 创建另一种方法来修复,而其他一切都进入主程序。错误只是说明 array3[i] 无法解析为变量,我想我可以将它传递给新的非静态方法并使其工作,除了 Jframe 不启动仅常规输入屏幕。
  • @SD:如果您只是坚持不懈并将大部分代码保留在静态方法中,那么您只会强化坏习惯并忽略我们给您的所有建议。既然我们只是在浪费时间试图给你一些经常被忽视的体面的建议,为什么还要给你建议呢?
  • 因为我花费了无数个小时、几天来试图理解这一点。通过我付出努力的事实,似乎引导我相信你们不愿意与我有效地合作。我已经阅读了各种教程和那些网站,只是简单地说它们没有意义。我没有时间继续阅读,阅读和阅读,我想要一些我可以真正理解并看似适用于我的程序的蹩脚术语。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
相关资源
最近更新 更多