Why does part of my RichJLabel text look private / hidden?

I read the Swing Hacks book and used part of my code for the RichJLabel part. I understand what the code does, but not why part of the word is covered or looks hidden. This does not mean that he does not draw the entire text, because half of the “a” in the horizontal plane is missing.

//imported libraries for the GUI import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.*; import java.awt.Toolkit; import java.awt.Dimension; import java.awt.Container; import java.awt.BorderLayout; import java.awt.*; //Rich JLabel import java.awt.GraphicsEnvironment; import java.awt.Graphics2D; import java.awt.FontMetrics; import java.awt.RenderingHints; import java.awt.font.*; import javax.swing.ListSelectionModel; import java.awt.Color; import java.awt.Font; public class nameInterfaceOne { //Declared components static JFrame frame; static JPanel TotalGUI, northP, southP, eastP, centerP, westP; static JButton buttons; //Frame method public nameInterfaceOne() { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } //For a different look & feel, change the text in the speech marks catch (ClassNotFoundException e) {} catch (InstantiationException e) {} catch (IllegalAccessException e) {} catch (UnsupportedLookAndFeelException e) {} frame = new JFrame("Interface"); frame.setExtendedState(frame.NORMAL); frame.getContentPane().add(create_Content_Pane()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(500, 500); //Size of main window frame.setVisible(true); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); // gets & sets frame size/location int fw = frame.getSize().width; int fh = frame.getSize().height; int fx = (dim.width-fw)/2; int fy = (dim.height-fh)/2; //moves the frame frame.setLocation(fx, fy); } public JPanel create_Content_Pane() { TotalGUI = new JPanel(); TotalGUI.setLayout(new BorderLayout(5,5)); //set layout for the Container Pane northP = new JPanel(); northP.setBorder(new TitledBorder(new EtchedBorder(), "Label")); TotalGUI.add(northP, BorderLayout.NORTH); RichJLabel label = new RichJLabel("Horizontal", 1); label.setLeftShadow(1,1,Color.white); label.setRightShadow(1,1,Color.gray); label.setForeground(Color.black); label.setFont(label.getFont().deriveFont(20f)); Box top = Box.createHorizontalBox(); top.add(Box.createHorizontalStrut(10)); top.add(label); top.add(Box.createHorizontalStrut(10)); northP.add(top); //EAST Panel eastP = new JPanel(); eastP.setBorder(new TitledBorder(new EtchedBorder(), "Boxes")); TotalGUI.add(eastP, BorderLayout.EAST); Box right = Box.createVerticalBox(); right.add(Box.createVerticalStrut(20)); right.add(new JLabel("EAST SIDE!")); eastP.add(right); //WEST Panel westP = new JPanel(); westP.setBorder(new TitledBorder(new EtchedBorder(), "Buttons")); TotalGUI.add(westP, BorderLayout.WEST); Box left = Box.createVerticalBox(); left.add(Box.createVerticalStrut(10)); ButtonGroup JbuttonGroup = new ButtonGroup(); JButton buttons; JbuttonGroup.add(buttons = new JButton("One")); buttons.setToolTipText("This is Button One"); left.add(buttons); left.add(Box.createVerticalStrut(10)); JbuttonGroup.add(buttons = new JButton("Two")); buttons.setToolTipText("This is Button Two"); left.add(buttons); left.add(Box.createVerticalStrut(10)); JbuttonGroup.add(buttons = new JButton("Three")); buttons.setToolTipText("This is Button Three"); left.add(buttons); left.add(Box.createVerticalStrut(10)); westP.add(left); TotalGUI.setOpaque(true); return(TotalGUI); } //Main method calling a new object of public static void main(String[] args) { new nameInterfaceOne(); } } //RICH JLABEL CLASS class RichJLabel extends JLabel { private int tracking; public RichJLabel(String text, int tracking) { super(text); 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())*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(this.getForeground()); g.drawString(""+chars[i],x,h); x+=w; } ((Graphics2D)g).setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); } // end paintComponent() } 

enter image description here

Thanks in advance for any help :)

+4
source share
1 answer

Empirically, the problem disappears when you add a label directly to the (default) FlowLayout from northP .

 northP.add(label); 

enter image description here

Appendix: An alternative is to override getMaximumSize() , as suggested in How to use BoxLayout: specifying component sizes .

 @Override public Dimension getMaximumSize() { return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE); } 
+2
source

All Articles