【问题标题】:Simple ActionListener within a 2D array of JButtons二维 JButton 数组中的简单 ActionListener
【发布时间】:2012-03-07 05:14:09
【问题描述】:

好的,我正在制作一个二维 JToggleButtons 数组。我启动了动作监听器,但我无法分辨哪个按钮是哪个。

如果我点击一个,它返回的只是类似

javax.swing.JToggleButton[,59,58,19x14,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@53343ed0,flags=296,maximumSize=,minimumSize=,preferredSize= ,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled= false,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=]

是否有在按钮对象中粘贴某种项目或数字来关联每个按钮? 然后当点击按钮时,我可以检索给它的项目或号码?

这是我的按钮生成器代码。 (我怎样才能让“int l”关联(并计数)到每个按钮,当它被调用时,它会返回那个数字,或者类似的东西。

JToggleButton buttons[][] = new JToggleButton[row][col];
int l = 0;


        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                buttons[i][j] = new JToggleButton("");
                buttons[i][j].setSize(15,15);
                buttons[i][j].addActionListener(new e());
                panel.add(buttons[i][j]);
                l++;

            }
        }

动作列表器

public class e implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        System.out.println(source);
    }

}

变量“source”是我用来获取数据的,那么当一个按钮被点击时,如何通过“source”返回int l(作为点击的唯一按钮的唯一值)?

谢谢, -奥斯汀

【问题讨论】:

    标签: java swing actionlistener multidimensional-array jtogglebutton


    【解决方案1】:

    我做了一个扫雷游戏,遇到了类似的问题。您可以做到的唯一方法之一是获取单击按钮的绝对位置,然后将其除以按钮之间的 x 和 y,所以对我来说是

    if ((e.getComponent().getX() != (randx) * 25 && e.getComponent().getY() != (randy) * 25) &&bomb[randx][randy] == false) {
    

    此代码用于检查该区域是否有炸弹。所以我在炸弹位置之间有 25 x 和 y 的差异。这只会让您大致了解如何执行此操作。

    我相信:(左侧的 x - x 间距)/缓冲区 - 1 会起作用。

    【讨论】:

    • 我也在做扫雷!但是,难道没有更简单的方法来标记每个按钮吗? (在背景中)
    • 嗯,除此之外,您可以浏览所有按钮的列表并将其与组件进行比较,如果它排成一行,您就在其中。主要问题是,鼠标单击的点是与单击的组件相关,而不是完整的 Frame,因此您必须获取组件以使其唯一。
    【解决方案2】:

    您总是可以调用“e.getActionCommand()”来代替“e.getSource()”。对于每个按钮,您可以通过以下方式指定:

    JButton button = new JButton("Specify your parameters here"); /*you get these from getActionCommand*/
    button.setText("title here"); /*as far as I remember*/
    

    【讨论】:

    • 我的意思是你这些参数被回复到指定ActionListener实例的getActionCommand()方法
    • 但这会将文本添加到按钮中,我希望它们为空白。这是一款扫雷游戏。
    【解决方案3】:

    非常简单的方法是将 ClientProperty 添加到 JComponent,将定义添加到循环中,例如

    buttons[i][j].putClientProperty("column", i);
    buttons[i][j].putClientProperty("row", j);
    buttons[i][j].addActionListener(new MyActionListener());
    

    e 重命名为 MyActionListener 并更改其内容

    public class MyActionListener implements ActionListener {
    
        @Override
        public void actionPerformed(ActionEvent e) {
            JToggleButton btn = (JToggleButton) e.getSource();
            System.out.println("clicked column " + btn.getClientProperty("column")
                    + ", row " + btn.getClientProperty("row"));
    }
    

    编辑:

    对于MinerCraft,克隆不需要实现Listeners中的任何一个,只有大约Icon,在这段代码中找出(不要实现任何监听器并删除使用的ItemListener)

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class ButtonsIcon extends JFrame {
    
        private static final long serialVersionUID = 1L;
        private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
        private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
        private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    ButtonsIcon t = new ButtonsIcon();
                }
            });
        }
    
        public ButtonsIcon() {
            setLayout(new GridLayout(2, 2, 4, 4));
    
            JButton button = new JButton();
            button.setBorderPainted(false);
            button.setBorder(null);
            button.setFocusable(false);
            button.setMargin(new Insets(0, 0, 0, 0));
            button.setContentAreaFilled(false);
            button.setIcon((errorIcon));
            button.setRolloverIcon((infoIcon));
            button.setPressedIcon(warnIcon);
            button.setDisabledIcon(warnIcon);
            add(button);
    
            JButton button1 = new JButton();
            button1.setBorderPainted(false);
            button1.setBorder(null);
            button1.setFocusable(false);
            button1.setMargin(new Insets(0, 0, 0, 0));
            button1.setContentAreaFilled(false);
            button1.setIcon((errorIcon));
            button1.setRolloverIcon((infoIcon));
            button1.setPressedIcon(warnIcon);
            button1.setDisabledIcon(warnIcon);
            add(button1);
            button1.setEnabled(false);
    
            final JToggleButton toggleButton = new JToggleButton();
            toggleButton.setIcon((errorIcon));
            toggleButton.setRolloverIcon((infoIcon));
            toggleButton.setPressedIcon(warnIcon);
            toggleButton.setDisabledIcon(warnIcon);
            toggleButton.addItemListener(new ItemListener() {
    
                @Override
                public void itemStateChanged(ItemEvent e) {
                    if (toggleButton.isSelected()) {
                    } else {
                    }
                }
            });
            add(toggleButton);
    
            final JToggleButton toggleButton1 = new JToggleButton();
            toggleButton1.setIcon((errorIcon));
            toggleButton1.setRolloverIcon((infoIcon));
            toggleButton1.setPressedIcon(warnIcon);
            toggleButton1.setDisabledIcon(warnIcon);
            toggleButton1.addItemListener(new ItemListener() {
    
                @Override
                public void itemStateChanged(ItemEvent e) {
                    if (toggleButton1.isSelected()) {
                    } else {
                    }
                }
            });
            add(toggleButton1);
            toggleButton1.setEnabled(false);
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            pack();
            setVisible(true);
        }
    }
    

    【讨论】:

    • 确保还有另外两种方法(AFAIK)如何正确地做到这一点,也许你必须等待
    • 好的,另一个问题。我已经添加了这个。 if (bombloc == true) { button[i][j].putClientProperty("bomb", true); } else { 按钮[i][j].putClientProperty("bomb", false);我如何检查它是否真实,我知道我可以点击它并且它说真实,但是我如何通过 btn.getClientProperty 做出“if”语句?
    • 没关系,我也得到了这个工作。我想我只有最后一个关于 actionListener 是如何工作的问题。我有东西的图像图标,如何让当前的 btn(如果它是炸弹)显示炸弹符号?我知道如果它是炸弹并且所有图像都已加载,我只是不知道如何让图标更新 I.E. btn.setIcon(炸弹图像);
    • @Austin for MineCraft clone 不需要实现 ActionListener,你只需要 setIcon 并检查是否 isSelected,请查看我的编辑
    • 好的,我明白了,我让它工作了。现在我要寻找另一个问题,如何注册“rick-click”。我们必须用它在扫雷舰上放下我们的旗帜。
    【解决方案4】:

    只需将行和列数据添加到每个侦听器即可。您可以添加一个显式构造函数,但我建议添加一个小方法(以后可能会添加更多)。

                buttons[i][j].addActionListener(e(i, j));
    ...
    private ActionListener e(final int i, final int j) {
        return new ActionListener() {
            // i and j available here
            ...
    

    (在 JDK8 中,您应该能够使用 lambda 来减少语法混乱。)

    然后用更好的名字重命名它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多