JPanel图像背景视觉故障

时间:2015-07-01 17:50:35

标签: java image swing graphics jpanel

我试图创建一个以图片为背景的JPanel,我能够做但是从GIF中可以看出,从选择不同的条目时似乎存在某种绘画问题JList。除了它的alpha值为65之外,JList没有什么特别之处,这意味着它几乎是透明的。我想知道如何修复奇怪的视觉故障。

enter image description here

我自定义JPanel的代码......

package com.css.aor.graphics;

import java.awt.Graphics;
import java.awt.Image;

import javax.swing.JPanel;

/**
 * @author Asmicor
 */

public class JImagePanel extends JPanel {

    private static final long serialVersionUID = 248015296776870365L;
    private Image img;
    private boolean autoScale;

    /**
     * A JPanel that draws an image as the background in the center of the panel
     * 
     * @param img Image that will be drawn as the background
     * @param autoScale Should the image be scaled to fit the whole space of the panel
     */
    public JImagePanel(Image img, boolean autoScale) {
        this.img = img;
        this.autoScale = autoScale;
    }

    @Override
    public void paintComponent(Graphics g) {        
        super.paintComponent(g);        

        if (autoScale) {
            int h = img.getHeight(null);
            int w = img.getWidth(null);

            // Scale Horizontally:
            if (w > this.getWidth()) {
                img = img.getScaledInstance(getWidth(), -1, Image.SCALE_SMOOTH);
                h = img.getHeight(null);
            }

            // Scale Vertically:
            if (h > this.getHeight()) {
                img = img.getScaledInstance(-1, getHeight(), Image.SCALE_SMOOTH);
            }          
        }

        // Center Images
        int x = (getWidth() - img.getWidth(null)) / 2;
        int y = (getHeight() - img.getHeight(null)) / 2;

        g.drawImage(img, x, y, this);       
    }   
}

当我在g.drawImage之后添加一个repaint()时,问题似乎已经解决了,但据我所知,这不是一件好事。

编辑: 我注意到,当我向JList添加一个监听器,当所选值被更改,然后在整个框架上调用重绘时,这个问题似乎也解决了,所以我认为某些事情的顺序出错了重新绘制组件。

示例可运行代码...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

import javax.swing.AbstractListModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;

public class Test {

    private class JImagePanel extends JPanel {

        private static final long serialVersionUID = 248015296776870365L;
        private Image img;
        private boolean autoScale = false;

        /**
         * A JPanel that draws an image as the background in the center of the panel
         * 
         * @param img Image that will be drawn as the background
         * @param autoScale Should the image be scaled to fit the whole space of the panel
         */
        public JImagePanel(Image img, boolean autoScale) {
            this.img = img;
            this.autoScale = autoScale;
        }

        @Override
        public void paintComponent(Graphics g) {        
            super.paintComponent(g);        

            if (img != null) {
                if (autoScale) {
                    int h = img.getHeight(null);
                    int w = img.getWidth(null);

                    // Scale Horizontally:
                    if (w > this.getWidth()) {
                        img = img.getScaledInstance(getWidth(), -1, Image.SCALE_SMOOTH);
                        h = img.getHeight(null);
                    }

                    // Scale Vertically:
                    if (h > this.getHeight()) {
                        img = img.getScaledInstance(-1, getHeight(), Image.SCALE_SMOOTH);
                    }          
                }

                // Center Images
                int x = (getWidth() - img.getWidth(null)) / 2;
                int y = (getHeight() - img.getHeight(null)) / 2;

                g.drawImage(img, x, y, this);       
            }           
        }   
    }

    private JFrame frame;
    private JImagePanel panel;
    private JList list;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Test window = new Test();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Test() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        panel = new JImagePanel(Toolkit.getDefaultToolkit().getImage("C:\\Users\\Asmicor\\Desktop\\lh8vuSc.png"), true);        // <-------- Just change this to a viable path
        frame.getContentPane().add(panel, BorderLayout.CENTER);

        list = new JList();
        list.setModel(new AbstractListModel() {
            String[] values = new String[] {"ghgfhgfhgfhgfhgfh", "gfhgfhgfhgfhgfhgfh", "gfhgfhgfhgfhgfhgfh", "gfhgfhgfhgfhdshs", "hgdfgdsfgsgdsfgdsfg", "dfhgfhdgfhdfhgfdhdgh"};
            public int getSize() {
                return values.length;
            }
            public Object getElementAt(int index) {
                return values[index];
            }
        });

        list.setBackground(new Color(0, 125, 50, 65));
        GroupLayout gl_panel = new GroupLayout(panel);
        gl_panel.setHorizontalGroup(
            gl_panel.createParallelGroup(Alignment.LEADING)
                .addGroup(Alignment.TRAILING, gl_panel.createSequentialGroup()
                    .addContainerGap(41, Short.MAX_VALUE)
                    .addComponent(list, GroupLayout.PREFERRED_SIZE, 359, GroupLayout.PREFERRED_SIZE)
                    .addGap(34))
        );
        gl_panel.setVerticalGroup(
            gl_panel.createParallelGroup(Alignment.LEADING)
                .addGroup(gl_panel.createSequentialGroup()
                    .addGap(19)
                    .addComponent(list, GroupLayout.PREFERRED_SIZE, 208, GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(34, Short.MAX_VALUE))
        );
        panel.setLayout(gl_panel);
    }
}

EDIT2:从我可以收集的内容来看,任何在图像上绘制透明背景的组件都会发生这种情况。我在JLabel和JTable上进行了测试,两者都有类似的视觉故障。唯一真正的解决方法是将repaint()添加到我的paintComponent的JImagePanel,但我的CPU使用率非常高。

0 个答案:

没有答案