简体   繁体   English

扩展JButton在鼠标悬停之前无法显示

[英]Extended JButton fails to appear until Mouse Over

So the situation is that I'm making a panel filled with 8*8 buttons, like a matrix, and I'm gonna have to change specific button texts depending on the position of the clicked button. 因此,情况是我正在制作一个由8 * 8按钮组成的面板,例如矩阵,并且我将不得不根据单击的按钮的位置更改特定的按钮文本。 It seemd like a good idea to make my own JButton where I can assign x and y indexes to the button, so I can check easily wich button was clicked by indexes. 制作自己的JButton似乎是个好主意,在这里我可以为按钮分配x和y索引,因此我可以轻松地检查索引是否单击了按钮。 Here is the code for that: 这是该代码:

import javax.swing.JButton;

public class MatrixButton extends JButton {
    private int x;
    private int y;

    public MatrixButton(int x, int y, String text){
        super(text);
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }
    public int getY() {
        return y;
    }
}

And it does solve the task, but these Matrix buttons doesn't want to appear until I mouse over them. 它确实解决了任务,但是这些“矩阵”按钮直到我将鼠标悬停在它们上之前都不想出现。 What could be the problem? 可能是什么问题呢?

here is the code for the panel wich contains these buttons and handles their actions: 这是包含这些按钮并处理其动作的面板代码:

public class PlayField extends JPanel implements ActionListener {
    private MatrixButton[][] button = new MatrixButton[8][8];

    public PlayField(){
        Random rand = new Random();

        setLayout(new GridLayout(8, 8));

        for (int i = 0; i < 8; ++i){
            for (int j = 0; j < 8; ++j){
                button[i][j] = new MatrixButton(j, i, "" + rand.nextInt(80));
                button[i][j].addActionListener(this);

                add(button[i][j]);
            }
        }
    }

    private String incrementText(MatrixButton mb){
        return "" + (Integer.parseInt(mb.getText()) + 1);
    }

    @Override
    public void actionPerformed(ActionEvent e){
        MatrixButton mb = (MatrixButton)e.getSource();

        for (int i = mb.getY(); i >= 0; --i){
            button[i][mb.getX()].setText(incrementText(button[i][mb.getX()]));
        }
        for (int i = 0; i < 8; ++i){
            if (i != mb.getX())
            button[mb.getY()][i].setText(incrementText(button[mb.getY()][i]));
        }
    }
}

PS: if I fill with ordinary JButtons they appear as they should be. PS:如果我用普通的JButton填充,它们将按原样显示。 Thats why I'm confused, cuz I didn't change much on the JButton extension just added 2 more variables to it. 这就是为什么我感到困惑的原因,因为我在JButton扩展上没有做太多改变,只是向它添加了2个变量。

This is dangerous code: 这是危险的代码:

public int getX() {
    return x;
}
public int getY() {
    return y;
}

You do realize that this overrides two of JButton's critical methods (actually, the methods are from JButton's parent, JComponent) that help set the placement of the button on the GUI (add @Override above the methods to see that this is so). 您确实意识到这将覆盖JButton的两个关键方法(实际上,这些方法来自JButton的父JComponent),这些方法有助于设置按钮在GUI上的位置(在方法上方添加@Override可以看到是这样)。 I strongly suggest that you either change the signature of these methods, perhaps getGridX() and getGridY() , or even better, use composition and not inheritance, since you run into risk of these types of problems -- unwittingly overriding a key method -- when you extend complex classes such as Swing component classes. 我强烈建议您更改这些方法的签名,也许是getGridX()getGridY() ,或者甚至更好,使用合成而不是继承,因为您会遇到这类问题的风险-不知不觉中覆盖了关键方法- -扩展诸如Swing组件类的复杂类时。 For this reason I try to avoid extending these classes unless absolutely necessary. 因此,除非绝对必要,否则我将尽量避免扩展这些类。

For example: 例如:

import java.awt.GridLayout;
import java.awt.event.*;
import java.util.Random;

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

public class PlayField {
    private static final int ROWS = 8;
    private static final int COLS = ROWS;
    private static final int MAX_RAND = 80;
    private JPanel mainPanel = new JPanel();
    private MatrixButton[][] button = new MatrixButton[ROWS][COLS];

    public PlayField(){
        Random rand = new Random();
        mainPanel.setLayout(new GridLayout(ROWS, COLS));
        for (int i = 0; i < ROWS; ++i){
            for (int j = 0; j < COLS; ++j){
                button[i][j] = new MatrixButton(j, i, rand.nextInt(MAX_RAND));
                button[i][j].addActionListener(new MyMatrixListener(i, j));
                mainPanel.add(button[i][j].getButton());
            }
        }
    }

    private class MyMatrixListener implements ActionListener {
        private int i;
        private int j;

        public MyMatrixListener(int i, int j) {
            this.i = i;
            this.j = j;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            for (int i2 = 0; i2 < button.length; i2++) {
                if (i2 != i) {
                    int value = button[i2][j].getValue();
                    value++;
                    button[i2][j].setValue(value);
                }
            }
            for (int j2 = 0; j2 < button[i].length; j2++) {
                if (j2 != j) {
                    int value = button[i][j2].getValue();
                    value++;
                    button[i][j2].setValue(value);
                }
            }
        }
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

    private static void createAndShowGui() {
        JFrame
        frame = new JFrame("PlayField");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new PlayField().getMainPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }    
}

class MatrixButton {
    private int column;
    private int row;
    private JButton button = new JButton();
    private int value;

    public MatrixButton(int column, int row, int value) {
        this.column = column;
        this.row = row;
        setValue(value);
    }

    public void addActionListener(ActionListener listener) {
        button.addActionListener(listener);
    }

    public int getColumn() {
        return column;
    }

    public int getRow() {
        return row;
    }

    public JButton getButton() {
        return button;
    }

    public int getValue() {
        return value;
    }

    public final void setValue(int value) {
        this.value = value;
        button.setText("" + value);
    }
}

Better to just use ints and not Strings 最好只使用整数而不是字符串

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

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