JTextArea has a setColumns method to set maximum number of columns, but JTextPane doesn't. Of course, it can have different fonts in a single pane, so setting number of columns or rows doesn't exactly make sense. However, when I create a dialog containing a JTextPane inside a JScrollPane and setText to a long string, it grows to the entire width of the screen and a single row, which I want to prevent.
setMaximumSize doesn't seem to have an effect and is not recommended at any rate (see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?).
My current solution, which seems quite ugly, is to extend JTextPane, borrowing code from JTextArea implementation:
textArea = new JTextPane() {
int maxWidth;
int rowHeight;
void init(Font font) {
FontMetrics fontMetrics = getFontMetrics(font);
maxWidth = fontMetrics.charWidth('M') * 80;
rowHeight = fontMetrics.getHeight();
}
{
initFont(getFont());
}
#Override
public void setFont(Font font) {
init(font);
super.setFont(font);
}
#Override
public Dimension getPreferredScrollableViewportSize() {
Dimension base = super.getPreferredSize();
Insets insets = getInsets();
int width = Math.min(maxWidth, base.width) + insets.left + insets.right;
int estimatedRows = Math.max(1, (int) Math.ceil(base.getWidth() / maxWidth));
int height = estimatedRows * rowHeight + insets.top + insets.bottom;
return new Dimension(width, height);
}
};
Related
I am new here.
I have a JLabel with a fixed size and an image in it placed with JLabel.CENTER. I wanted to know how does it place the image for example when the width of the image is 49px and the width of the label is 50px.
does the pixel comes at first or at the end of the label.
here the image in the jLabel (the jLabel has a border)
the real image
Thanks to those who will take time to read this
There is no guarantee of exactly how a JLabel’s icon will be centered when the number of surplus pixels is odd. You can observe the current behavior, of course, but there’s no guarantee a later Java version won’t do it differently.
If you want to be certain, you can create a subclass of JPanel, override the paintComponent and getPreferredSize methods, and draw the image yourself:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import javax.swing.JPanel;
public class ImagePanel
extends JPanel {
private static final long serialVersionUID = 1;
private Image image;
public ImagePanel(Image image) {
this.image = image;
}
#Override
public Dimension getPreferredSize() {
Insets insets = getInsets();
Dimension size = new Dimension(
insets.left + insets.right, insets.top + insets.bottom);
if (image != null) {
int width = image.getWidth(this);
int height = image.getHeight(this);
size.width += Math.max(width, 0);
size.height += Math.max(height, 0);
}
return size;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
int width = image.getWidth(this);
int height = image.getHeight(this);
if (width > 0 && height > 0) {
int widthDifference = getWidth() - width;
int x = widthDifference / 2;
if (widthDifference % 2 != 0) {
// If you want the extra space on the left:
//x++;
}
int y = (getHeight() - height) / 2;
g.drawImage(image, x, y, this);
}
}
}
}
I'm using JFreeChart and I want to customise the ToolTip by creating my own Class which extends ChartPanel and override createToolTip().
static private class PrivateChartPanel extends ChartPanel{
//constructors
#Override
public JToolTip createToolTip() {
JToolTip jtt = super.createToolTip();
jtt.setBackground(Color.WHITE);
jtt.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));
return jtt;
}
}
The problem is at Border. It is not rounded on all corners.
Why it is not rounded on all corners and how I could done it?
P.S.: I created a new simple project
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class HelloWorld {
public static void main(String[] args) {
JFrame a = new JFrame();
a.setBounds(100, 100, 100, 100);
a.setLayout(null);
JPanel b = new JPanel();
b.setBounds(5, 5, 50, 50);
b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));
a.add(b);
a.setVisible(true);
}
}
and Border of JPanel is with same problem. I'm using Java 10
The effect of rounded corners depends on the size of these rounded corners. In case of LineBorder, it is determined by the thickness property. This is how the relevant implementation code looks like:
int offs = this.thickness;
int size = offs + offs;
if (this.roundedCorners) {
float arc = .2f * offs;
outer = new RoundRectangle2D.Float(x, y, width, height, offs, offs);
inner = new RoundRectangle2D.Float(x + offs, y + offs, width - size, height - size, arc, arc);
}
else {
outer = new Rectangle2D.Float(x, y, width, height);
inner = new Rectangle2D.Float(x + offs, y + offs, width - size, height - size);
}
Path2D path = new Path2D.Float(Path2D.WIND_EVEN_ODD);
path.append(outer, false);
path.append(inner, false);
g2d.fill(path);
So it differentiates between inner and outer corner, which is not much meaningful for a line size of one. But even worse, the outer corner size is just offs, which is identical to thickness (one in your case) and the size of the inner rounded corner is determined by arc, which is .2f * offs. For your thickness of one, the resulting inner corner size is 0.2. So it seems to be a pure coincidence (rounding issue of these two different corners) that we see an effect in the upper left corner, as even the bigger outer corner size of one is not enough to create a visible rounded effect.
Here is how it looks like with a thickness of 20, which results in an outer corner size of 20 and a whopping inner corner size of 4:
It don’t know which actual use case the Swing developers had in mind when they added the rounded corner support in this class. I can’t imagine any scenario where this strategy is useful.
Implementing a meaningful Border is not that hard. One possible implementation looks like:
public class RoundedLineBorder extends AbstractBorder {
int lineSize, cornerSize;
Paint fill;
Stroke stroke;
private Object aaHint;
public RoundedLineBorder(Paint fill, int lineSize, int cornerSize) {
this.fill = fill;
this.lineSize = lineSize;
this.cornerSize = cornerSize;
stroke = new BasicStroke(lineSize);
}
public RoundedLineBorder(Paint fill, int lineSize, int cornerSize, boolean antiAlias) {
this.fill = fill;
this.lineSize = lineSize;
this.cornerSize = cornerSize;
stroke = new BasicStroke(lineSize);
aaHint = antiAlias? RenderingHints.VALUE_ANTIALIAS_ON: RenderingHints.VALUE_ANTIALIAS_OFF;
}
#Override
public Insets getBorderInsets(Component c, Insets insets) {
int size = Math.max(lineSize, cornerSize);
if(insets == null) insets = new Insets(size, size, size, size);
else insets.left = insets.top = insets.right = insets.bottom = size;
return insets;
}
#Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2d = (Graphics2D)g;
Paint oldPaint = g2d.getPaint();
Stroke oldStroke = g2d.getStroke();
Object oldAA = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
try {
g2d.setPaint(fill!=null? fill: c.getForeground());
g2d.setStroke(stroke);
if(aaHint != null) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, aaHint);
int off = lineSize >> 1;
g2d.drawRoundRect(x+off, y+off, width-lineSize, height-lineSize, cornerSize, cornerSize);
}
finally {
g2d.setPaint(oldPaint);
g2d.setStroke(oldStroke);
if(aaHint != null) g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldAA);
}
}
}
Now, when I change the line
b.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1, true));
in your example to
b.setBorder(new RoundedLineBorder(Color.BLACK, 1, 10, true));
I get
I'm trying to make a level editor for my platformer game, I want my levels to be 100 by 100 squares.
So far the editor works, but I can't scroll through the JPanel. I've been playing around and I've made a small test class to fiddle with which I'll post. If you run it, all it does it show the grid. However if I swap out two variables (I'll comment where) it can show an image and scroll according to the size of that image.
I want that scrolling ability only for the JPanel, so that I can scroll through my 100 x 100 square level.
import java.awt.BorderLayout;
public class ScrollPaneJ extends JFrame {
// setting the panels
private JPanel contentPane;
private JScrollPane scrollPane;
// dimensions/ variables of the grid
int size = 16;
int startX = 112;
int startY = 48;
int width = 30;
int height = 30;
// this is the grid
String[][] grid = new String[width][height];
// this is from the full editor class
String currentImage = new String("platform");
ImageIcon currentBackIcon = new ImageIcon("Resources/backdirttile.jpg");
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
// adding the scrollpane
ScrollPaneJ frame = new ScrollPaneJ();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ScrollPaneJ() {
setTitle("Scrolling Pane Application");
setSize(new Dimension(300, 200));
setBackground(Color.gray);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// defining the top and bottom panels, bottom is what I think I'm
// drawing on, top is where the scrollpanel goes, I copied this code
// from the internet and I'm not too sure how it works
JPanel topPanel = new JPanel();
JPanel bottomPanel = new JPanel(new GridLayout());
bottomPanel.setLayout(new BorderLayout());
getContentPane().add(bottomPanel);
topPanel.setLayout(new BorderLayout());
getContentPane().add(topPanel);
// this is the label I was talking about
Icon image = new ImageIcon("src/MenuDesign.jpg");
JLabel label = new JLabel(image);
// Create a tabbed pane
// if you set it to say label instead of bottomPanel, you can scroll
// through the size of the label
scrollPane = new JScrollPane(bottomPanel);
scrollPane.setBounds(40, 40, 100, 100);
// set it label here as well.
scrollPane.getViewport().add(bottomPanel);
// I was hoping this would force the scrollbar in but it does nothing
scrollPane
.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane
.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBounds(50, 30, 300, 50);
JPanel contentPane = new JPanel(null);
contentPane.setPreferredSize(new Dimension(500, 400));
contentPane.add(scrollPane);
topPanel.add(scrollPane, BorderLayout.CENTER);
init();
}
public void init() {
// this sets the grid to empty
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
grid[x][y] = "";
}
}
}
#Override
public void paint(Graphics g) {
// this paints the grid
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.black);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
g2d.drawRect(x * size + startX, y * size + startY, size, size);
if (grid[x][y].equals("")) {
g2d.drawImage(currentBackIcon.getImage(),
x * size + startX, y * size + startY, null);
}
g2d.setColor(Color.black);
g2d.drawRect((x * size) + 1 + startX, (y * size) + 1 + startY,
size, size);
}
}
}
public void drawTile() {
// this isn't enabled which is why you can't paint the grid, however it
// would change the tile of the square you're mouse is on, to the
// current tile, it works and isn't really important for what i need
// help with
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
int mouseX = (int) b.getX();
int mouseY = (int) b.getY();
int gMX = ((mouseX - 48) / 16) - 4;
int gMY = ((mouseY - 48) / 16) - 3;
grid[gMX][gMY] = currentImage;
repaint();
}
}
scrollPane.getViewport().add(bottomPanel); should be more like scrollPane.getViewportView(bottomPanel);
You shouldn't be painting directly to the frame, as child components can be painted without the notification to the parents, meaning that what ever you've painted could be partially wiped out. Instead, this kind of painting should be done within a custom component which acts as the JScrollPane's, JViewport's view.
A JScrollPane needs two things, first, the size that the component would like to be (the preferredSize) and the size of the viewport view. If the component doesn't implement the Scrollable interface, then the component's preferredSize is used to determine that as well. This is why a JLabel will work.
A JScrollPane has a JViewport as it's primary child component. The JViewport should only have a single component, typically assigned either via JScrollPane#setViewportView or JViewport#setView methods
See How to Use Scroll Panes for more details
Create a custom component that extends JPanel and override it's getPreferredSize method to return the size of the component you want. Override it's paintComponent method and perform you custom painting their.
Overlaying custom painting ontop of other components is more difficult
You can also add JScrollPane in your panel like this
JPanel p = new JPanel();
add(new JScrollPane(p));
I have a JTable with a few columns and potentially very many rows. I only want to display 3 rows at a time, and I want the width of the JTable to be 400, including the width of the scroll bar.
Here is the code I have so far:
public class SwingDrivesMeMad
{
public static void main(String[] args)
{
Object[][] rowData = { {"Homer", "beer"},
{"Marge", "wine"},
{"Bart", "coke"},
{"Lisa", "water"},
{"Maggie", "milk"} };
Object[] headerData = { "name", "beverage" };
JTable table = new JTable(rowData, headerData)
{
public Dimension getPreferredScrollableViewportSize()
{
return new Dimension(400, getRowHeight() * 3);
}
};
JScrollPane scrollPane = new JScrollPane(table);
JFrame frame = new JFrame("learn you a barkeep for great good!");
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
}
This is how it looks:
The height is perfect. Unfortunately, the width is 400 plus the width of the scrollbar, with a total of 415. This messes up the layout, because there is a graphics area with a fixed width of 400 directly above the table, and both components should line up perfectly. Having the table be slightly bigger just looks bad.
Of course I could simply set the width to 385, because on my system, scrollbars appear to take 15 pixels, but that does not seem very portable. Is there a better solution?
Unfortunately, none of the proposed solutions were pixel-perfect. So I came up with a hack:
How about trying a width of 400 first, then calculate the actual width, and finally correct for the excess?
JTable table = new JTable(rowData, headerData)
{
private static final int DESIRED_WIDTH = 400;
Dimension dim = new Dimension(DESIRED_WIDTH, Integer.MAX_VALUE);
{
JScrollPane dummy = new JScrollPane(this);
dummy.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JFrame frame = new JFrame();
frame.add(dummy);
frame.pack();
int actualWidth = dummy.getSize().width;
frame.dispose();
int excess = actualWidth - DESIRED_WIDTH;
dim = new Dimension(DESIRED_WIDTH - excess, getRowHeight() * 3);
}
public Dimension getPreferredScrollableViewportSize()
{
return dim;
}
};
Now scrollPane.getSize().width is exactly 400. Yes, it's a hack. But hey, it works!
Normally, I would just create the JLabel using a string as the first parameter and JLabel.CENTER as the second parameter; adding the label to the panel using BorderLayout.CENTER would then cause the text in the label to be aligned in the center of the panel.
However, I'm using the 'RichJLabel' class in order to get a drop shadow on my text. To do this, it overrides Component.paintComponent in such a way that the alignment information is lost, and the label's text is drawn in the top left of the panel no matter what I do.
From what I understand, the workaround for this is to encase the label inside of another panel; that way, I can align the panel itself inside the parent panel, but I'm uncertain of how exactly to do this.
My complete goal is to:
Figure out what font size a given string needs in order to fill up its parent JPanel
Add a drop shadow to that text
Center the text within its JPanel
Here's what I've got so far:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;
public class RichJLabel extends JLabel {
private int tracking;
public RichJLabel(String text, int tracking) {
super(text, JLabel.CENTER);
this.tracking = tracking;
}
private int left_x, left_y, right_x, right_y;
private Color left_color, right_color;
public void setLeftShadow(int x, int y, Color color) {
left_x = x;
left_y = y;
left_color = color;
}
public void setRightShadow(int x, int y, Color color) {
right_x = x;
right_y = y;
right_color = color;
}
public Dimension getPreferredSize() {
String text = getText();
FontMetrics fm = this.getFontMetrics(getFont());
int w = fm.stringWidth(text);
w += (text.length()-1)*tracking;
w += left_x + right_x;
int h = fm.getHeight();
h += left_y + right_y;
return new Dimension(w,h);
}
public void paintComponent(Graphics g) {
((Graphics2D)g).setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
char[] chars = getText().toCharArray();
FontMetrics fm = this.getFontMetrics(getFont());
int h = fm.getAscent();
int x = 0;
for(int i=0; i<chars.length; i++) {
char ch = chars[i];
int w = fm.charWidth(ch) + tracking;
g.setColor(left_color);
g.drawString(""+chars[i],x-left_x,h-left_y);
g.setColor(right_color);
g.drawString(""+chars[i],x+right_x,h+right_y);
g.setColor(getForeground());
g.drawString(""+chars[i],x,h);
x+=w;
}
((Graphics2D)g).setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
} // end paintComponent()
public static void main(String[] args) {
JPanel panel1 = new JPanel( new BorderLayout() );
panel1.setBackground( Color.BLUE );
panel1.setBorder( BorderFactory.createBevelBorder( BevelBorder.LOWERED ));
JPanel interiorPanel = new JPanel( new BorderLayout() );
panel1.add(interiorPanel, BorderLayout.CENTER);
RichJLabel label = new RichJLabel("100", 0);
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
label.setVisible( true );
label.setForeground( Color.YELLOW );
interiorPanel.add(label, BorderLayout.CENTER);
label.setFont(new Font("Arial", Font.BOLD, 140));
label.setFont(label.getFont().deriveFont(140f));
//resize code
Font labelFont = label.getFont();
String labelText = label.getText();
int stringWidth = label.getFontMetrics(labelFont).stringWidth(labelText);
int componentWidth = interiorPanel.getWidth();
// Find out how much the font can grow in width.
double widthRatio = (double)componentWidth / (double)stringWidth;
int newFontSize = (int)(labelFont.getSize() * widthRatio);
int componentHeight = interiorPanel.getHeight();
// Pick a new font size so it will not be larger than the height of label.
int fontSizeToUse = Math.min(newFontSize, componentHeight);
// Set the label's font size to the newly determined size.
label.setFont(new Font(labelFont.getName(), Font.BOLD, fontSizeToUse));
label.setLeftShadow(-3,-3,Color.BLACK);
// drop shadow w/ highlight
label.setRightShadow(2,3,Color.black);
label.setForeground(Color.gray);
JFrame frame = new JFrame("Label SSCCEE");
frame.getContentPane().add(panel1);
frame.pack();
frame.setVisible(true);
}
}
What it does right now is this:
The code was checking for the size of the container too soon. Before it is displayed, it has a width/height of 0.
Altered code
import java.awt.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;
public class RichJLabel extends JLabel {
private int tracking;
public RichJLabel(String text, int tracking) {
super(text, JLabel.CENTER);
this.tracking = tracking;
}
private int left_x, left_y, right_x, right_y;
private Color left_color, right_color;
public void setLeftShadow(int x, int y, Color color) {
left_x = x;
left_y = y;
left_color = color;
}
public void setRightShadow(int x, int y, Color color) {
right_x = x;
right_y = y;
right_color = color;
}
public Dimension getPreferredSize() {
String text = getText();
FontMetrics fm = this.getFontMetrics(getFont());
int w = fm.stringWidth(text);
w += (text.length()-1)*tracking;
w += left_x + right_x;
int h = fm.getHeight();
h += left_y + right_y;
return new Dimension(w,h);
}
public void paintComponent(Graphics g) {
((Graphics2D)g).setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
char[] chars = getText().toCharArray();
FontMetrics fm = this.getFontMetrics(getFont());
int h = fm.getAscent();
int x = 0;
for(int i=0; i<chars.length; i++) {
char ch = chars[i];
int w = fm.charWidth(ch) + tracking;
g.setColor(left_color);
g.drawString(""+chars[i],x-left_x,h-left_y);
g.setColor(right_color);
g.drawString(""+chars[i],x+right_x,h+right_y);
g.setColor(getForeground());
g.drawString(""+chars[i],x,h);
x+=w;
}
((Graphics2D)g).setRenderingHint(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
} // end paintComponent()
public static void main(String[] args) {
JPanel panel1 = new JPanel( new BorderLayout() );
panel1.setBackground( Color.BLUE );
panel1.setBorder( BorderFactory.createBevelBorder( BevelBorder.LOWERED ));
JPanel interiorPanel = new JPanel( new BorderLayout() );
panel1.add(interiorPanel, BorderLayout.CENTER);
RichJLabel label = new RichJLabel("100", 0);
label.setLeftShadow(-3,-3,Color.BLACK);
// drop shadow w/ highlight
label.setRightShadow(2,3,Color.black);
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
label.setVisible( true );
label.setForeground( Color.YELLOW );
interiorPanel.add(label, BorderLayout.CENTER);
label.setFont(new Font("Arial", Font.BOLD, 140));
label.setFont(label.getFont().deriveFont(140f));
//resize code
Font labelFont = label.getFont();
JFrame frame = new JFrame("Label SSCCEE");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setContentPane(panel1);
frame.pack();
frame.setVisible(true);
int componentWidth = interiorPanel.getWidth();
String labelText = label.getText();
int stringWidth = label.getFontMetrics(labelFont).stringWidth(labelText);
// Find out how much the font can grow in width.
double widthRatio = (double)componentWidth / (double)stringWidth;
int newFontSize = (int)(labelFont.getSize() * widthRatio);
int componentHeight = interiorPanel.getHeight();
// Pick a new font size so it will not be larger than the height of label.
int fontSizeToUse = Math.min(newFontSize, componentHeight);
System.out.println("fontSizeToUse: " + fontSizeToUse);
if (fontSizeToUse<1) {
System.err.println("Font size less than 1!");
System.exit(1);
}
// Set the label's font size to the newly determined size.
label.setFont(new Font(labelFont.getName(), Font.BOLD, fontSizeToUse));
label.setForeground(Color.gray);
}
}
If it is this RichJLabel, then take a look at paintComponent. I would sugges making your own shadowed label, maybe consisting out of two shadow labels and one foreground label. I did not expect to see a 3 times drawing of every character. Problematic: inefficient and cannot do scripting languages like arabic or combining diacritic characters (one char letter, another accent).
At some points hacking around isn't worth it. If you had seen the sources, who knows.
I am not sure that I have the right code. It certainly might be of a very early version.
RichJLabel has a getPreferredSize() suitable for layouting. JPanel.setBounds(int, int, int, int) is the single method by which resizing is done. Hence you can use absolute layouting in a JPanel (null layout).
public class EPanel2 extends JPanel {
private RichJLabel label = new RichJLabel("", 0);
public EPanel2(String text) {
super(null);
setBackground(Color.GREEN.brighter().brighter());
label.setFont(new Font("Univers", Font.BOLD, 48));
label.setText(text);
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
label.setForeground(Color.BLUE);
label.setLeftShadow(2, 2, Color.RED);
label.setRightShadow(2, 2, Color.ORANGE);
label.setVisible(true);
add(label);
}
#Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
Dimension labelSize = label.getPreferredSize();
int labelX = (width - labelSize.width) / 2;
int labelY = (height - labelSize.height) / 2;
label.setBounds(labelX, labelY, labelSize.width, labelSize.height);
}
}