我试图复制这个组件(在帖子的底部),但我似乎无法让它看起来不错。
所以我想知道,我该如何复制这种渐变涂料?或者如果它不是渐变涂料,我该怎么做才能得到类似的结果?
与此组件相比,我的尝试变得非常平坦。它还有JFrame选项(关闭,最小化等),它没有组件的“圆润”外观。我正在寻找能够改善我所拥有的东西并解释我哪里出错的人。我知道我可以简单地使用已经制作的外观,但我希望我的示例项目尽可能接近除了文本的图像中的BitDefender GUI。 (如果需要,我可以提供代码)
另请注意,我跳过了Background和'Virus Shield','Auto Scan','My BitDefender'面板之间的面板。我这样做主要是因为我想让我的SSCCE尽可能小。
另外我想要注意的是,在3 gbc.insets = new Insets(2,10,2,10);
上设置TopPanels
的插图使其看起来更接近BitDefender GUI的间距。 (我现在没有时间上传图片。所以我按原样保留了代码,但我确实知道它可以更新为上面的插图。
修改 - 更新了更多来源
这是我的代码/ SSCCE(它是3个单独的类,但我将它们合并为一个.java)
package testgui;
import java.awt.*;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TestGui {
public TestGui() {
JFrame frame = new JFrame();
MidPanel midPanel = new MidPanel();
TopPanel topPanel1 = new TopPanel();
TopPanel topPanel2 = new TopPanel();
TopPanel topPanel3 = new TopPanel();
JLabel appName = new JLabel("MyApplication");
JLabel verNum = new JLabel("version 1.0");
Font verFont = new Font("Tahoma", Font.BOLD, 11);
Font nameFont = new Font("Tahoma", Font.BOLD, 14);
GridBagConstraints gbc = new GridBagConstraints();
appName.setForeground(Color.WHITE);
appName.setFont(nameFont);
verNum.setForeground(Color.WHITE);
verNum.setFont(verFont);
//add program name and version number
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 5, 5, 5);
midPanel.add(appName, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 5, 5, 5);
midPanel.add(verNum, gbc);
//add 3 example top panels to midpanel
gbc.gridx = 0;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(1,2,1,2);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
midPanel.add(topPanel1, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.insets = new Insets(1,2,1,2);
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
midPanel.add(topPanel2, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(1,2,1,2);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
midPanel.add(topPanel3, gbc);
//add panel to push other panels to top
gbc.gridx = 0;
gbc.gridy = 5;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.weighty = 1.0;
JPanel invisPanel = new JPanel();
invisPanel.setOpaque(false);
midPanel.add(invisPanel, gbc);
frame.getContentPane().add(midPanel);
frame.pack();
frame.setVisible(true);
}
//test it out
public static void main(String[] args) {
new TestGui();
}
//class for the top 3 panels
private class TopPanel extends JPanel {
private int maxLength;
private boolean cyclic;
public TopPanel() {
initComponents();
setOpaque(false);
cyclic = true;
maxLength = 0;
}
@Override
public void paintComponent(Graphics g) {
if(isOpaque()) {
super.paintComponent(g);
return;
}
int width = getWidth();
int height = getHeight();
GradientPaint paint = null;
Color top = new Color(50, 50, 50);
Color btm = new Color(19, 19, 19);
paint = new GradientPaint(width / 2, 0, top, width / 2, maxLength > 0 ? maxLength : height, btm, cyclic);
if(paint == null) {
throw new RuntimeException("Invalid direction specified in GamerTagPanel");
}
Graphics2D g2d = (Graphics2D) g;
Paint oldPaint = g2d.getPaint();
g2d.setPaint(paint);
g2d.fillRect(0, 0, width, height);
g2d.setPaint(oldPaint);
super.paintComponent(g);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
private void initComponents() {
GridBagConstraints gbc;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
setBorder(BorderFactory.createLineBorder(new Color(204,204,204)));
setLayout(new GridBagLayout());
jLabel1.setFont(new Font("Tahoma", Font.BOLD, 11));
jLabel1.setForeground(new Color(255, 255, 255));
jLabel1.setText("Scanning...");
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(5, 5, 5, 5);
add(jLabel1, gbc);
jLabel2.setFont(new java.awt.Font("Tahoma", Font.BOLD, 11));
jLabel2.setForeground(new java.awt.Color(255, 255, 255));
jLabel2.setText("C:\\Directory\\Folder\\SubFolder\\SpecificFolder\\File.file");
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = 1.0;
gbc.insets = new Insets(5, 5, 5, 5);
add(jLabel2, gbc);
}
}
public class MidPanel extends JPanel {
private int maxLength;
private boolean cyclic;
public MidPanel() {
setLayout(new GridBagLayout());
setOpaque(false);
maxLength = 0;
cyclic = false;
}
@Override
public void paintComponent(Graphics g) {
if(isOpaque()) {
super.paintComponent(g);
return;
}
int width = getWidth();
int height = getHeight();
GradientPaint paint = null;
Color top = new Color(75, 75, 75);
Color btm = new Color(19, 19, 19);
paint = new GradientPaint(width / 2, 0, top, width / 2, maxLength > 0 ? maxLength : height, btm, cyclic);
if(paint == null) {
throw new RuntimeException("Invalid direction specified in GamerTagPanel");
}
Graphics2D g2d = (Graphics2D) g;
Paint oldPaint = g2d.getPaint();
g2d.setPaint(paint);
g2d.fillRect(0, 0, width, height);
g2d.setPaint(oldPaint);
super.paintComponent(g);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 400);
}
}
}
感谢JoopEggen在GradientPaint上指出我的颜色问题。它帮了很多忙。我仍然在寻找一个人来组织一个更好/更近看的例子。这是我第一次以这种方式覆盖paintComponent。
答案 0 :(得分:5)
让我们先做一些逆向工程。在此过程中,可以使用几种简化方式。此外,我想说也可以增强应用程序外观,因为第一印象远非积极。
基本上可以在该设计背后找到以下元素:
请注意,圆角,轮廓很重要。顺便说一句,一些渐变可以进行优化,以提供简洁的设计。请检查The Battle Between Flat Design And Skeuomorphism以获得更多动力。
您的示例已修改,看起来如下(它只是一个直观结果):
我使用了以下颜色:
代码:
public class TestGui {
public TestGui() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MidPanel midPanel = new MidPanel();
TopPanel topPanel1 = new TopPanel();
TopPanel topPanel2 = new TopPanel();
TopPanel topPanel3 = new TopPanel();
JLabel appName = new JLabel("MyApplication");
JLabel verNum = new JLabel("version 1.0");
Font verFont = new Font("Tahoma", Font.BOLD, 11);
Font nameFont = new Font("Tahoma", Font.BOLD, 14);
GridBagConstraints gbc = new GridBagConstraints();
appName.setForeground(Color.WHITE);
appName.setFont(nameFont);
verNum.setForeground(new Color(0xFF9f9f9f));
verNum.setFont(verFont);
//add program name and version number
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 5, 5, 5);
midPanel.add(appName, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(5, 5, 5, 5);
midPanel.add(verNum, gbc);
//add 3 example top panels to midpanel
gbc.gridx = 0;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(1,2,1,2);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
midPanel.add(topPanel1, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.insets = new Insets(1,2,1,2);
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
midPanel.add(topPanel2, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(1,2,1,2);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
midPanel.add(topPanel3, gbc);
//add panel to push other panels to top
gbc.gridx = 0;
gbc.gridy = 5;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.weighty = 1.0;
JPanel invisPanel = new JPanel();
invisPanel.setOpaque(false);
midPanel.add(invisPanel, gbc);
frame.getContentPane().add(midPanel);
frame.pack();
frame.setVisible(true);
}
//test it out
public static void main(String[] args) {
new TestGui();
}
//class for the top 3 panels
private class TopPanel extends JPanel {
private int maxLength;
private boolean cyclic;
public TopPanel() {
super(true);
initComponents();
setOpaque(false);
cyclic = true;
maxLength = 0;
}
@Override
public void paintComponent(Graphics g) {
if(isOpaque()) {
super.paintComponent(g);
return;
}
int width = getWidth();
int height = getHeight();
GradientPaint paint = null;
//Color top = new Color(50, 50, 50);
//Color btm = new Color(19, 19, 19);
Color top = new Color(0xFF222222);
Color btm = new Color(0xFF0c0c0c);
paint = new GradientPaint(width / 2, 0, top, width / 2, maxLength > 0 ? maxLength : height, btm, cyclic);
if(paint == null) {
throw new RuntimeException("Invalid direction specified in GamerTagPanel");
}
Graphics2D g2d = (Graphics2D) g;
Paint oldPaint = g2d.getPaint();
g2d.setPaint(paint);
g2d.fillRect(0, 0, width, height);
g2d.setPaint(oldPaint);
super.paintComponent(g);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
@Override
public void paintBorder(Graphics g) {
Dimension d = getSize();
g.setColor(new Color(0xFF484848));
g.drawRoundRect(1, 1, d.width-3, d.height-3, 10, 10);
g.setColor(Color.BLACK);
g.drawRoundRect(0, 0, d.width-1, d.height-1, 10, 10);
}
private void initComponents() {
GridBagConstraints gbc;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
setBorder(BorderFactory.createLineBorder(new Color(204,204,204)));
setLayout(new GridBagLayout());
jLabel1.setFont(new Font("Tahoma", Font.BOLD, 11));
jLabel1.setForeground(new Color(255, 255, 255));
jLabel1.setText("Scanning...");
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(5, 5, 5, 5);
add(jLabel1, gbc);
jLabel2.setFont(new java.awt.Font("Tahoma", Font.BOLD, 11));
jLabel2.setForeground(new Color(0xFF9f9f9f));
jLabel2.setText("C:\\Directory\\Folder\\SubFolder\\SpecificFolder\\File.file");
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = 1.0;
gbc.insets = new Insets(5, 5, 5, 5);
add(jLabel2, gbc);
}
}
public class MidPanel extends JPanel {
private int maxLength;
private boolean cyclic;
public MidPanel() {
setLayout(new GridBagLayout());
setOpaque(false);
maxLength = 0;
cyclic = false;
}
// public void paintBorder(Graphics g) {
// g.setColor(Color.RED);
// Rectangle bounds = getBounds();
// g.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 10, 10);
// }
@Override
public void paintComponent(Graphics g) {
if(isOpaque()) {
super.paintComponent(g);
return;
}
int width = getWidth();
int height = getHeight();
GradientPaint paint = null;
Color top = new Color(0xFF282828);
Color btm = new Color(0xFF0e0e0e);
paint = new GradientPaint(width / 2, 0, top, width / 2, maxLength > 0 ? maxLength : height, btm, cyclic);
if(paint == null) {
throw new RuntimeException("Invalid direction specified in GamerTagPanel");
}
Graphics2D g2d = (Graphics2D) g;
Paint oldPaint = g2d.getPaint();
g2d.setPaint(paint);
g2d.fillRect(0, 0, width, height);
g2d.setPaint(oldPaint);
super.paintComponent(g);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 400);
}
}
}
实施此用户界面的最佳方式
我认为唯一正确的方法是实现新的Look& Feel子集。看看project seaglass:
我使用了什么
所有这些示例都是使用Inkscape - 一个开源矢量图形编辑器准备的。 您可以下载我的SVG source
答案 1 :(得分:4)
在紧要关头,这是我能想到的最好的。
offset
增亮(大多数情况下我可以看差异!)将颜色减少到0,使颜色更接近显示的颜色并制作线条更明显。#F9F9F9
),但我使用#B9B9B9
作为顶部文字,白部作为其他文字。import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
class GradientPanels {
/** An 'offset' to make gradients more obvious.
* Reduce to 0 for more subtle effect. */
static final int o = 50;
static final Color borderColor = new Color(74,74,74);
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
JPanel gui = new JPanel(new BorderLayout());
JPanel main = new GradientPanel(o + 40, 22);
main.setLayout(new BorderLayout(4, 4));
JLabel lTop = new JLabel("<html><body><h1 style='color: #B9B9B9'>Up<br>Here");
main.add(lTop, BorderLayout.PAGE_START);
main.setBorder(new EmptyBorder(4, 4, 4, 4));
JPanel center = new GradientPanel(o + 40, 17);
AbstractBorder b = new CompoundBorder(
new LineBorder(borderColor, 1, true),
new EmptyBorder(6, 6, 6, 6));
center.setBorder(b);
LayoutManager lm = new BoxLayout(center, BoxLayout.Y_AXIS);
center.setLayout(lm);
main.add(center, BorderLayout.CENTER);
addPanel(center, "Virus Shield", o);
center.add(Box.createRigidArea(new Dimension(10, 10)));
addPanel(center, "Auto Scan", o);
center.add(Box.createRigidArea(new Dimension(10, 10)));
addPanel(center, "My BitDefender", o);
center.add(Box.createRigidArea(new Dimension(10, 50)));
gui.add(main, BorderLayout.CENTER);
JOptionPane.showMessageDialog(null, gui);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
public static void addPanel(JPanel p, String text, int offset) {
JPanel t = new GradientPanel(offset + 28, 20);
AbstractBorder b = new CompoundBorder(
new LineBorder(borderColor, 1, true),
new EmptyBorder(6, 6, 6, 6));
t.setBorder(b);
t.add(new JLabel("<html><body><h2 style='color: #FFFFFF'>" + text));
p.add(t);
}
}
class GradientPanel extends JPanel {
Color top;
Color btm;
GradientPanel(int t, int b) {
top = new Color(t, t, t);
btm = new Color(b, b, b);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
GradientPaint gp = new GradientPaint(0f, 0f, top,
0f, (float) getHeight(), btm);
g2.setPaint(gp);
g2.fillRect(0, 0, getWidth(), getHeight());
}
}
我的第一个例子中的边界与所需截图中的边界相差甚远。在this answer中,我创建了一个带有更圆角的自定义边框(“讲话气泡”)。
不幸的是,该示例更适用于完全透明的组件,例如JLabel
。我没有时间考虑将其用于不透明组件。
有关进一步的讨论,请参阅Border with rounded corners & transparency。