简体   繁体   English

Java Swing(带有ActionListener的问题)

[英]Java Swing (issue with ActionListener)

I have a take home assignment where I need to make a sudoku board that displays integers from a file on a board and allows someone to click a JButton and input a missing value. 我有一个家庭作业,我需要制作一个数独板,该板可显示板上文件中的整数,并允许某人单击JButton并输入缺少的值。

I have gotten the board to show up using JPanel and printed the text file to the individual buttons but I can't figure out how to get the addActionListener to pick up any of the buttons that are missing values. 我已经使用JPanel来显示板,并将文本文件打印到各个按钮上,但是我不知道如何获取addActionListener来拾取缺少值的任何按钮。 It only works for the last button that is blank. 它仅适用于空白的最后一个按钮。 (Blank buttons are given a value of 0). (空白按钮的值为0)。

my question is why is the last blank button only being targeted. 我的问题是为什么最后一个空白按钮仅作为目标。 There are 6 in total but only the last one brings up the dialogue box after being clicked? 共有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");
            }
        }
    }
}

The reason for the problem was already pointed out by Vyacheslav in https://stackoverflow.com/a/21803753 Vyacheslav已在https://stackoverflow.com/a/21803753中指出了问题的原因

Some hints: 一些提示:

You should use proper variable names. 您应该使用适当的变量名。 Calling a JButton b2 is horrible. 调用JButton b2太可怕了。 When it is a "Load" button, then call it loadButton . 当它是“加载”按钮时,将其loadButton When it is a "Save" button, call it saveButton . 当它是“保存”按钮时,将其称为saveButton Code is written (at most) once, but read possibly hundreds of times. 代码(最多)只编写一次,但可能读取数百次。 And Java code should read like prose, in the best case. 在最佳情况下,Java代码应像散文一样读。

Reading a file with a hard-coded name in the constructor, in order to build the GUI components, is a very bad practice. 在构造器中读取具有硬编码名称的文件以构建GUI组件是一种非常糟糕的做法。 You should consider creating some "Data model" that contains the information that you can create your GUI from, and split the process of 您应该考虑创建一些“数据模型”,其中包含可以用来创建GUI的信息,并拆分了

  1. reading the file and store the data in the data model, and 读取文件并将数据存储在数据模型中,以及
  2. creating the GUI from a data model. 从数据模型创建GUI。

This will also allow you to handle Exceptions better than by printing 这也将使您比通过打印更好地处理异常

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

In order to resolve your problem, you might consider using anonymous listeners . 为了解决您的问题,您可以考虑使用匿名监听器 Creating a single ActionListener that is responsible for all buttons is not very flexible. 创建负责所有按钮的单个ActionListener并不是很灵活。 Usually, you only want to associate a click on a button with a single call to a (private) method. 通常,您只想将按钮的单击与对(专用)方法的单次调用相关联。 So for example, you could write 因此,例如,您可以编写

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

Particularly for the case that you have several buttons wit similar functionality, this approach offers an advantage: You can create anonymous listeners for each button, each of them containing the required information about which button was clicked - roughly applied to your code: 特别是对于具有相似功能的多个按钮的情况,此方法具有一个优点:您可以为每个按钮创建匿名侦听器,每个侦听器都包含有关单击哪个按钮的必需信息-大致应用于您的代码:

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

你的错误很简单-每个迭代for你分配一个新JButton对象引用b4变量,以便最终b4是指持续JButton你创造。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM