Java setUnderatted()代码工作不正常

Java setUnderatted()代码工作不正常,java,jframe,jpanel,Java,Jframe,Jpanel,该程序运行良好,但当我添加设置未修饰的代码时,面板不会出现。当我最小化并重新打开程序时,问题就解决了。我尝试了重新绘制(),但不起作用 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

该程序运行良好,但当我添加设置未修饰的代码时,面板不会出现。当我最小化并重新打开程序时,问题就解决了。我尝试了
重新绘制()
,但不起作用

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


}
怎么了

问题
  • 覆盖
    绘制
    。强烈反对覆盖
    绘制
    ,绘制是一系列复杂的合成方法,它们共同工作以产生最终结果。强烈建议您替代
    paintComponent
  • 不调用super.paint,请参见前面的注释。除非你确切知道你在做什么,并且准备好承担油漆法的责任,否则就称之为“代码>超级< /代码>方法,只有很少的用例,我认为不做这件事是安全的。
  • 在不透明组件上使用基于alpha的颜色<代码>面板背景(新颜色(0,0,0,0))。这是个坏主意。Swing只知道如何处理不透明和透明组件,它不知道如何使用基于alpha的颜色绘制组件。API只会忽略它下面的任何组件,这可能是问题的主要原因之一
  • g.dispose()永远不要处理未创建或复制的
    图形
    上下文。这样做可以防止其他部件被喷漆
  • 不要调用
    panel.repaint()在任何绘制方法中,绘制绘制当前状态,它不应该做任何事情来改变它,这样做会让你陷入CPU死亡的漩涡,因为它开始吞噬所有CPU周期,事实上,
    MyCanvas
    无权修改
    面板
    以及你的代码设置方式,它可能会生成一个
    NullPointerException
“其他”关切
  • 静态缓冲区图像背景令人担忧。没有其他主体需要处理这个变量,应该处理它的唯一类是
    MyCanvas
  • g.setClip(0,0,宽度,高度)
    是没有意义的(并且有潜在的危险),在调用
    paint
    方法之前已经这样做了。更糟糕的是,您不依赖组件的实际大小,这可能会导致绘制超出组件的可见边界
  • JFrame
    扩展。您应该避免从顶级容器扩展,它们是复杂的组件,您很少向其中添加任何新的/可重用的功能,并且它们将您锁定在单个用例中,最好从
    JPanel开始,并将其添加到您需要的任何容器中
一个例子。。。


不编译…系统每秒可以调用几次绘制方法。不要在绘制方法中读取图像文件。相反,在构造函数中读取它并将其存储在字段中。另外,切勿从绘制方法调用
repaint
;它将导致再次调用paint,从而创建一个无限循环。@VGR:当然,只有调用
repaint()
的变量实际存在,或者包含有缺陷的
paint
方法的组件在打开窗口后没有立即被另一个替换(如果代码曾经编译过的话)…您在打开窗口后添加组件,对于这两种情况,
add(new MyCanvas())
add(panel)
您无法指定布局约束(默认情况下,内容窗格具有
BorderLayout
)。没有指定在这种情况下应该发生什么,一个组件可以替换另一个组件,或者布局管理器会忽略这两个组件,但是在任何一种情况下,添加后不验证UI的事实都会导致不可预测的结果,它可能会被验证为另一个操作的副作用,也可能不会。这就是为什么
未装饰的
似乎会有所不同。在打开窗口之前添加所有组件将消除手动验证的需要。不过,你应该考虑VGR的评论,并进一步学习如何使用布局管理器……我想根据像素定位。代码>边框布局()
代码有效。但是,当我设置
setLayout(null)
时,面板不会出现。是的,欢迎了解不应使用null布局的原因。避免使用
null
布局,像素完美的布局在现代ui设计中是一种错觉。影响零部件单个尺寸的因素太多,您无法控制。Swing的设计初衷是与布局管理器一起工作,丢弃这些布局管理器将导致无止境的问题,您将花费越来越多的时间来纠正这些问题
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();
    }

}