繁体   English   中英

Swing Java旋转JLabel但文本被删除

[英]Swing Java Rotate JLabel but text be erased

我正在使用swing Java尝试用java做一些事情。 现在我想要旋转JLabel,我做到了。 但不幸的是,我在JLabel中的部分文本被删除了(如下图所示)。 我试过搜索,但似乎没有人像我一样有问题。 我猜它发生了导致它们重叠的JLabel。

在此输入图像描述

这是我的代码

serviceName[j] = new JLabel(name){
    protected void paintComponent(Graphics g) {

        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        AffineTransform aT = g2.getTransform();
        Shape oldshape = g2.getClip();
        aT.rotate(Math.toRadians(300));
        g2.setTransform(aT);
        g2.setClip(oldshape);
        super.paintComponent(g);
    }
};

你能帮我解决一下吗?

您应该在绘画后恢复原始变换和剪辑。 像这样

protected void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    AffineTransform aT = g2.getTransform();
    Shape oldshape = g2.getClip();

    g2.rotate(Math.toRadians(300));
    super.paintComponent(g);

    g2.setTransform(aT);
    g2.setClip(oldshape);
}

您可以从这个小程序中找到一些提示。 试验setPrefferedSize的值以获得更多想法。 如果仍然无法解决问题,请在上面的问题中修改并添加更多代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.*;

public class InclinedLabels extends JFrame{
    /** Creates a new instance of InclinedLabels */
    public InclinedLabels() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        JPanel jPanel1 = new JPanel();
        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        add(jPanel1);

        JPanel jPanel2 = new JPanel();
        jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel2.setPreferredSize(new Dimension(10, 100));
        add(jPanel2, BorderLayout.NORTH);


        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel1.setPreferredSize(new java.awt.Dimension(200, 200));
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-400)/2, (screenSize.height-352)/2, 300, 352);



        String str = "The quick brown fox jumps over the lazy dog";
        String[] word = str.split(" ");
        JLabel[] serviceName = new JLabel[str.length()];
        String name;
        for (int j=0; j<word.length; j++) {
            name = word[j];
            serviceName[j]  = new JLabel(name){
                protected void paintComponent(Graphics g) {

                    Graphics2D g2 = (Graphics2D)g;
                    g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                    AffineTransform aT = g2.getTransform();
                    Shape oldshape = g2.getClip();
                    aT.rotate(Math.toRadians(300));
                    g2.setTransform(aT);
                    g2.setClip(oldshape);
                    super.paintComponent(g);
                }
            };
            serviceName[j].setPreferredSize(new Dimension(50,20));
            serviceName[j].setBorder(BorderFactory.createLineBorder(Color.RED));
            jPanel1.add(serviceName[j]);
        }

    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new InclinedLabels().setVisible(true);
            }
        });
    }
}

更新:我找到了一个更接近的提示,可以解决这个问题。 这里最重要的因素是组件布局。 null布局允许重叠JLabel组件,因此它是此处使用的最合适的布局。 然后,您必须通过setBounds方法自定义标签的位置和大小。 在下面的代码中有serviceName[j].setBounds(xOffset + j*20,180, 170, 15); 因此,在每次循环迭代中,标签的x位置增加20.所有标签的大小为170 x 15.我还为组件放置了临时边框,以帮助理解输出。

import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;

public class InclinedLabels extends JFrame{

    /** Creates a new instance of InclinedLabels */
    public InclinedLabels() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-360)/2, (screenSize.height-352)/2, 360, 352);

        JPanel jPanel1 = new JPanel();
        jPanel1.setBorder(BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel1.setLayout(null);  // null layout allows overlapping of components
        add(jPanel1);

        JPanel jPanel2 = new JPanel();
        jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel2.setPreferredSize(new Dimension(10, 100));
        add(jPanel2, BorderLayout.NORTH);


        String str = "The quick brown fox jumpsssssssssssss123456 over the lazy dogssssssssssssss123456";
        String[] word = str.split(" ");
        JLabel[] serviceName = new JLabel[str.length()];
        String name;
        int xOffset = 30;
        for (int j=0; j<word.length; j++) {
            name = word[j];
            serviceName[j]  = new JLabel(name){
                protected void paintComponent(Graphics g) {
                    Graphics2D g2 = (Graphics2D)g;
                    g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                    AffineTransform aT = g2.getTransform();
                    Shape oldshape = g2.getClip();
                    aT.rotate(Math.toRadians(300));
                    g2.setTransform(aT);
                    g2.setClip(oldshape);
                    super.paintComponent(g2);

                }
            };

            serviceName[j].setBounds(xOffset + j*20,180, 170, 15); // experiment here
            serviceName[j].setBorder(BorderFactory.createLineBorder(Color.RED));

            jPanel1.add(serviceName[j]);
        }

    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new InclinedLabels().setVisible(true);
            }
        });
    }

}

我在上面的代码中找到的限制是父面板的宽度。 在该示例中,具有文本dogssssssssssssss123456的标签未完整打印。 这可以通过增加框架的宽度来克服,这又增加了jPanel1的宽度。

您的JLabel子类还应覆盖getPreferredSize()以报告旋转时的大小; 否则,任何使用询问组件的首选大小的布局管理器都将使用JLabel的版本,该版本假定文本是水平绘制的。

另一种方法是创建文本图标并将图标添加到JLabel,而不是尝试旋转组件。

创建TextIcon您可以创建一个旋转图标以添加到标签。 RotatedIcon将计算Icon的正确大小,因此标签的大小也是正确的,不需要自定义绘画。

所以基本代码是这样的:

JLabel label = new JLabel();
TextIcon textlIcon = new TextIcon(label, "Rotated Text");
label.setIcon( new RotatedIcon(textIcon, 300) );

编辑:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.io.*;

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        OverlapLayout layout = new OverlapLayout(new Point(20, 0));
        setLayout( layout );

        addLabel("one");
        addLabel("two");
        addLabel("three or more");
        addLabel("four");
    }

    private void addLabel(String text)
    {
        JLabel label = new JLabel();
        TextIcon textIcon = new TextIcon(label, text);
        label.setIcon( new RotatedIcon(textIcon, 300) );
        label.setVerticalAlignment(JLabel.BOTTOM);
        add(label);
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

此示例还使用“ 重叠布局”,以便可以将标签涂在彼此之上。

import java.awt.Color; 
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;

public class Test {
    public static void main(String[] args) {
        // Create the first label, which will be rotated later.
        Test.RotateLabel one = new Test.RotateLabel( "Rotated", 100, 100 );
        one.setRotation( 270 );
        JLayeredPane pane = new JLayeredPane();
        pane.setLayer( one, JLayeredPane.DEFAULT_LAYER );
        pane.add( one );
        pane.setBorder(new javax.swing.border.LineBorder(Color.BLACK,1));
        // Put the container pane in a frame and show the frame.
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( pane );
        frame.setSize( 500, 500 );
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }

    static class RotateLabel extends JLabel {
        private static final long serialVersionUID = 1L;
        private int angle = 0;
        public RotateLabel( String text, int x, int y ) {
        super( text );
        setBorder( new javax.swing.border.CompoundBorder( 
            new javax.swing.border.LineBorder( Color.red, 1), getBorder() ) );
        int width = getPreferredSize().width;
        int height = getPreferredSize().height;
        setBounds(x, y, width, height);
    }

    @Override
    public void paintComponent( Graphics g ) {
        Graphics2D gx = (Graphics2D) g;
        Shape old = gx.getClip();
        gx.rotate(-Math.toRadians(45), getWidth() / 2, getHeight() / 2);
        gx.setClip(old);
        super.paintComponent(gx);
    }

    public void setRotation( int angle ) { this.angle = angle; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM