6

我试图复制这个组件(在帖子的底部),但我似乎无法让它看起来不错。

在此处输入图像描述

所以我想知道,我如何复制这种渐变色?或者如果不是渐变色,我该怎么做才能得到类似的结果?

与这个组件相比,我的尝试变成了非常平坦的黑色。它还具有 JFrame 选项(关闭、最小化等),并且对组件没有“圆形”外观。我正在寻找可以改善我所拥有的并解释我哪里出错的人。我知道我可以简单地使用已经制作的外观和感觉,但我想让我的示例项目尽可能接近图像中的 BitDefender GUI,不包括文本。(如果需要我可以提供代码)

另请注意,我跳过了背景和“病毒防护”、“自动扫描”、“我的 BitDefender”面板之间的面板。我这样做主要是因为我想让我的 SSCCE 尽可能小。

另外我想指出,将插图设置为gbc.insets = new Insets(2,10,2,10);3TopPanels使其看起来更接近 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。

4

2 回答 2

5

让我们先做一些逆向工程。在此过程中可以进行一些简化。此外,我想说增强应用程序的外观也是可能的,因为第一印象远非积极。

在此处输入图像描述

基本上可以在该设计背后找到以下元素:

  • 渐变
  • 正确选择的颜色
  • 圆角
  • 大纲

在此处输入图像描述

请注意,圆角、轮廓很重要。顺便说一句,可以优化一些渐变以提供干净和简单的设计。请查看平面设计与拟物化之间的战斗以获得更多动力。

您的示例已修改,如下所示(它只是一个视觉结果):

在此处输入图像描述

我使用了以下颜色:

在此处输入图像描述

代码:

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);
        }
    }
}

实现此 UI 的最佳方式

我认为唯一正确的方法是实现新的 Look&Feel 子集。看看项目 seaglass

在此处输入图像描述

我用了什么

所有这些示例都是使用Inkscape准备的——一个开源矢量图形编辑器。你可以下载我的SVG 源代码

于 2013-02-22T17:34:56.380 回答
4

在紧要关头,这是我能想到的最好的。

渐变面板

笔记:

  1. 据我所知,线条边框颜色是 74、74、74。我使用了圆形边框,但它的半径比原始示例中显示的要小。
  2. 顶部颜色由代码中定义的颜色变亮offset(主要是为了让我能看到差异!)将其减少到 0 以使颜色更接近出现的颜色并使线条更明显。
  3. 文本的颜色似乎是 249,249,249 ( #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());
    }
}

编辑 1

我的第一个示例中的边框与所需屏幕截图中的边框仍然相去甚远。在这个答案中,我创建了一个带有更多圆角的自定义边框(“语音气泡”)。

会话框

不幸的是,该示例对于完全透明的组件(例如JLabel. 我还没有时间考虑将其用于不透明组件。

有关进一步讨论,请参阅带圆角和透明度的边框。

于 2013-02-22T04:27:30.227 回答