简体   繁体   English

使用swing,JButtons等在程序上显示信息的问题

[英]Issue with displaying information on a program using swing, JButtons,etc

I'm making a multiplication table using swing.Its basically made up of JButtons. 我正在使用swing创建一个乘法表,它基本上由JButton组成。 The table is formed from input from the user. 该表由用户输入形成。 The user selects the size of the table by entering a number. 用户通过输入数字来选择表格的大小。 The last thing i need to do with this is create a heading that displays the numbers of the table created. 我要做的最后一件事是创建一个标题,该标题显示创建的表的编号。 Here is my sample code, if you run it, you'll see that its done for the vertical numbers. 这是我的示例代码,如果运行它,您将看到它已完成对垂直数字的处理。 How can i get the numbers above and properly formatted to represent each column. 我怎样才能得到上面的数字,并正确格式化以代表每一列。 Thank you. 谢谢。

package lab7;

import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GUIMultiplicationTable{
JFrame theFrame;
int number = 0;
JPanel panel, answerPanel, topPanel, leftPanel;
JLabel answerLabel, topLabel, leftLabel;

private void createAndShowGui(){
    String x;
    do{
        x = JOptionPane.showInputDialog(null, "Enter the number");
        number = Integer.parseInt(x);
    }while (number <= 0);
    theFrame = new JFrame("Multiplication Table");
    panel = new JPanel(new GridLayout(number, number));

    answerPanel = new JPanel();     
    answerLabel = new JLabel();

    topPanel = new JPanel();
    topLabel = new JLabel();

    leftPanel = new JPanel();
    leftLabel = new JLabel();


    for (int i = 0; i < number; i++){
        JLabel blah = new JLabel(Integer.toString(i + 1));
        panel.add(blah);//add center to label
        for (int j = 0; j < number; j++){

            JButton button = new JButton();
            if (i == 0){

                button.setText(String.valueOf(j + 1));
            }
            if (j == 0){
                button.setText(String.valueOf(i + 1));
            }
            for (int k = 1; k < number; k++)
            {
                if (i == k)
                {
                    button.setText(String.valueOf((j + 1) * (k + 1)));
                }
            }
            button.addActionListener(new ButtonsTableActionListener(i, j));
            panel.add(button);
        }   
    }

    answerPanel.add(answerLabel);
    theFrame.add(answerPanel, BorderLayout.SOUTH);

    topPanel.add(topLabel);
    theFrame.add(topPanel, BorderLayout.NORTH);

    theFrame.add(panel);
    theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    theFrame.pack();
    theFrame.setLocationRelativeTo(null);
    theFrame.setVisible(true);
}
public static void main(String[] args){
    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            GUIMultiplicationTable h = new GUIMultiplicationTable();
            h.createAndShowGui();
        }
    });
}

private class ButtonsTableActionListener implements ActionListener{
    private int theRow, theColumn;

    public ButtonsTableActionListener(int row, int column){
        theRow = row;
        theColumn = column;
    }

    @Override
    public void actionPerformed(ActionEvent e){
        int value = (theRow + 1) * (theColumn + 1);
        answerLabel.setText("The value is: " + value + ".\nI got that by multiplying \n" +    (theRow + 1) + "x" + (theColumn + 1));
    }
};
}

The loop in your actionListener is not required, the source of the event is the button that triggered it, so you can simply do... 不需要actionListener的循环,事件的源是触发它的按钮,因此您只需执行...

JButton source = (JButton) e.getSource();
JOptionPane.showMessageDialog(theFrame, source.getText());

Instead. 代替。

Now having said that, I would, personally, use some kind of Map to link the JButton to the value, removing the need to have to try and cast the text of the button back to a numeric value (which I believe would be your next step), or store other information you might need to work with for the button (such as the values required to produce the answer)... 话虽如此,我个人将使用某种Map来将JButton链接到该值,从而无需尝试将按钮的文本强制转换回数字值(我相信这是您的下一个选择)步骤),或存储您可能需要使用该按钮的其他信息(例如产生答案所需的值)...

private Map<JButton, int[]> answers = new HashMap<JButton, int[]>(25);
//...

for(int i = 0; i < number; i++){
    for(int j = 0; j < number; j++){
        buttons[i][j] = new JButton();
        if(i ==  0) {
            buttons[i][j].setText(String.valueOf(j+1));
        }
        if(j == 0) {
            buttons[i][j].setText(String.valueOf(i+1));
        }
        for(int k = 1; k < number; k++){
            if(i == k){
                buttons[i][j].setText(String.valueOf((j+1) * (k+1)));
            }
        }
        panel.add(buttons[i][j]);
        // Store the answer here...
        answers.put(buttons[i][j], new int[]{i, j});
    }
}

//...

public void actionPerformed(ActionEvent evt) {
    JButton source = (JButton) e.getSource();
    int[] answer = answers.get(source);
    JPanel panel = new JPanel();
    JTextField[] fields = new JTextField[]{
        new JTextField(2),
        new JTextField(2)
    };
    panel.add(fields[0]);
    panel.add(new JLabel("x"));
    panel.add(fields[1]);
    panel.add(new JLabel(" = " + source.getText()));
    JOptionPane.showMessageDialog(theFrame, panel);
    // check the values of the fields against the
    // values of the answer
}

Everything you need to do is just putting a JLabel somewhere. 您需要做的只是将JLabel放在某个地方。

final JLabel resultLabel = new JLabel("Select a button!");

Note that it should be final to be able to use it in the ActionListener . 注意,它应该是final ,以便能够在ActionListener使用它。 In the ActionListener you already had the right way, just look at these few lines to make it happen: ActionListener您已经有正确的方法,只需查看以下几行即可实现:

ActionListener first = new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
         for(int i = 0; i < number; i++){
                for(int j = 0; j < number; j++){
                    if(buttons[i][j] == e.getSource()){

                       // write the equation to the label
                        resultLabel.setText(buttons[i][j].getText() 
                                          + " = " + (i+1) + " * " 
                                          + (j+1));
                       // since you found the button you can now break
                        break;
                    }
                }
         }
    }
};

Note the i+1 and j+1 . 注意i+1j+1 The buttons are indexed from 0 to number-1, so the button at (0,0) actually shows the result of 1*1. 按钮从0到数字1进行索引,因此(0,0)处的按钮实际显示1 * 1的结果。

This is also important for your next two lines of code: 这对于接下来的两行代码也很重要:

// you used i=1 and j=1, but you have to start with 0 to make it work for all buttons
for(int i = 0; i < number; i++){
    for(int j = 0; j < number; j++){
        buttons[i][j].addActionListener(first);
    }
}

At a last step you also have to show the the label. 在最后一步,您还必须显示标签。 If you just add it to the frame, as you do with the panel, you will see that you will not see it. 如果只是将其添加到框架中(就像在面板上所做的那样),您将看到看不到它。

theFrame.add(resultLabel);
theFrame.add(panel);

The problem is that theFrame doesn't have a layoutmanager yet. 问题是theFrame还没有theFrame器。 So use a new Layout here as well: 因此,也请在此处使用新的布局:

theFrame.setLayout(new GridLayout(2,1));

Of course there will be better choices or some nice tweeks to make the layout more beautiful. 当然,会有更好的选择或更好的tweek使布局更漂亮。

So as in sum how to change your code from top to bottom: 因此,总之,如何从上到下更改代码:

  • set a Layout for theFrame theFrame设置布局
  • create a new JLabel for the result of the click, make it final 为点击结果创建一个新的JLabel,使其最终
  • set the label's text in the actionPerformed() method actionPerformed()方法中设置标签的文本
  • add the label to theFrame 将标签添加到框架

You can also consider putting the Label into a new JPanel and add that Panel to theFrame. 您也可以考虑将Label放入新的JPanel并将该Panel添加到theFrame。

An easy way to do this is to store the position of the button in the ActionListener , you can accomplish this by making your own class extending ActionListener , instead of doing an anonymous class. 一种简单的方法是将按钮的位置存储在ActionListener ,您可以通过使自己的类扩展ActionListener来实现此目的,而不是执行匿名类。 This way the code executed by the button will already have the information it needs to accomplish whatever you want. 这样,按钮执行的代码将已经具有完成所需功能所需的信息。

Also you don't need the array of buttons, just add a button in the panel at a time, and at the same time add the actionListener. 另外,您不需要按钮数组,只需一次在面板中添加一个按钮,并同时添加actionListener。

This is your code cleaned up and working properly. 这是您的代码清理并正常工作。 Now, instead of showing a dialog do whatever you want to do. 现在,您无需执行任何对话框,而无需显示对话框。

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

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GUIMultiplicationTable
{
    JFrame theFrame;
    int number = 0;
    JPanel panel;

    private void createAndShowGui()
    {
        String x;
        do
        {
            x = JOptionPane.showInputDialog(null, "Enter the number");
            number = Integer.parseInt(x);
        } while (number <= 0);
        theFrame = new JFrame("Multiplication Table");
        panel = new JPanel(new GridLayout(number, number));
        for (int i = 0; i < number; i++)
        {
            for (int j = 0; j < number; j++)
            {
                JButton button = new JButton();
                if (i == 0)
                {
                    button.setText(String.valueOf(j + 1));
                }
                if (j == 0)
                {
                    button.setText(String.valueOf(i + 1));
                }
                for (int k = 1; k < number; k++)
                {
                    if (i == k)
                    {
                        button.setText(String.valueOf((j + 1) * (k + 1)));
                    }
                }
                button.addActionListener(new ButtonsTableActionListener(i, j));
                panel.add(button);
            }
        }
        theFrame.add(panel);
        theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        theFrame.pack();
        theFrame.setLocationRelativeTo(null);
        theFrame.setVisible(true);

    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run()
            {
                GUIMultiplicationTable h = new GUIMultiplicationTable();
                h.createAndShowGui();
            }
        });

    }

    private class ButtonsTableActionListener implements ActionListener
    {
        private int _row, _column;

        public ButtonsTableActionListener(int row, int column)
        {
            _row = row;
            _column = column;
        }

        @Override
        public void actionPerformed(ActionEvent e)
        {
            // /do something
            int value = (_row + 1) * (_column + 1);
            String message = "I'm the button in the position (" + _row + ", " + _column + ")\nMy value is " + value + " = " + (_row + 1) + "*" + (_column + 1);
            JOptionPane.showMessageDialog(theFrame, message);
        }
    };
}

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

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