我是Java新手,我尝试使用JLabel创建标题,并将其填充为渐变。我无法让它工作,我已经尝试了一段时间。我一直在抓住来自这里和其他网站的一些东西,似乎无法使这项工作成功,也无法理解其他人更复杂的代码。到目前为止,这是我的两个班级:
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
}
}
答案 0 :(得分:4)
有一个小小的"技巧"你实际上可以做到这一点,通过让标签保持透明,你可以在调用super.paintComponent
之前通过绘画实际绘制文本,例如......
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
仍然想要在组件下绘制
还有另外一招,但我两岁的女儿想检查圣诞老人是否在这里;)
<强>更新强>
另一个技巧是了解油漆过程的实际运作方式。当您调用super.paintComponent
时,它会调用update
上的ComponentUI
方法(外观和感觉委托),这实际上是填充背景的方法,如果组件是不透明的,那么此方法称之为代理的paint
方法,实际上是基础绘画...
我们可以稍微绕过这个过程而不是调用super.paintComponent
,我们可以直接调用代理的paint
方法...
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
绘制此组件下方的区域,但它可能不适用于所有外观
答案 1 :(得分:3)
问题在于你使JLabel不透明,这意味着它将绘制背景。因此,调用super.paintComponent(...)会绘制渐变背景。所以摆脱:
//this.setOpaque(true);
代码的另一个问题是color1.brighter()不起作用。尝试类似:
Color color2 = Color.RED;
此外,您不应更改Graphics对象,因为该对象也用于绘制其他Swing组件。相反,您应该使用g.create()
来获取Graphics对象的副本。对该对象进行更改,进行绘制,然后dispose()
对象。
所以(未经测试的)代码应该是这样的:
Graphics2D g2d = (Graphics2D)g.create();
...
g2d.fillRect(...);
g2d.dispose();
super.paintCompoenent(g);
答案 2 :(得分:2)
您应该将gradientPaint对象设置为Graphics,然后将其传递给super.paintComponent
试试这个:
public void paintComponent(Graphics g) {
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);
super.paintComponent(g2d);
}