创建带有渐变的JLabel [英] Creating a JLabel with a Gradient

查看:62
本文介绍了创建带有渐变的JLabel的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Java的新手,我正在尝试使用JLabel创建标题并将其填充为渐变.我无法使其正常工作,并且已经尝试了一段时间.我一直在从这里和其他网站上获取一些信息,似乎无法使这项工作奏效,也无法理解其他人可以使用的更复杂的代码.到目前为止,这是我的两节课:

I'm new to Java and I'm trying to create a heading using a JLabel and for its fill to be a gradient. I cannot get it to work and I've been trying for a while. I've been grabbing bits of come from here and other websites and cannot seem to make this work, nor make sense of other peoples more complex code that does work. Here are my two classes so far:

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
public class Test {
    public static void main(String[] args) {
        new Test().setupGUI();
    }
    public void setupGUI() {
        //set up frames and buttons etc.
            JFrame theFrame = new JFrame ("Crystal Ball");
            theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel background = new JPanel();
            background.setBackground(Color.BLUE);
            background.setLayout(new BoxLayout(background, BoxLayout.PAGE_AXIS));
            theFrame.setSize(500,1000);
            DLabel heading = new DLabel("Guess a Number");
            heading.setText("GUESS A NUMBER");
            heading.setPreferredSize(new Dimension(theFrame.getWidth(),100));
            heading.setFont(new Font("Serif", Font.PLAIN, 40));
            heading.setAlignmentX(Component.CENTER_ALIGNMENT);
            //heading.setBackground(Color.YELLOW);
            heading.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
            background.add(heading);
            theFrame.getContentPane().add(background);
            theFrame.pack();
            theFrame.setVisible(true);
            //startGame();
        }
}

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BorderFactory;
import javax.swing.JLabel;

public class DLabel extends JLabel
{

    Dimension size = new Dimension(70, 80);

    public DLabel(String name)
    {
        this.setPreferredSize(size);
        this.setText(name);
        this.setBorder(BorderFactory.createBevelBorder(TOP, Color.white, Color.black));
        this.setOpaque(true);
    }

    public void paintComponent(Graphics g) {
      // super.paintComponent(g);  // *** commented
      Graphics2D g2d = (Graphics2D) g;
      Color color1 = Color.YELLOW;
      Color color2 = color1.brighter();
      int w = getWidth();
      int h = getHeight();
      GradientPaint gp = new GradientPaint(0, 0, color1, 0, h, color2);
      g2d.setPaint(gp);
      g2d.fillRect(0, 0, w, h);
      super.paintComponent(g); // *** added
    }

}

推荐答案

您实际上可以做一个小花样",通过使标签保持透明,您实际上可以在调用super.paintComponent之前通过绘画来在文本下进行绘画. ,例如...

There is one little "trick" you can actually do, by leaving the label transparent, you can actually paint under the text by painting BEFORE you call super.paintComponent, for example...

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestLabel101 {

    public static void main(String[] args) {
        new TestLabel101();
    }

    public TestLabel101() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JLabel {

        public TestPane() {
            setText("Happy, Happy");
            setForeground(Color.WHITE);
            setHorizontalAlignment(CENTER);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            LinearGradientPaint lgp = new LinearGradientPaint(
                    new Point(0, 0), 
                    new Point(0, getHeight()), 
                    new float[]{0.142f, 0.284f, 0.426f, 0.568f, 0.71f, 0.852f, 1f}, 
                    new Color[]{Color.PINK, Color.MAGENTA, Color.BLUE, Color.GREEN, Color.YELLOW, Color.ORANGE, Color.RED});
            g2d.setPaint(lgp);
            g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
            g2d.dispose();
            super.paintComponent(g);
        }

    }

}

nb:我应该指出,此过程效率不高,因为RepaintManager仍要在组件下方绘制

nb: I should point out that this process is inefficient, as the RepaintManager will still want to paint under the component

还有另一招,但我两岁的女儿想检查一下圣诞老人是否在这里;)

There is another trick, but my two year old daughter wants to check to see if Santa is here ;)

已更新

另一个技巧是了解绘画过程的实际工作方式.当您调用super.paintComponent时,它会调用ComponentUI上的update方法(外观委托),这实际上是在组件不透明时填充背景的方法,然后该方法调用外观委托的paint方法,实际上是在做基础绘画...

The other trick involves understanding how the paint process actually works. When you call super.paintComponent, it calls the update method on the ComponentUI (look and feel delegate), this is actually the method that fills the background if the component is opaque, this method then calls the look and feels delegate's paint method, which actually does the base painting...

我们可以略微规避该过程,而不是调用super.paintComponent,我们可以直接调用外观的委托人的paint方法...

We can circumvent the process slightly and instead of calling super.paintComponent, we can call the look and feels delegate's paint method directly...

public class TestPane extends JLabel {

    public TestPane() {
        setText("Happy, Happy");
        setForeground(Color.WHITE);
        setHorizontalAlignment(CENTER);
        setOpaque(true);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        LinearGradientPaint lgp = new LinearGradientPaint(
                new Point(0, 0), 
                new Point(0, getHeight()), 
                new float[]{0.142f, 0.284f, 0.426f, 0.568f, 0.71f, 0.852f, 1f}, 
                new Color[]{Color.PINK, Color.MAGENTA, Color.BLUE, Color.GREEN, Color.YELLOW, Color.ORANGE, Color.RED});
        g2d.setPaint(lgp);
        g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
        g2d.dispose();
        getUI().paint(g, this);
    }

}

这比上一个示例更有效,因为它不需要RepaintManager绘制该组件下方的区域,但可能无法在所有外观上起作用

This is more efficient then the previous example, as it doesn't require the RepaintManager to paint the area underneath this component, but it might not work with all look and feels

这篇关于创建带有渐变的JLabel的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆