The G-Meister The G-Meister - 4 months ago 17
Java Question

Allow text in multiple JLabels to overlap

Here's the context if it's necessary for any answers. I'm building an engine in which I'm going to make a videogame. It involves a 96 x 54 (columns x rows) table of letters, to keep an even spacing between them. Because of this, it would be very helpful if any solutions could be as least resource intensive as reasonably achievable. I made a web demo for this engine which worked exactly as intended, apart from being a bit slow. Now I am migrating the project over to Java, and some things aren't working quite as intended.

To mimic the HTML

<table>
I have used a
GridLayout
of
JLabel
s inside a couple
JPanel
s to keep the sizing constant, all inside a
JFrame
. The issue I'm facing is that, due to changing the size of the table to improve the look, the JLabels overlap slightly. In the web demo, this was fine, as the letters simply went into the next box. This is what I am trying to achieve in Java and cannot for the life of me find out how.

Here's an image to show you what I mean:

Here's an image to show you what I mean.

In the web demo on the left we have a circle of underscores inside a circle of "a"s, and the letters "pqyjg" on the right. There is also a small grey box on one of the underscores. This is the highlighted box below the underscore, showing that underscore overlaps 1 pixel into it.

When we put this same code into the Java version, the underscores are nowhere to be seen, and the tails on the letters "pqyjg" are cut off. The desired effect is for it to work like the example on the left.

I've searched this site, the rest of the internet and through many Java class pages in search of a method that will help, to no avail.

Can anyone point me to a class or method I could invoke on the
JLabel
s or any other component to achieve this effect, without changing the size of the table?

Here is my current code for setting everything up in case it helps anyone.

import javax.swing.*;
import static java.lang.Math.*;
import java.awt.*;

public class transparencyExample{

//Declaring constants
public static final Color[] MAINFRAME = {new Color(0x35ce4a), new Color(0x111111)};

//Creating static variables and methods
private static JLabel tempLabel;
private static JLabel[][] table = new JLabel[54][96];
private static JPanel layout = new JPanel(new GridLayout(54,96));
private static JPanel background = new JPanel();
private static BoxLayout box = new BoxLayout(background, 0);
private static JFrame frame = new JFrame("Transparency Example");
private static void initialise(){

//Adding labels to table
for (int i = 0; i < 5184; i++){
tempLabel = new JLabel("M", SwingConstants.CENTER);
tempLabel.setFont(new Font("Courier", Font.PLAIN, 15));
table[(int) floor((double) i / 96)][i % 96] = tempLabel;
}

//Laying out the table
layout.setPreferredSize(new Dimension(1056, 594));
layout.setOpaque(false);
for(int i = 0; i < 5184; i++){
layout.add(table[(int) floor((double) i / 96)][i % 96]);
}
background.setBackground(MAINFRAME[1]);
background.add(layout);

//Laying out the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(background);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

//Fill table
public static void fill(String s){
for(int i = 0; i < 5184; i++){
table[(int) floor((double) i / 96)][i % 96].setText(String.valueOf(s.charAt(i)));
}
}
public static void main(String[] args){
initialise();
transparencyExample.fill(" aaaaaaaa a a aa a _____ a a _ ___ a a_ __ a a _ _ a pqyjg aa _ _ a a _ _ a a _ _ a a _ _ a a _ _ a a _ _ a a __ _ a a __ __ a a _______ a a a a aa aa a aa aa aa aaaa ");
}
}

Answer

Per my comment:

... and I'm not 100% as to the effect you're trying to create and the problems that you may be having, but often problems in this category are due to trying to artificially constrain the sizes of components and containers

Yes, your problem is that you're artificially constraining the size of your layout JPanel with layout.setPreferredSize(new Dimension(1056, 594));, and this is preventing all the components that it holds to be well displayed. If you get rid of that line, and then you pack and setVisible(true) your JFrame, after filling it with data, you'll see the full text.


Your comment:

I was trying to keep the size of the table the same, but instead let the JLabels overlap so that their text can overflow from one into the other.

Consider option 2: don't use JLabels but rather draw your desired text directly into either a BufferedImage that is displayed in your JPanel's paintComponent method or directly within the JPanel's paintComponent method itself.