0

I am new to Swing in Java and am trying to make a visual grid. I have some simple questions as to how to do the following. Here are some characteristics of the grid:

  1. For each square of the grid, I should be having an equivalent index(i,j) using which I can identify the square and place a text. Edit - (i,j) is the row/column value - the index of the square in the grid.

  2. The diagonals of the squares should be drawn and each of the four divisions of the square should be having a different color.

Any suggestions as to how to do so.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Dinesh
  • 2,194
  • 3
  • 30
  • 52
  • What's `i` and `j`? Are they column/row values? Points in space? Do you want the grid index or it's position on the screen (virtual vs actual)? – MadProgrammer Feb 07 '14 at 03:29
  • Each of the 4 colored areas in the square has a value from a table based on some algorithm. The color depends upon the value. Currently, it is just used as an indicator. But the user needs to select an initial square in the grid where I place a mark that it is initial. – Dinesh Feb 07 '14 at 04:38
  • I also plan to place a text in each of the region indicating that value. Hence, there is one text field to be placed in each of the four partitions of the square. – Dinesh Feb 07 '14 at 04:40
  • @AndrewThompson I need a text field because I need to change the text during the course of the algorithm. – Dinesh Feb 07 '14 at 16:17
  • @AndrewThompson I mean the program – Dinesh Feb 07 '14 at 16:27

4 Answers4

3

Given row and column you will need to know the number of columns per row. With this information you can simply do (row * columns) + column which will return the index of the square.

For example, with 8 columns per row, a request for

  • row = 0, column = 4, will return 4
  • row = 1, column = 4, will return 12
  • row = 0, column = 0, will return 0

Rendering the sections of the square is more complex and can be achieved in at least two ways. You could use a Polygon which generates a triangle for each section or Shape and simply use Graphics2D#fill to fill it.

This will come down to how you physically render each square...

Take a look at 2D Graphics for more details and this for an example of both.

A Shape would be much easier to rotate and position and would only require you to have a single instance (or a single instance for each square based on your needs), where as you would require at least 4 Polygons or do some fun rotation...

Updated with simple example

All done with rotating triangles...

Example

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DividedSquare {

    public static void main(String[] args) {
        new DividedSquare();
    }

    public DividedSquare() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private TriangleShape baseTriangle;
        private Color[] colors;

        public TestPane() {
            colors = new Color[]{Color.RED, Color.GREEN, Color.BLUE, Color.MAGENTA};
        }

        @Override
        public void invalidate() {
            super.invalidate();

            baseTriangle = new TriangleShape(
                    new Point(0, 0),
                    new Point(getWidth(), 0),
                    new Point(getWidth() / 2, getHeight() / 2));

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            String text[] = new String[]{
                "123.123",
                "456.789",
                "012.315",
                "678.921"
            };

            FontMetrics fm = g2d.getFontMetrics();

            double angel = 0;
            for (int index = 0; index < 4; index++) {
                g2d.setColor(colors[index]);
                Path2D rotated = rotate(baseTriangle, angel);
                g2d.fill(rotated);
                Rectangle bounds = rotated.getBounds();
                int x = bounds.x + ((bounds.width - fm.stringWidth(text[0])) / 2);
                int y = bounds.y + (((bounds.height - fm.getHeight()) / 2) + fm.getAscent());
                g2d.setColor(Color.WHITE);
                g2d.drawString(text[index], x, y);
                angel += 90;
            }
            g2d.setColor(Color.BLACK);
            g2d.drawLine(0, 0, getWidth(), getHeight());
            g2d.drawLine(getWidth(), 0, 0, getHeight());
            g2d.dispose();
        }

        public Path2D rotate(TriangleShape shape, double angel) {

            Rectangle bounds = shape.getBounds();
            int x = bounds.width / 2;
            int y = bounds.width / 2;

            return new Path2D.Float(shape, AffineTransform.getRotateInstance(
                    Math.toRadians(angel),
                    x,
                    y));

        }

    }

    public class TriangleShape extends Path2D.Double {

        public TriangleShape(Point2D... points) {
            moveTo(points[0].getX(), points[0].getY());
            lineTo(points[1].getX(), points[1].getY());
            lineTo(points[2].getX(), points[2].getY());
            closePath();
        }

    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • That's another valid way to go, custom draw the entire viewable area. I just prefer a `GridLayout` because it provides an easy way to delineate the different components contained within it. – Andrew Thompson Feb 07 '14 at 03:54
  • @AndrewThompson Agreeded. Think I prefer to create a `Square` component and put into a `GridLayout` or `GridBagLayout`...Put you'd still need to paint the sub sections ;) – MadProgrammer Feb 07 '14 at 03:59
  • @MadProgrammer I saw the posts regarding the triangle and shape. Could you please provide some sample code for one square with 4 triangles ( with text in them ) and the diagonal lines drawn? – Dinesh Feb 10 '14 at 04:13
  • Do you want the rotated with the triangle? – MadProgrammer Feb 10 '14 at 05:00
  • @MadProgrammer I want to have a square with diagonal lines with each of the four partitions having a different color. I also would like to have a text placed in each of the 4 partitions. I did not understand what you meant by rotated. Hope I have made myself clear. – Dinesh Feb 10 '14 at 16:29
  • Do you the text aligned horizontally or aligned with the rotation of the section? – MadProgrammer Feb 10 '14 at 20:03
  • @MadProgrammer The text needs to be horizontally aligned. The text consists of floating point numbers like 2.345,-13.583 etc – Dinesh Feb 10 '14 at 23:57
  • @MadProgrammer I did not understand the function of the line `rotated.transform(AffineTransform.getTranslateInstance(0, 0));` That line does not seem to make any difference to the code. – Dinesh Feb 12 '14 at 05:00
  • Probably got left in by mistake...thought I was going to need to translate the positions of the triangles after they were rotated... – MadProgrammer Feb 12 '14 at 05:03
  • @MadProgrammer Also, when I extend the code to a grid, I am unable to obtain the rotated triangles properly. I have changed the coordinates of the triangle but what else should I modify in the rotate function. Could we have a chatroom? – Dinesh Feb 12 '14 at 05:03
  • That process always confuses me... http://chat.stackoverflow.com/rooms/47281/visual-custom-grid – MadProgrammer Feb 12 '14 at 05:09
  • You should only need to create a single Triangle, in theory...which you then create rotated instances and translate into the position you want. – MadProgrammer Feb 12 '14 at 05:10
  • @MadProgrammer I would like to have the text closer to the borders rather than the center. The text in the left triangle should start from the left. The text in the top triangle should start just below the upper line of the square. The text in the right triangle should end at the border of the right triangle and so on. Could you help in this. – Dinesh Feb 14 '14 at 21:08
  • @MadProgrammer Could you help me with this question: http://stackoverflow.com/questions/21995995/unable-take-screenshot-of-jframe-java-swing – Dinesh Feb 24 '14 at 20:04
2

Yes, see Making a robust, resizable Chess GUI for a GUI that uses a GridLayout to contain JButton objects. The buttons are held in an 8x8 array (the chessboard), while displayed in a 9 row x 9 column grid layout to accommodate the row (8-1) & column (A-H) identifiers of the board.

Buttons will accept an image that might represent the '4 color diagonal' and text. In the chess board I only use images (the chess pieces).

Edit 1

What is the actual difference between the 4 colored areas (besides the color). E.G. is there supposed to be different functionality depending on which of the diagonal areas the user clicks in?

Each of the 4 colored areas in the square has a value from a table based on some algorithm. The color depends upon the value. Currently, it is just used as an indicator. But the user needs to select an initial square in the grid where I place a mark that it is initial.

And the text. Should it be on top of the '4 color diagonal', beside it, below it..?

I also plan to place a text in each of the region indicating that value. Hence, there is one text field to be placed in each of the four partitions of the square.

Text field or label? A label can show text, but a text field makes it possible to copy the text or change it.

I need a text field because I need to change the text during the course of the algorithm.

By 'I' DYM the program, or the user? The program can change text in a label or text field, but the text field is user editable.

I mean the program

OK - Draw the design and text on an image. Use the image as a button icon. The user can select an initial square by clicking the button. If the text changes, generate a new image and set it to the button.

Edit 2

So do you mean that I have to create an image with 4 colors? Would that not be difficult. I would like to change the colors from the program itself. My algorithm would generate the values and at certain points of the algorithm, I would like to see the visualization.

Not if you generate the image at run-time.

How do I generate an image at run-time?

See the answer to Example images for code and mark-up Q&As The first set of Icons..

...

..As well as the Sprite sheet..

..were generated at run-time in Java code. Each set of images links to the question that includes the code that generated them.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • So do you mean that I have to create an image with 4 colors? Would that not be difficult. I would like to change the colors from the program itself. My algorithm would generate the values and at certain points of the algorithm, I would like to see the visualization. – Dinesh Feb 07 '14 at 16:41
  • How do I generate an image at run-time? – Dinesh Feb 08 '14 at 16:01
0

I believe you're describing the SetGridLayout feature in swing. If you want a tutorial on how to set up such a window, you can find it here:

http://docs.oracle.com/javase/tutorial/uiswing/layout/grid.html

After reading your question a second time... I think you plan on drawing a grid... I'd look into the Draw.java library

PSeUdocode
  • 412
  • 1
  • 4
  • 10
0

Maybe you can try to do this adding a jTable object, this object contains methods that can put values in every value i and j respectively like:

jTable1.setValueAt(Value, i, j);

this will allows you to change the value in every cell.