3

I'm using Java Swing and I need to display a matrix with square brackets (normal square bracket like the one we use in math that spans more than one line), the matrix size is not fixed, it depends on the input.

Here is the code I'm using to display the matrix:

public static void printMatrix(String[][] matrix) {
        String output = "";
        for (int x = 0; x < matrix.length; x++) {
            output += Arrays.toString(matrix[x]) + "\n";
        }
        JOptionPane.showMessageDialog(null, output, "Matrix",
                JOptionPane.INFORMATION_MESSAGE);
    }

The output: Output Matrix

But I need to have one big connected square bracket as follows: enter image description here

So I'm searching on how to do this and I found this link https://docs.oracle.com/javase/tutorial/uiswing/components/border.html but it doesn't contain the brackets that I need and also found this https://team.mumie.net/mumie/mathletfactory_lib_apidocs/net/mumie/mathletfactory/display/noc/matrix/MatrixBorder.html#MatrixBorder%28java.awt.Component,%20int%29 but I didn't find any examples on how to use it.

Frakcool
  • 10,915
  • 9
  • 50
  • 89
  • and what did you try? – cello Jan 11 '17 at 15:06
  • How does this relate to the Swing library? Also, what have you tried so far? – CraigR8806 Jan 11 '17 at 15:07
  • Sounds like a rendering issue. Have you thought about using a LaTeX JavaScript engine in a browser frame? – duffymo Jan 11 '17 at 15:09
  • my code doesn't give me a connected bracket, so I was searching on how to do this and I found this link https://docs.oracle.com/javase/tutorial/uiswing/components/border.html but it doesn't contain the brackets that I need and also found this https://team.mumie.net/mumie/mathletfactory_lib_apidocs/net/mumie/mathletfactory/display/noc/matrix/MatrixBorder.html#MatrixBorder%28java.awt.Component,%20int%29 but I didn't find any examples on how to use it. The application is based on Swing, that's why I need to do this with Swing. I didn't try LaTeX, will search about this. – Samaa El-Komy Jan 11 '17 at 15:19
  • Try posting your swing code that is responsible for it - then it will be possible for us to help you. We need [Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve) with input that should work, but is not working. – Alex Baranowski Jan 11 '17 at 15:51
  • For better help sooner please post a valid [mcve], however I can think of drawing `[` and `]` with 3 lines, 2 horizontal short lines and 1 larger (as large as the matrix length) vertical line. With [Swing custom painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/) – Frakcool Jan 11 '17 at 16:42
  • Also check this [related question](http://stackoverflow.com/questions/17834573/swing-custom-border) and this [also related example](http://stackoverflow.com/questions/15025092/border-with-rounded-corners-transparency/16909994#16909994) – Frakcool Jan 11 '17 at 17:08
  • @AlexBaranowski I updated my question – Samaa El-Komy Jan 12 '17 at 11:30
  • @Frakcool okay, done. I'm currently checking the links you provided, thanks! – Samaa El-Komy Jan 12 '17 at 11:31

1 Answers1

3

Based on nIcE cOw's answer on one of my above comments, you need to create your own CustomBorder class that extends AbstractBorder and override its paintBorder() method to draw each part of the brackets.

In this case I divided this task in 3 parts, the top / bottom / left & right part of both brackets.

The internalGap variable is the space that should be between the content and the border

Here are some screenshots of how the output looks like:

With 2, 6 and 10 elements

enter image description here enter image description here enter image description here

The code that produces the above outputs is:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.AbstractBorder;

public class EquationMatrixBorder {

    private JPanel pane;
    private CustomBorder customBorder;
    private static final int ROWS_AND_COLS = 1;

    private void displayGUI() {
        JFrame frame = new JFrame("Custom Border Example");

        customBorder = new CustomBorder(Color.RED, 15, 10);
        pane = new JPanel();
        
        pane.setLayout(new GridLayout(ROWS_AND_COLS, ROWS_AND_COLS, 15, 15));
        //Used to fill the grid, not relevant to question
        Random random = new Random();
        for (int i = 0; i < ROWS_AND_COLS; i++) {
            for (int j = 0; j < ROWS_AND_COLS; j++) {
                int r = 0;
                if (j % 2 == 0) {
                    r = random.nextInt(2);
                } else {
                    r = random.nextInt(2) - 1;
                }
                pane.add(new JLabel(String.valueOf(r)));
            }
        }
        
        pane.setBorder(customBorder);
        frame.add(pane);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new EquationMatrixBorder().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

class CustomBorder extends AbstractBorder {
    
    private Color color;
    private int gap;
    private int bracketsTopAndBottom = 10;
    private int internalGap;
    
    public CustomBorder(Color color, int gap, int internalGap) {
        this.color = color;
        this.gap = gap;
        this.internalGap = internalGap;
    }
    
    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        super.paintBorder(c, g, x, y, width, height);
        Graphics2D g2d = null;
        if (g instanceof Graphics2D) {
            g2d = (Graphics2D) g;
            g2d.setColor(color);
            g2d.setStroke(new BasicStroke(3));
            
            //top part of brackets
            g2d.drawLine(x + gap, y + gap, x + gap + bracketsTopAndBottom, (y +  gap));
            g2d.drawLine(width - x - gap - bracketsTopAndBottom, y + gap, width - gap - x, (y +  gap));
            
            //bottom part of brackets
            g2d.drawLine(x + gap, height - gap, x + gap + bracketsTopAndBottom, height - gap);
            g2d.drawLine(width - x - gap - bracketsTopAndBottom, height - gap, width - gap - x, height - gap);
            
            //left and right part of brackets
            g2d.drawLine(x + gap, y + gap, x + gap, height - gap);
            g2d.drawLine(width - x - gap, y + gap, width - x - gap, height - gap);
        }
    }
    
    @Override
    public Insets getBorderInsets(Component c) {
        return getBorderInsets(c, new Insets(gap, gap, gap, gap));
    }
    
    @Override
    public Insets getBorderInsets(Component c, Insets insets) {
        insets.left = insets.top = insets.right = insets.bottom = gap + internalGap;
        return insets;
    }
}

Note

I haven't done rows and cols numbers shown in desired output of OP, I'm leaving that out as this question is only related to the square brackets

Community
  • 1
  • 1
Frakcool
  • 10,915
  • 9
  • 50
  • 89