Java Swing(ActionListener问题)

时间:2014-02-15 21:05:23

标签: java swing

我有一个带回家的任务,我需要制作一个数独板,显示板上文件的整数,并允许有人点击JButton并输入缺失值。

我已经使用JPanel显示该板并将文本文件打印到各个按钮但我无法弄清楚如何让addActionListener获取任何缺少值的按钮。它仅适用于空白的最后一个按钮。 (空白按钮的值为0)。

我的问题是为什么最后一个空白按钮仅被定位。共有6个,但只有最后一个在点击后会弹出对话框?

public class MyCustomeFrame extends JFrame {
    private int[][] numbers;
    private String[] nums;
    JButton b1;
    JButton b2;
    JButton b3;
    JButton b4;

    private JPanel p2;

    public MyCustomeFrame() {
        // Create the border layout
        setLayout(new BorderLayout(5, 5));

        // Create a new panel for the buttons to be placed on
        JPanel p1 = new JPanel();

        // Create 3 buttons

        b1 = new JButton("Load");
        b2 = new JButton("Save");
        b3 = new JButton("Check");

        // Adds the 3 buttons to the panel
        p1.add(b1);
        p1.add(b2);
        p1.add(b3);

        // Create the event handlers for when the button is pressed
        b1.addActionListener(new MyButtonHandler());
        b2.addActionListener(new MyButtonHandler());
        b3.addActionListener(new MyButtonHandler());


        // Place the panel south in the window
        add(p1, BorderLayout.SOUTH);

        p2 = new JPanel();

        // Define the grid parameters
        p2.setLayout(new GridLayout(9, 9, 5, 5));

        // Show the grid
        add(p2, BorderLayout.CENTER);
        int[][] numbers = new int[9][9];
        int rowIdx = 0;



        //This is where i read the input file located on my computer and place the numbers on the Sudoku board
        try {
            BufferedReader bReader = new BufferedReader(new FileReader(
                "C:\\Users\\Derek\\Desktop\\input.txt"));

            String line = bReader.readLine();

            while (line != null) {
                nums = line.split(",");

                for (int i = 0; i < numbers[0].length; i++) {
                    numbers[rowIdx][i] = Integer.parseInt(nums[i]);

                    // This creates the individual buttons that are then placed on the board
                    if (numbers[rowIdx][i] >= 1) {
                        p2.add(new JButton(nums[i]));
                    } else {

                        //this is where I'm having the issue
                        b4 = new JButton(" ");
                        p2.add(b4);
                        b4.addActionListener(new MyButtonHandler());
                    }
                }

                rowIdx++;
                line = bReader.readLine();
            }
            bReader.close();
        } catch (FileNotFoundException g) {
            System.out.println("File Not Found!");
        } catch (IOException g) {
            System.out.println("Something went wrong...Try Again");
            g.printStackTrace();
        }
    }

    class MyButtonHandler implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == b1) {
                System.out.println("Loading File...");

            } else if (e.getSource() == b2) {
                System.out.println("Saving File...");

                try {
                    BufferedWriter bWriter = new BufferedWriter(new FileWriter(
                        new File("C:\\SudokuSave.txt"), true));

                    bWriter.close();

                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            } else if (e.getSource() == b3) {
                System.out.println("Checking Solution...");

            } else if (e.getSource() == b4) {
                System.out.println("clicked");
                JOptionPane.showInputDialog("Input a number between 1 - 9");
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

Vyacheslav在https://stackoverflow.com/a/21803753

中已经指出了问题的原因

一些提示:

您应该使用适当的变量名称。调用JButton b2非常糟糕。如果是“加载”按钮,则将其命名为loadButton。如果是“保存”按钮,请将其命名为saveButton。代码(最多)写入一次,但可能读取数百次。在最好的情况下,Java代码应该像散文一样阅读。

在构造函数中读取带有硬编码名称的文件,以构建GUI组件,这是一种非常糟糕的做法。您应该考虑创建一些“数据模型”,其中包含可以创建GUI的信息,并分割

的过程。
  1. 读取文件并将数据存储在数据模型中,
  2. 从数据模型创建GUI。
  3. 这也可以让您比打印更好地处理例外

    System.out.println("Something went wrong...Try Again");
    

    为了解决您的问题,您可以考虑使用匿名侦听器。创建一个负责所有按钮的ActionListener不是很灵活。通常,您只想将按钮上的单击与对单个(私有)方法的单个调用相关联。例如,您可以编写

    JButton saveButton = new JButton("Save");
    saveButton.addActionListener(new ActionListener() {
    {
        @Override
        public void actionPerformed(ActionEvent) {
            saveButtonWasPressed();
        }
    });
    

    特别是对于具有类似功能的多个按钮的情况,此方法提供了一个优势:您可以为每个按钮创建匿名侦听器,每个按钮包含有关的所需信息单击按钮 - 大致应用于您的代码:

    if (numbers[rowIdx][i] == 0) {
        JButton b = new JButton(" ");
        panel.add(b);
        b.addActionListener(createActionListener(rowIdx, i));
    }
    
    ...
    
    private ActionListener createActionListener(
        final int row, final int column) {
        ActionListener actionListener = new ActionListener() {
        {
            @Override
            public void actionPerformed(ActionEvent) {
                System.out.println("Pressed button in row "+row+", column "+column);
            }
        };
        return actionListener;
    }
    

答案 1 :(得分:1)

您的错误很简单 - for的每次迭代都会为JButton变量分配一个新的b4对象引用,所以最后b4指的是最后JButton你创造了。