4

我的问题有点奇怪。

我希望我创建的表单(使用 JFrame)着色应该像这张图片:

在此处输入图像描述

我应该使用特殊的外观和感觉吗?

4

2 回答 2

18

我应该使用特殊的外观和感觉吗?

据我所知,没有这样的内置外观和感觉可用。然而对于“Look&Feel”,“Look”指的是 GUI 小部件(更正式地说,JComponents)的外观,“feel”指的是小部件的行为方式。如果是这样,那么我们总是可以让我们的 Swing 组件在 GUI 中随心所欲地出现。

图形丰富的高级响应式应用程序散发着酷炫的魅力,从一开始就吸引用户并以兴奋的死亡抓地力抓住他们。他们让用户向他们的朋友介绍这些应用程序。

然而,要开发图形丰富的 Swing 应用程序,我们必须知道如何在组件上渲染自定义图形,使它们按照我们想要的方式出现(具有闪亮的颜色、漂亮的纹理、移动的动画、漂亮的排版)。我们需要学习如何正确地布局组件以将它们相对于另一个进行排列。通过回答您的各种问题,我了解到您想成为一名摇摆怪。出色地:

  • 首先,了解Swing JComponent ( JPanel, JLabel, JButton, JList, JTable, JTextPaneetc) 和各种类型的事件侦听器以及它们如何响应组件。
  • 、了解一下Layout Managers。还有其他高级布局管理器可用,这使生活更轻松,但首先要了解标准管理器。
  • 、了解在swing组件上渲染自定义图形和swing绘画机制。然后关于字体概念
  • 、学习GraphicsGraphics2D学习各类几何物体的渲染、图像渲染、纹理、渐变绘制等。
  • 、了解Swing中的并发。Swing 不是线程安全的,它维护单线程规则。需要对线程有很好的了解,StackOverflow 几乎每天都因 Swing 的线程问题而溢出。
  • ,当你几乎读完以上所有内容时,收集《肮脏的富客户》一书并仔细阅读。

现在,为您提供一个演示示例:

我试图使应用程序尽可能简短和简单。但是我已经做了一些事情来实现您请求的 GUI,如果您不知道它们是如何工作的,那么您不应该这样做(例如覆盖paint()函数)。在此示例中,我无法收集纹理作为您提供的图像。但我使用了织物纹理。应用程序需要首先加载纹理图像。密切关注控制台。它将在运行应用程序之前显示以下消息:

请等待,加载纹理: http ://www.brewsterwallcovering.com/data/default/images/catalog/original/289-5757.jpg

加载完毕。开始演示!

我使用过:GridBagLayout作为 MainContainer 的窗格布局管理器。仔细查看代码并阅读相应的扩展(扩展 JCompononent 和 JButton)和我为实现更好的 GUI 所做的绘画(对许多评论家来说并没有那么好,但对于 DEMO ......)

在此处输入图像描述

演示源代码:

import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.*;

/// creating the Button with custom look
class CButton extends JButton
{

    BasicStroke basicStroke = new BasicStroke(2.0f);
    public CButton(String txt) {
        super(txt);
        setForeground(Color.WHITE);
        setFont(getFont().deriveFont(Font.BOLD, 13));
        setContentAreaFilled(false);
        setBorder(null);
        setCursor(new Cursor(Cursor.HAND_CURSOR));
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(new Color(0xFFAA00));

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(basicStroke);

        int archH =  (getHeight()-4)/2;
        g2d.drawRoundRect(3, 3, getWidth()-4, getHeight()-4, archH, archH);

        if(getModel().isRollover())
        {
            g2d.fillRoundRect(3, 3, getWidth()-4, getHeight()-4, archH, archH);
            setForeground(Color.black);

        }
        else 
        {
            setForeground(Color.white);
        }
        g2d.dispose();

        super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.

    }



}

/** creating the MainContainer panel with custom look **/
// custom painting to with paintComponent(Graphics g) and paint(Graphics g)
class MainContainer extends JPanel
{

    public BufferedImage gradientImage = null;
    public static BufferedImage textureImg; // made it static just for easyness
    public static boolean loadingFinished = false;

    public MainContainer() {

        setBorder(new EmptyBorder(50, 50, 50, 50)); // setting the insets 
        // learn about GridBagLayout from the linked page about LayoutManager
        setLayout(new GridBagLayout()); 

        JLabel usrNameLabel = new JLabel("User Name");
        changeCompFont(usrNameLabel);

        JTextField usrNameFeild = new JTextField("user name");
        changeCompFont(usrNameFeild);

        // create compund border for text and password feild with left padding 5 px
        Border compundBorder = BorderFactory.createCompoundBorder(
                                            new LineBorder(Color.white, 2), 
                                            new EmptyBorder(2, 5, 2, 2));
        usrNameFeild.setBorder(compundBorder);


        usrNameFeild.setOpaque(false);
        usrNameLabel.setLabelFor(usrNameFeild);

        JLabel passwordLabel = new JLabel("Password");
        changeCompFont(passwordLabel);

        JPasswordField passFeild = new JPasswordField("Password");
        changeCompFont(passFeild);
        passFeild.setBorder(compundBorder);

        passFeild.setOpaque(false);
        passwordLabel.setLabelFor(passFeild);

        // working with GridBagConstraints, please check out the linked online tutorial 
        GridBagConstraints labCnst = new GridBagConstraints();
        GridBagConstraints txtCnst = new GridBagConstraints();

        labCnst.insets = new Insets(0, 0, 5, 10);
        txtCnst.insets =  new Insets(0, 0, 5, 10);

        labCnst.ipady = txtCnst.ipady = 10;
        txtCnst.fill = labCnst.fill = GridBagConstraints.HORIZONTAL;

        labCnst.gridx = 0;
        txtCnst.gridx = 1;

        labCnst.gridwidth = 1;
        txtCnst.gridwidth = 2;

        labCnst.weightx = 0.3;
        txtCnst.weightx = 0.7;

        txtCnst.gridy = labCnst.gridy = 0;
        add(usrNameLabel, labCnst);
        add(usrNameFeild, txtCnst);


        txtCnst.gridy = labCnst.gridy = 1;
        add(passwordLabel, labCnst);
        add(passFeild, txtCnst);

        labCnst.gridx = 2;
        labCnst.gridy = 2;
        labCnst.ipady = 13;
        labCnst.insets = new Insets(0, 0, 0, 150);
        JButton submitButt = new CButton("Log IN");
        add(submitButt, labCnst);

    }

    public void changeCompFont(JComponent comp)
    {
        comp.setForeground(Color.WHITE);
        comp.setFont(getFont().deriveFont(Font.BOLD, 13));
    }

    // To PAINT THE TEXTURE ABOVE THE COMPONENTS, 
    //DON'T DO IT UNTIL YOU UNDERSTAND PAINTING MECHANISM FULLY
    @Override
    public void paint(Graphics g) {
         super.paint(g); //To change body of generated methods, choose Tools | Templates.

        Graphics2D g2d = (Graphics2D)g.create(); // cloning to work, it is safer aproach
        Rectangle2D txRect = new Rectangle2D.Double(0, 0, textureImg.getWidth(), textureImg.getHeight());
        TexturePaint txPaint = new TexturePaint(textureImg, txRect);
        g2d.setPaint(txPaint);

        //make the texture transparent
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
        g2d.fillRect(0, 0, getWidth(), getHeight());
        g2d.dispose();// disposing the graphics object 
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
        Graphics2D g2d = (Graphics2D) g.create();

        if(gradientImage==null || gradientImage.getHeight() != getHeight())
        {
            gradientImage = createGradientImg();
        }

        g2d.drawImage(gradientImage, 0, 0, getWidth(), getHeight(), this);
        g2d.dispose();
    }

    public BufferedImage createGradientImg()
    {
       BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
       /// background gradient paint, linear gradient paint for the background
       /// Gradient paint rendering could be made more optimized
            LinearGradientPaint lgrPaint =  new LinearGradientPaint(0.0f, 0.0f, getWidth(), getHeight(),
                                                                new float[] { 0.0f, 0.5f, 0.6f, 1.0f },
                                                                new Color[] { new Color(0x002AFF),
                                                                new Color(0x0CAAF9),
                                                                new Color(0x0CAAF9),
                                                                new Color(0x002AFF) });


            Graphics2D g2d = (Graphics2D) image.getGraphics();
            g2d.setPaint(lgrPaint);
            //g2d.shear(0.2, 0);
            g2d.fillRect(0, 0, getWidth(), getHeight());

            g2d.dispose();
            //g2d.drawImage(textureImg, 0, 0, getWidth(), getHeight(), null);
            return image;
    }


}

public class CustomApp {

    public static void main(String[] args) throws IOException {

        // load the texture resource image
        System.out.println("Please wait, Loading Texture : http://www.brewsterwallcovering.com/data/default/images/catalog/original/289-5757.jpg");
        MainContainer.textureImg = ImageIO.read(new URL("http://www.brewsterwallcovering.com/data/default/images/catalog/original/289-5757.jpg"));
        System.out.println("Loading finished. Starting the Demo!");

        MainContainer.textureImg = MainContainer.textureImg.getSubimage(0, 0, 200, 200);

        // Starting the Swing GUI in the EDT, learn about it
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("Demo: LogIn Dialogue");

                // set frame size as Demo perposes, otherwise not recommended
                frame.setSize(new Dimension(500, 300)); 
                MainContainer container = new MainContainer();

                frame.add(new MainContainer());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);

            }
        });
    }
}
于 2013-10-27T03:41:59.570 回答
2

您可以使用JavaFX它使您获得一些很棒的外观和感觉。我认为如果您正在寻找 Java Swing 中提供更好外观和动画的出色设计,那么使用 JavaFX 会更好。您可以参考此链接,希望这对您有所帮助。

FXML 入门

使用 JavaFX 摇摆

于 2013-10-28T13:05:46.383 回答