Текст дублируется в JLabel - PullRequest
       11

Текст дублируется в JLabel

0 голосов
/ 07 февраля 2019

Я разрабатываю приложение для настройки поддона, и у меня есть класс, расширяющий JLabel, который я использую для создания JLabels с повернутым текстом.В Интернете я нашел несколько примеров того, как это сделать, и моя ротация работает достаточно хорошо, она не идеальна, но она находится в процессе разработки.
Проблема, с которой я столкнулся на данный момент, заключается в том, что текст в моих повернутых JLabelsдублируется, и я не знаю почему.Ниже приведена картинка, показывающая дублированный текст в каждой метке, в некоторых из них он более заметен, чем в других, например, с меткой высоты, отчетливо видно дублирование.

Дубликат текстового изображения ярлыка:
Duplicate Label Text Image

Вот исходный код моего RotatableText класса, который расширяет JLabel.

public class RotatableText extends JLabel 
{
    private static final long serialVersionUID = 1L;

    private String text;
    private double angle;

    public final static String DEGREES = "deg";
    public final static String RADIANS = "rad";

    private final static double TO_RADIANS = Math.PI/180;
    private final static double TO_DEGREES = 180/Math.PI;

    /**
     * Creates text rotated by angle in a clockwise direction if clockwise is true,
     * or anti-clockwise if it's false
     * @param angle angle to be rotated by in degrees
     * @param clockwise determines direction of rotation@exception Exception if angleUnit is not RotatableText.DEGREES or RotatableText.RADIANS
     */
    public RotatableText(String text, double angle, boolean clockwise, final String angleUnit) throws IllegalAngleUnitException 
    {
        if (!(angleUnit.equals(DEGREES) || angleUnit.equals(RADIANS)))
        {
            throw new IllegalAngleUnitException("Invalid Angle Selected");
        }
        else if (angleUnit.equals(DEGREES))
        {
            if (!clockwise)
            {
                this.angle = -angle * TO_RADIANS;
                super.setText(text);
            }
            else
            {
                this.angle = angle * TO_RADIANS;
                super.setText(text);
            }
        }
        else if (angleUnit.equals(RADIANS))
        {
            if (!clockwise)
            {
                this.angle = -angle;
                super.setText(text);
            }
            else
            {
                this.angle = angle;
                super.setText(text);
            }
        }
        setVerticalAlignment(JLabel.TOP);
        setHorizontalAlignment(JLabel.LEFT);

    }

    /**
     * Creates text rotated by angle in an anti-clockwise rotation
     * @param angle angle to be rotated by in degrees
     * @exception Exception if angleUnit is not RotatableText.DEGREES or RotatableText.RADIANS
     */
    public RotatableText(String text, double angle, final String angleUnit) throws IllegalAngleUnitException
    {
        if (!(angleUnit.equals(DEGREES) || angleUnit.equals(RADIANS)))
        {
            throw new IllegalAngleUnitException("Invalid Angle Selected");
        }
        else if (angleUnit.equals(DEGREES))
        {
            this.angle = angle * TO_RADIANS;
            super.setText(text);
        }
        else if (angleUnit.equals(RADIANS))
        {
            this.angle = angle;
            super.setText(text);
        }
        setVerticalAlignment(JLabel.BOTTOM);
        setHorizontalAlignment(JLabel.CENTER);
        }

    /**
     * Draws the Component
     */
    @Override
    protected void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        g2.rotate(angle, getPreferredSize().width/2, getPreferredSize().height/2);
        g2.drawString(super.getText(), 0, 0);
        setBounds(getX(), getY());
        super.paintComponent(g);
    }

    /**
     * Gets the text of this RotatableText.
     * @return text
     */
    public String getText()
    {
        return super.getText();
    }

    /**
     * Set's bounds with a fixed size
     */
    public void setBounds(int x, int y)
    {
        super.setBounds(x, y, 100, 100);
    }

    public void setText(String text)
    {
        super.setText(text);
        repaint();
    }

    /**
     * Set the angle of this RotatableText in Radians
     * @param angle
     */
    public void setAngle(double angle)
    {
        this.angle = angle;
        repaint();
    }

    /**
     * Sets the angle of this RotatableText in the specified unit
     * @param angle
     * @param angleUnit
     * @throws IllegalAngleUnitException
     */
    public void setAngle(double angle, String angleUnit) throws     IllegalAngleUnitException
    {
        if (!(angleUnit.equals(DEGREES) || angleUnit.equals(RADIANS)))
        {
            throw new IllegalAngleUnitException("Invalid Angle Selected");
        }
        else if (angleUnit.equals(DEGREES))
        {
            this.angle = angle * TO_RADIANS;
        }
        else if (angleUnit.equals(RADIANS))
        {
            this.angle = angle;
        }
        repaint();
    }

    /**
     * Gets the angle of this RotatableText, anti-clockwise from the horizontal, in degrees.
     * @return
     */
    public double getAngle()
    {
        return angle * TO_DEGREES;
    }
}

Каждая метка генерируется следующим образом (это метка длины)

lengthLabel = new RotatableText("0", 14, true, RotatableText.DEGREES);  

Каждая метка обновляется путем передачи получения текста из соответствующего текстового поля и передачи его в качестве аргумента для label.setText().

РЕДАКТИРОВАТЬ: печать System.out.println(heightLabel.getText()) печатает только одну копию текста.

Если у кого-то есть идея относительно того, почему происходит такое дублирование, я бы хотел их услышать.
Спасибо,
Сэм.

1 Ответ

0 голосов
/ 07 февраля 2019

Вы дважды рисуете свой текст в своем коде, как показано ниже:

@Override
protected void paintComponent(Graphics g)
{
    Graphics2D g2 = (Graphics2D) g;
    g2.rotate(angle, getPreferredSize().width/2, getPreferredSize().height/2);
    g2.drawString(super.getText(), 0, 0);  // ****** here *****
    setBounds(getX(), getY());
    super.paintComponent(g);             // ******* here ******
}

Кроме того, я бы не стал устанавливать границы компонента в методе рисования, что опасно, но нужно учитыватьустановив клип Graphics2D там.Также я бы сделал поворот на копию объекта Graphics, а затем избавился бы от копии, когда закончил.В противном случае вы рискуете распространить побочные эффекты вращения вниз по течению в цепочке окраски (если не хотите)

например,

@Override
protected void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.rotate(angle, getPreferredSize().width / 2, getPreferredSize().height / 2);
    // g2.drawString(super.getText(), 0, 0);
    // setBounds(getX(), getY());

    // ***** This is a kludge and needs to be calculated better ****
    Rectangle clipBounds = g2.getClipBounds();
    int extraBounds = 10;
    int x = clipBounds.x - extraBounds;
    int y = clipBounds.y - extraBounds;
    int width = clipBounds.width + 2 * extraBounds;
    int height = clipBounds.height + 2 * extraBounds;
    g2.setClip(x, y, width, height);
    // ***** end kludge

    super.paintComponent(g2);
    g2.dispose();
}
...