Java:修复数组 "linking" 以允许重置

Java: Fixing array "linking" to allow for resetting

首先,我知道列表在几乎(如果不是全部)各方面都更好。我在制作的编码器程序中遇到了一个重大错误。在这个程序中,我有一个按钮可以重置负责编码的 "wheels"(其中一个轮子在每个字母编码后旋转)。我有一个名为 wheelsOriginal 的最终 int[][],它应该存储名为 wheels 的 int[][] 的原始值。这两个数组都是 int[9][36]。我想要一种使 wheelsOriginal 在整个程序中保持不变的方法,而不是出于某种原因随 wheels 改变。这是重现问题的好方法(对于冗长的 intToChar 和 charToInt 方法感到抱歉!):

主要class:

import java.awt.*;
import javax.swing.*;

public class mainClass {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Encoder");
        frame.setBackground(new Color(225,225,225));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Display d = new Display();
        frame.add(d);
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
    }
}

显示class:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Display extends JPanel implements ActionListener {
    static JButton button;
    static JLabel letter;
    static int currentKey = -10;
    static int wheel = 0;
    static int[][] wheels = {
        {-3,10,-6,2,20,-7,22,5,23,4,6,-9,3,26,0,15,21,-2,13,14,12,1,17,11,-8,-5,18,8,24,9,25,7,19,16,-4,-1},
        {9,22,14,12,18,-3,3,6,16,1,-7,25,24,19,-8,8,21,20,5,-6,-2,26,15,-9,23,10,11,0,-5,4,-4,2,17,-1,13,7},
        {18,20,-9,15,12,-6,16,-4,-5,14,24,-7,-8,-3,-1,1,4,7,8,25,10,11,5,6,13,22,19,21,23,-2,3,26,17,9,0,2},
        {-3,10,-6,2,20,-7,22,5,23,4,6,-9,3,26,0,15,21,-2,13,14,12,1,17,11,-8,-5,18,8,24,9,25,7,19,16,-4,-1},
        {9,22,14,12,18,-3,3,6,16,1,-7,25,24,19,-8,8,21,20,5,-6,-2,26,15,-9,23,10,11,0,-5,4,-4,2,17,-1,13,7},
        {25,18,5,8,7,-8,4,11,6,-7,26,21,-1,24,15,23,9,-6,-2,13,16,22,-5,10,17,3,1,-9,0,12,2,19,-4,14,20,-3},
        {25,18,5,8,7,-8,4,11,6,-7,26,21,-1,24,15,23,9,-6,-2,13,16,22,-5,10,17,3,1,-9,0,12,2,19,-4,14,20,-3},
        {25,18,5,8,7,-8,4,11,6,-7,26,21,-1,24,15,23,9,-6,-2,13,16,22,-5,10,17,3,1,-9,0,12,2,19,-4,14,20,-3},
        {9,22,14,12,18,-3,3,6,16,1,-7,25,24,19,-8,8,21,20,5,-6,-2,26,15,-9,23,10,11,0,-5,4,-4,2,17,-1,13,7}
    };
    final static int[][] wheelsOriginal = wheels;

    public Display() {
        setPreferredSize(new Dimension(250,200));
        setFocusable(true);
        button = new JButton("Reset");
        button.setPreferredSize(new Dimension(225,50));
        button.setFont(new Font(button.getFont().getFontName(), button.getFont().getStyle(), 25));
        letter = new JLabel(" ", SwingConstants.CENTER);
        letter.setPreferredSize(new Dimension(225,100));
        letter.setFont(new Font(letter.getFont().getFontName(), Font.BOLD, 125));
        letter.setForeground(new Color(0,0,0));
        addKeyListener(
            new KeyListener() {
                public void keyPressed(KeyEvent e) {
                    if(currentKey == -10 && e.getKeyCode() >= 65 && e.getKeyCode() <= 90) {
                        currentKey = e.getKeyCode() - 64;
                        letter.setText(encode() + "");
                    }
                    else if(currentKey == -10 && e.getKeyCode() >= 48 && e.getKeyCode() <= 57) {
                        currentKey = -1 * (e.getKeyCode() - 48);
                        letter.setText(encode() + "");
                    }
                }
                public void keyReleased(KeyEvent e) {
                    currentKey = -10;
                    letter.setText(" ");
                }
                public void keyTyped(KeyEvent e) {}
            }
        );
        button.addActionListener(this);
        add(button, TOP_ALIGNMENT);
        add(letter);
    }

    public static char encode() {
        int key = currentKey;
        for(int i = 0; i < 9; i++) {
            key = wheels[i][key + 9];
        }
        for(int i = 8; i >= 0; i--) {
            key = wheels[i][key + 9];
        }
        rotate(wheels[wheel], isEven(wheel));
        if(wheel < 8) {
            wheel++;
        }
        else {
            wheel = 0;
        }
        return((char) key);
    }

    public static int[] rotate(int[] wheel, boolean positive) {
        int revolve;
        if(positive) {
            revolve = wheel[wheel.length - 1];
            for(int i = wheel.length - 2; i > 0; i--) {
                wheel[i + 1] = wheel[i];
            }
            wheel[0] = revolve;
        }
        else {
            revolve = wheel[0];
            for(int i = 1; i < wheel.length - 1; i++) {
                wheel[i - 1] = wheel[i];
            }
            wheel[wheel.length - 1] = revolve;
        }

        return wheel;
    }

    public static boolean isEven(int num) {
        return (num/2 == Math.abs(num/2));
    }

    public void actionPerformed(ActionEvent e) {
        if(e.getSource().equals(button)) {
            reset();
            grabFocus();
        }
    }

    public static void reset() {
        for(int[] i : wheels) {
            for(int x : i) {
                System.out.print(x + " ");
            }
            System.out.println("");
        }
        System.out.println(" ");
        for(int[] i : wheelsOriginal) {
            for(int x : i) {
                System.out.print(x + " ");
            }
            System.out.println("");
        }
        System.out.println(" ");
        wheels = wheelsOriginal;
        for(int[] i : wheels) {
            for(int x : i) {
                System.out.print(x + " ");
            }
            System.out.println("");
        }
        wheel = 0;
        letter.setText(" ");
        currentKey = ' ';
        System.out.println("Pressed");
    }
}

只要按下一个键,编码的字母就会出现在 window 中。即使反复按下同一个键,通常也会产生不同的字母。按重置按钮应重置编码器,以便按字母 'A' 三次应按顺序产生 S、E 和 Q。我还设计了这个,以便无论何时按下重置按钮,控制台都会打印出三大块数字。它们按顺序显示重置前的 wheels 数组、wheelsOriginal 数组和产品 wheels 数组。如果您多次按下按键并单击重置,您会注意到 wheelsOriginal 随轮子而变化。请帮忙...

您的问题是您正在创建 wheelsOriginal 作为 wheels 的参考而不是副本。这就是为什么当你更换轮子时,wheelsOriginal 也会改变。

final static int[][] wheelsOriginal = wheels;

类似这个循环的东西可以用来创建轮子的副本

int[][] wheelsOriginal = new int[wheels.length][];
for( int i = 0; i < wheelsOriginal.length; i++ )
{
    wheelsOriginal[i] = Arrays.copyOf( wheels[i], wheels[i].length );
}

此外,对于您的 charToIntIntToChar 方法 - 您可以使用字符是数字和 a->z A->Z 0->9 组合在一起以缩短它们的事实显着

我没有测试过 - 如果您决定使用这样的东西 - 请自己思考和测试

public int charToInt( char c )
{
    if( c >= '0' && c <= '9' ) {
        return '0' - c;
    } else if( c >= 'A' && c <= 'Z' ) {
        return c - 'A' + 1;
    } else if( c >= 'a' && c <= 'z' ) {
        return c - 'a' + 1;
    } else {
        return -10;
    }
}

public char intToChar( int c )
{
    if( c >= -9 && c <= 0 ){
        return (char)('0' - c);
    } else if( c >= 1 && c <= 26 ){
        return (char)(c + 'A' - 1);
    } else{
        return ' ';
    }
}