Это связано с Как получить X и Y индекс элемента внутри сообщения GridLayout? и ответы на него.
По какой-то причине никто из них не предлагал расширить JButton
, чтобы включить его положение в сетке и в связанный массив кнопок.
Я сделал следующую иллюстрацию, которая просто отображает координаты кнопки при нажатии.
Расширенный JButton
:
package buttons_array;
import javax.swing.*;
@SuppressWarnings("serial")
public class ButtonWithCoordinates extends JButton {
int coordX;
int coordY;
public ButtonWithCoordinates(String buttonText, int coordX, int coordY) {
super(buttonText);
this.coordX = coordX;
this.coordY = coordY;
}
/**
* @return the coordX
*/
public int getCoordX() {
return coordX;
}
/**
* @return the coordY
*/
public int getCoordY() {
return coordY;
}
}
Пример графического интерфейса:
package buttons_array;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonsArray implements ActionListener {
private ButtonWithCoordinates buttons[][];
private int nRows;
private int nCols;
private JFrame frame;
private JPanel panel;
public ButtonsArray(int x, int y) {
if (x > 0 && y > 0) {
nRows = x;
nCols = y;
buttons = new ButtonWithCoordinates[nRows][nCols];
for (int i=0; i < nRows; ++i) {
for (int j=0; j < nCols; ++j) {
buttons[i][j] = new ButtonWithCoordinates(" ", i, j);
buttons[i][j].addActionListener(this);
}
}
} else {
throw new IllegalArgumentException("Illegal array dimensions!!!");
}
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
ButtonWithCoordinates button = (ButtonWithCoordinates) e.getSource();
button.setText(button.getCoordX() + ", " + button.getCoordY());
}
public void GUI() {
if (buttons == null) { throw new NullPointerException("Array is not initialized!!!"); }
frame = new JFrame();
panel = new JPanel();
frame.setContentPane(panel);
panel.setLayout(new GridLayout(nRows, nCols));
for (int i=0; i < nRows; ++i) {
for (int j=0; j < nCols; ++j) {
panel.add(buttons[i][j]);
}
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ButtonsArray(3, 5).GUI();
}
});
}
}
Теперь мои вопросы:
Не изобретал ли я здесь велосипед? Я имею в виду, есть ли более простой способ добиться того же?
Это чем-то хуже, чем поиск в массиве каждый раз, когда нам нужно найти координаты?
1 ответ
Исходная версия этого примера использованное расширение:
GridButton extends JButton
Обновленная версия была основана на беседе, которую видели здесь. Хотя расширение может быть подходящим в некоторых контекстах, несколько альтернатив упоминаются здесь; недвижимость клиента особенно удобна. Идентифицировать кнопку по координатам сетки также легко:
private static final int N = 5;
List<JButton> list = new ArrayList<>();
…
private JButton getGridButton(int r, int c) {
int index = r * N + c;
return list.get(index);
}
JComponent
? У меня также есть один не связанный вопрос. В своем примере вы использовали EventQueue.invokeLater(...)
. Учебники, которые я видел, хотят, чтобы мы использовали SwingUtilities.invokeLater(...)
. Один больше подходит, чем другой?
SwingUtilities.invokeLater()
"просто прикрытие для java.awt.EventQueue.invokeLater()
". По дизайну см. Bloch, op cit. , особенно пункты 16 и 17.
Похожие вопросы
Связанные вопросы
Новые вопросы
java
Java - это язык программирования высокого уровня. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег редко используется отдельно и чаще всего используется вместе с [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] и [maven].
GridLayout
.b
- позволяет использовать либоGridLayout
, либоGridBagLayout
;c
- хотите привести примеры?