-1

i have the following grid with cells of size 10x10 and i am trying to write a certain number in the absolute middle of every cell. is there any way to do it?

the grid looks like this:

the grid is being created inside a public void paintComponent(Graphics g), is zoomable and has the following code:

g.setColor(Color.darkGray);
    for (int i = 0; i < getWIDTH(); i++) {
        g.drawLine(i * size, 0, i * size, HEIGHT);
    }
    for (int i = 0; i < getHEIGHT(); i++) {
        g.drawLine(0, i * size, WIDTH, i * size);
    }

update: i've managed to do this by using g.drawString method, but the text is not center and remains the same size when zooming in our out

****** SOLUTION *******

update: after trying my hand with multiple techniques, mostly weird and quite stupid actually, i found out a way to do it. the idea is that i am declaring a set of coordinates to be used in the drawString() method. the position is not perfect, but it does its job, and as someone once said, if it looks stupid but it works, then it ain't stupid. even the font is zoomable, increasing or decreasing in size when zooming in or out, and will only display if the size of the grid is bigger than 20px. the grid now looks like this (i gotta change the font tho):

the code is:

if(size > 20) {
                g.setColor(Color.darkGray);
                Font smallNumbers = new Font("SansSerif", Font.PLAIN, size/2);
                int x = j * size + size / 3;
                int y = i * size + (size * 100) / 145;
                g.setFont(smallNumbers);

                g.drawString("0", x, y);
            }

1 Answers1

2

There are two main ways that I know to do this:

  • A more difficult way where you use FontMetrics to calculate the estimated height and width of the text to display, get the width of the cell, and then calculate the x and y placement of your String and use this to draw it as per this answer

  • An easier way where you use a JLabel, set its Font, set its horizontal alignment to SwingConstants.CENTER, and then set its text to the desired text.

For my money, I'd go with the 2nd any chance I'd get. Note that instead of creating the grid in paintComponent, you could give the larger JPanel a GridLayout, and then fill it with JLabels. Cell borders can be achieved by either giving each JLabel its own LineBorder, and the enclosing JPanel a LineBorder, or by using the GridLayout constructor that takes 4 int parameters, giving the JPanel a background color, and making the labels opaque.

e.g.,

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout; 
import javax.swing.*;

@SuppressWarnings("serial")
public class MyGrid extends JPanel {
    private static final int ROWS = 200;
    private static final int COLS = 100;
    private static final Color TXT_COLOR = Color.DARK_GRAY;
    private static final Dimension LABEL_SZ = new Dimension(20, 20);
    private static final Font LABEL_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 10);
    private static final Color BG = new Color(140, 255, 200);
    private JPanel gridPanel = new JPanel(new GridLayout(ROWS, COLS));

    public MyGrid() {
        gridPanel.setBackground(BG);
        for (int r = 0; r < ROWS; r++) {
            for (int c = 0; c < COLS; c++) {
                char ch = (char)((int)(26 * Math.random()) + 'A');
                String text = String.valueOf(ch);
                JLabel label = new JLabel(text, SwingConstants.CENTER);
                label.setForeground(TXT_COLOR);
                label.setFont(LABEL_FONT);
                label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
                label.setPreferredSize(LABEL_SZ);
                gridPanel.add(label);
            }
        }
        JScrollPane scrollPane = new JScrollPane(gridPanel);

        setLayout(new BorderLayout());
        add(scrollPane);
        setPreferredSize(new Dimension(800, 650));
    }

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

    private static void createAndShowGui() {
        MyGrid mainPanel = new MyGrid();
        JFrame frame = new JFrame("My Grid");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
  • i think that it's quite difficult to do it with jpanels, since my grid can go as big as 1000x500 –  May 11 '19 at 11:23
  • @fr0ddo: why would that be difficult? – DontKnowMuchBut Getting Better May 11 '19 at 11:24
  • i was trying to get some more info and update the question and provide what i found, but it seems that i can't find anything. i'll try your method and i'll keep you updated. the reason for being a difficult task for me to use so much jpanels and gridlayouts is that i am not yet super familiar with gui programming –  May 11 '19 at 11:36
  • @fr0ddo: please see the link above as it shows how to center text in two very good answers. – DontKnowMuchBut Getting Better May 11 '19 at 11:37
  • i found a solution, i'm editing my question right now –  May 11 '19 at 20:22