setUndecorated()代码无法正常工作

时间:2017-01-30 15:22:27

标签: java jframe jpanel

该程序运行正常,但是当我添加setUndecorated代码时,该面板不会出现。当我最小化并重新打开程序时问题就解决了。我试过了repaint(),但它没有用。

package testing;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class test extends JFrame{

    static int width = 900;
    static int height = 520; 
    JFrame frame;
    JPanel panel;

    JButton selectKey = new JButton("Select KeyIMG");
    static BufferedImage bg;

    class MyCanvas extends JComponent{

        public void paint(Graphics g) {
              try {
                bg = ImageIO.read(new File("BGFILE"));
            } catch (IOException e) {
                e.printStackTrace();
            } 
            g.setClip(0, 0, width, height);   

            g.drawImage(bg,0,0,width,height, this);

            g.dispose();panel.repaint();       
          }
        }

    public test(){
        super("Test");             
        setBounds(250, 100, width, height);

        selectKey.setBounds(width/9,height/2,width/45*8,height/13);         

        getContentPane().add(new MyCanvas());setUndecorated(true);setVisible(true);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel = new JPanel(); 
        panel.setBackground( new Color(0, 0, 0, 0));
        panel.setLayout(null);

        panel.add(selectKey);
        add(panel);      

   }


   public static void main(String...Args){
       new test();
   }


}

出了什么问题?

1 个答案:

答案 0 :(得分:2)

问题

  • 覆盖paint。非常不鼓励覆盖paint,绘画是一系列复杂的复合方法,它们协同工作以产生最终结果。强烈建议您覆盖paintComponent而不是
  • 未调用super.paint,请参阅上一条评论。除非你确切地知道你正在做什么,并准备接管绘制方法的责任,所以称之为super方法,只有极少数用例我认为不安全。< / LI>
  • 在不透明组件上使用基于alpha的颜色; panel.setBackground(new Color(0, 0, 0, 0));。这是个坏主意。 Swing只知道如何处理不透明和透明的组件,它不知道如何使用基于alpha的颜色绘制组件。 API将简单地忽略其下的任何组件,这可能是导致问题的主要原因之一
  • g.dispose();不会丢弃您未创建或复制的Graphics上下文。这样做可以防止其他组件被涂漆
  • 不要在任何绘画方法中调用panel.repaint();,绘画描绘当前状态,它应该永远不会做任何改变它,这样做很好地让你陷入CPU死亡螺旋,因为它开始咀嚼事实上,所有CPU周期MyCanvas无权修改panel以及代码的设置方式,它可能会生成NullPointerException

“其他”问题

  • static BufferedImage bg;令人担忧。没有其他人有任何需要处理这个变量,唯一应该处理它的类是MyCanvas
  • g.setClip(0, 0, width, height);毫无意义(并且有潜在危险),这已经在调用paint方法之前完成。由于您不依赖于组件的实际大小,这可能会导致绘制超出组件的可见边界,这会变得更糟。
  • JFrame延伸。您应该避免从顶级容器扩展,它们是您很少添加任何新/可重用功能的复杂组件,并且它们将您锁定到单个用例中,更好地从JPanel开始并将其添加到任何你需要的容器

一个例子......

Background example

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    class Background extends JComponent {

        private BufferedImage bg;

        public Background() {
            try {
                bg = ImageIO.read(new File("/path/to/your/image"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            setLayout(new BorderLayout());
        }

        @Override
        public Dimension getPreferredSize() {
            return bg == null ? super.getPreferredSize() : new Dimension(bg.getWidth(), bg.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (bg != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
                g2d.dispose();
            }
        }
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setContentPane(new Background());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setUndecorated(true);

                JPanel panel = new JPanel(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                panel.add(new JLabel("This is a label, don't I look pretty"), gbc);
                JButton selectKey = new JButton("Select KeyIMG");
                panel.add(selectKey, gbc);
                panel.setOpaque(false);

                frame.add(panel);

                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static void main(String... Args) {
        new Test();
    }

}