swing – 为什么我的RichJLabel文本的一部分看起来被覆盖/隐藏?

我一直在阅读Swing Hacks书,并使用了他们的一些代码用于RichJLabel部分.我理解代码的作用,但不知道为什么某些单词被覆盖或看起来隐藏.并不是因为它没有绘制所有文本,因为即使水平中的’a’的一半也缺失了.

//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()
}

预先感谢您的任何帮助 :)

最佳答案 根据经验,将标签直接添加到northP的(默认)FlowLayout时问题就会消失.

northP.add(label);

附录:另一种方法是覆盖getMaximumSize(),如How to Use BoxLayout: Specifying Component Sizes所示.

@Override
public Dimension getMaximumSize() {
    return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
}
点赞