Java swing渐变绘画ISSUE

标签 java swing

我正在开发一个GUI,其中有一个300X300 Jframe,一个相同大小的JPanel(如 background),它的布局是一个BorderLayout,里面有三个JPanel。在其中一个 JPanel 中,还有另一个 JPanel,它有一个我制作的 CustomPanelUI,但是,当它绘制时JPanel颜色发生了变化

自定义面板UI:

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.plaf.basic.BasicPanelUI;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Ionut Cicio
 */
public class CustomPanelUI extends BasicPanelUI{
    Color firstColor;
    Color secondColor;

    CustomPanelUI(Color firstColor, Color secondColor){
        this.firstColor = firstColor;
        this.secondColor = secondColor; 
    }

    @Override
    public void update(Graphics g, JComponent c) {
        if (c.isOpaque()) {
            Graphics2D g2 = (Graphics2D) g;

            g2.setPaint(new GradientPaint(
                    c.getX(),
                    c.getY() + c.getHeight() / 2,
                    firstColor,
                    c.getX() + c.getWidth(),
                    c.getY() + c.getHeight() / 2,
                    secondColor));

            g2.fillRect(c.getX(), c.getY(), c.getWidth(), c.getHeight());
            g2.drawRect(c.getX(), c.getY(), c.getWidth(), c.getHeight());
        }

        paint(g, c);
    }
}

主机:

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Utente
 */
public class BaseConverterGUI extends javax.swing.JFrame {

    BufferedImage frameIcon = null; //Make Icon thicker

    /**
     * Creates new form BaseConverterGUI
     */
    public BaseConverterGUI() {
        try {
            frameIcon = ImageIO.read(new File("C:\\Users\\Utente\\Desktop\\BaseConverter\\data\\Icon.png"));
        } catch(IOException e){
            System.out.println(e);
        }

        initComponents();

        background.setUI(new CustomPanelUI(new Color(10, 36, 106), background.getBackground()));
        inputBackground.setUI(new CustomPanelUI(inputBackground.getBackground(), new Color(255, 255, 255)));
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        background = new javax.swing.JPanel();
        output = new javax.swing.JPanel();
        input = new javax.swing.JPanel();
        inputBackground = new javax.swing.JPanel();
        analysis = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle(" Base Converter");
        setIconImage(frameIcon);
        setName("MainFrame"); // NOI18N
        setPreferredSize(new java.awt.Dimension(300, 300));
        setResizable(false);
        setSize(new java.awt.Dimension(300, 300));

        background.setBackground(new java.awt.Color(165, 201, 239));
        background.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(212, 208, 200)));
        background.setForeground(new java.awt.Color(255, 255, 255));
        background.setLayout(new java.awt.BorderLayout());

        output.setBackground(new java.awt.Color(0, 0, 0));
        output.setOpaque(false);

        javax.swing.GroupLayout outputLayout = new javax.swing.GroupLayout(output);
        output.setLayout(outputLayout);
        outputLayout.setHorizontalGroup(
            outputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 298, Short.MAX_VALUE)
        );
        outputLayout.setVerticalGroup(
            outputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );

        background.add(output, java.awt.BorderLayout.PAGE_END);

        input.setBackground(new java.awt.Color(0, 0, 0));
        input.setOpaque(false);

        inputBackground.setBackground(new java.awt.Color(23, 123, 123));
        inputBackground.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(255, 255, 255), 2));

        javax.swing.GroupLayout inputBackgroundLayout = new javax.swing.GroupLayout(inputBackground);
        inputBackground.setLayout(inputBackgroundLayout);
        inputBackgroundLayout.setHorizontalGroup(
            inputBackgroundLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 86, Short.MAX_VALUE)
        );
        inputBackgroundLayout.setVerticalGroup(
            inputBackgroundLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 63, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout inputLayout = new javax.swing.GroupLayout(input);
        input.setLayout(inputLayout);
        inputLayout.setHorizontalGroup(
            inputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(inputLayout.createSequentialGroup()
                .addGap(77, 77, 77)
                .addComponent(inputBackground, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(131, Short.MAX_VALUE))
        );
        inputLayout.setVerticalGroup(
            inputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(inputLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(inputBackground, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        background.add(input, java.awt.BorderLayout.PAGE_START);

        analysis.setBackground(new java.awt.Color(0, 0, 0));
        analysis.setOpaque(false);

        javax.swing.GroupLayout analysisLayout = new javax.swing.GroupLayout(analysis);
        analysis.setLayout(analysisLayout);
        analysisLayout.setHorizontalGroup(
            analysisLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 298, Short.MAX_VALUE)
        );
        analysisLayout.setVerticalGroup(
            analysisLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 107, Short.MAX_VALUE)
        );

        background.add(analysis, java.awt.BorderLayout.CENTER);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(background, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(background, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Metal".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(BaseConverterGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(BaseConverterGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(BaseConverterGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(BaseConverterGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BaseConverterGUI().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel analysis;
    private javax.swing.JPanel background;
    private javax.swing.JPanel input;
    private javax.swing.JPanel inputBackground;
    private javax.swing.JPanel output;
    // End of variables declaration//GEN-END:variables
}

This is the result

最佳答案

Graphics 上下文会自动转换为组件坐标空间,这意味着左上角/左上角始终为 0x0

您的代码添加了一个额外的偏移量(组件在其父坐标空间内的位置),这使得绘画从不同的位置开始。

相反,只需使用0x0作为绘画的起点。

例如...

Example

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.basic.BasicPanelUI;

public class Test {

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

    public Test() {
        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);
                JPanel content = new JPanel(new GridBagLayout());
                // This will offset the content, so we can see that the code is working
                content.setBorder(new EmptyBorder(10, 10, 10, 10));
                frame.setContentPane(content);
                // Add multiple instances so we can see that the code is working
                frame.add(new TestPane());
                frame.add(new TestPane());
                frame.add(new TestPane());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setUI(new CustomPanelUI(Color.RED, Color.BLUE));
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public class CustomPanelUI extends BasicPanelUI {

        Color firstColor;
        Color secondColor;

        CustomPanelUI(Color firstColor, Color secondColor) {
            this.firstColor = firstColor;
            this.secondColor = secondColor;
        }

        @Override
        public void update(Graphics g, JComponent c) {
            if (c.isOpaque()) {
                Graphics2D g2 = (Graphics2D) g;

                g2.setPaint(new GradientPaint(
                                0,
                                c.getHeight() / 2,
                                firstColor,
                                c.getWidth(),
                                c.getHeight() / 2,
                                secondColor));

                g2.fillRect(0, 0, c.getWidth(), c.getHeight());
                g2.drawRect(0, 0, c.getWidth(), c.getHeight());
            }

            paint(g, c);
        }
    }

}

关于Java swing渐变绘画ISSUE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54203443/

相关文章:

java - 选择 Eclipse 上 Ubuntu 中的 JTextField 上看不到的文件路径

java - 为 future 的应用程序关键日志保留 Android 设备的内部存储

java - 使用 Docker 在 Apache 后面添加新的 Tomcat 容器

java - Gzip解压返回随机字符

java - JTextField 需要留空并且搜索时不区分大小写

java - 单击按钮后 KeyListener 不起作用

Java : read and write a file together

java - 在 Java 中使用扫描器的问题

java - 如何从内部框架访问 JFrame 中的组件

java - 如何为JTable的表头设置光标?