How to get X and Y index of element inside GridLayout?
This example shows how to create a grid button that knows its location on the grid. The method getGridButton()
shows how to obtain a button reference efficiently based on its grid coordinates, and the action listener shows that the clicked and found buttons are identical.
package gui;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see http://stackoverflow.com/questions/7702697
*/
public class GridButtonPanel {
private static final int N = 5;
private final List<JButton> list = new ArrayList<JButton>();
private JButton getGridButton(int r, int c) {
int index = r * N + c;
return list.get(index);
}
private JButton createGridButton(final int row, final int col) {
final JButton b = new JButton("r" + row + ",c" + col);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton gb = GridButtonPanel.this.getGridButton(row, col);
System.out.println("r" + row + ",c" + col
+ " " + (b == gb)
+ " " + (b.equals(gb)));
}
});
return b;
}
private JPanel createGridPanel() {
JPanel p = new JPanel(new GridLayout(N, N));
for (int i = 0; i < N * N; i++) {
int row = i / N;
int col = i % N;
JButton gb = createGridButton(row, col);
list.add(gb);
p.add(gb);
}
return p;
}
private void display() {
JFrame f = new JFrame("GridButton");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(createGridPanel());
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new GridButtonPanel().display();
}
});
}
}
My way to get X and Y index of buttons inside GridLayout
The original version of this example used extension:
GridButton extends JButton
The updated version was predicated on the colloquy seen here. While extension may be appropriate in some contexts, a few alternatives are mentioned here; a client property is particularly convenient. Identifying a button from its grid coordinates is also easy:
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);
}
How to get the gridlayout cell position of a JButton in Java?
It's not the easiest thing to do... Likely it would be more useful to hold your JButton
s in a 2D array, or better hold a map of JButton
to position.
If you really must discern the gridcell from the button, call
JPanel.getComponents()
(or whatever the parent container is), and find your Button in there. Then do the math.
say you find it at index 6.
Then since your grid is x by y divide by x to get the row, and mod by x to get the column.
so say the grid ix 4x4
6/4 is 1, so you are in the row with index 1 (second row)
6 % 4 is 2, so you are in the column with index 2 (third column)
How to get components from a JFrame with a GridLayout?
This example compares two approaches:
Maintain a
List<JButton>
and calculate the index algebraically.Extend
JButton
and allow each button to maintain its own grid location.
GridLayout coordinates
I didn't test it but try this out:
for (int y = s-1; y >= 0; y--) {
for (int x = 0; x < v; x++) {
grid[x][y] = new JLabel((x)+","+(y));
world.add(grid[x][y]);
How should a JButton keep track of its position in a GridLayout?
You could simply create a class extending JButton
and adding two fields for the position in the grid. Create a new constructor (or setters) that assign values to theses fields, and two simple getters that will return them.
Example :
class MyJButton extends JButton {
private int gridx;
private int gridy;
public MyJButton(String label, int gridx, int gridy) {
super(label);
this.gridx = gridx;
this.gridy = gridy;
}
public int getGridx() {
return gridx;
}
public int getGridy() {
return gridy;
}
}
You can assign these gridx
,gridy
values when you build the GUI. For example, the following creates 16 buttons, labelled with their position in the grid :
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
MyJButton btn = new MyJButton(i + "," + j, i, j);
//Configure your button here...
panel.add(btn);
}
}
How to get the row/column location of a widget in a QGridLayout?
There are two notions of coordinates that you're mixing up. There is the position within the parent widget. That's available via QWidget::x()
, QWidget::y()
and QWidget::pos()
methods. You don't need to implement anything here: it already works.
Then there's the notion of the row and column within the grid layout. This can be obtained without a need for any subclassing. The grid layout knows where its widgets are, you can simply ask it for the row/column location of any widget.
#include <QtWidgets>
struct Pos { int row = -1, col = -1; };
Pos gridPosition(QWidget * widget) {
if (! widget->parentWidget()) return {};
auto layout = qobject_cast<QGridLayout*>(widget->parentWidget()->layout());
if (! layout) return {};
int index = layout->indexOf(widget);
Q_ASSERT(index >= 0);
int _;
Pos pos;
layout->getItemPosition(index, &pos.row, &pos.col, &_, &_);
return pos;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
QGridLayout l(&w);
QLabel gridPos;
l.addWidget(&gridPos, 0, 0, 1, 4);
for (int i = 1; i < 4; ++ i)
for (int j = 0; j < 3; ++ j) {
auto b = new QPushButton(QString("%1,%2").arg(i).arg(j));
l.addWidget(b, i, j);
QObject::connect(b, &QPushButton::clicked, [&gridPos, b]{
auto p = gridPosition(b);
gridPos.setText(QString("Grid Pos: %1,%2")
.arg(p.row).arg(p.col));
});
}
w.show();
return a.exec();
}
JButtons inside JPanels with a GridLayout JFrame
Here try this code example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LayoutExample extends JFrame
{
private static final String INITIAL_TEXT = "Nothing Pressed";
private static final String ADDED_TEXT = " was Pressed";
private JLabel positionLabel;
private JButton resetButton;
private static int gridSize = 4;
public LayoutExample()
{
super("Layout Example");
}
private void createAndDisplayGUI()
{
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 20));
contentPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2));
JPanel leftPanel = new JPanel();
leftPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2));
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
JPanel labelPanel = new JPanel();
positionLabel = new JLabel(INITIAL_TEXT, JLabel.CENTER);
JPanel buttonLeftPanel = new JPanel();
resetButton = new JButton("Reset");
resetButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
positionLabel.setText(INITIAL_TEXT);
}
});
labelPanel.add(positionLabel);
buttonLeftPanel.add(resetButton);
leftPanel.add(labelPanel);
leftPanel.add(buttonLeftPanel);
contentPane.add(leftPanel);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(gridSize, gridSize, 10, 10));
for (int i = 0; i < gridSize; i++)
{
for (int j = 0; j < gridSize; j++)
{
JButton button = new JButton("(" + i + ", " + j + ")");
button.setActionCommand("(" + i + ", " + j + ")");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JButton but = (JButton) ae.getSource();
positionLabel.setText(
but.getActionCommand() + ADDED_TEXT);
}
});
buttonPanel.add(button);
}
}
contentPane.add(buttonPanel);
setContentPane(contentPane);
pack();
setLocationByPlatform(true);
setVisible(true);
}
public static void main(String[] args)
{
if (args.length > 0)
{
gridSize = Integer.parseInt(args[0]);
}
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new LayoutExample().createAndDisplayGUI();
}
});
}
}
OUTPUT :
Related Topics
Maven: Add a Dependency to a Jar by Relative Path
How to Update a Jfreechart'S Appearance After It's Been Made Visible
Initialize Class Fields in Constructor or At Declaration
Best Implementation For Hashcode Method For a Collection
Why Do I Get an Unsupportedoperationexception When Trying to Remove an Element from a List
How to Refer to the Current Type With a Type Variable
Does Gc Release Back Memory to Os
How to Programmatically Close a Jframe
What Is "String Args[]"? Parameter in Main Method Java
Java Runtime.Getruntime(): Getting Output from Executing a Command Line Program
How to Get X and Y Index of Element Inside Gridlayout
How to Capitalize the First Character of Each Word in a String
To Prevent a Memory Leak, the Jdbc Driver Has Been Forcibly Unregistered
Are Getters and Setters Poor Design? Contradictory Advice Seen