Graphics类似乎重写了JFrame / JPanel

时间:2013-07-24 00:16:25

标签: java swing graphics jframe jpanel

我在理解JPanel,JFrame和图形类的整个结构以及扩展和覆盖等方面遇到了一些麻烦。我似乎已经完成了所有工作,直到我添加了图形类,然后我的按钮等我的JPanel / JFrame上的按钮才显示出来了。我发现它与覆盖或超级有关?但我真的需要一些澄清。非常感谢!

我已经缩小了代码以便于查看。

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

public class windowBuild extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private int energy = 4;
    private JButton btnClaw = new JButton("Claw");
    private Image bg;
    private boolean loaded = false;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                windowBuild frame = new windowBuild();
                frame.setVisible(true);

            }
        });
    }

    private class ButtonHandler implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            String which = e.getActionCommand();
            if (which.equals("Claw")) {
                energy = energy - 1;
                System.out
                        .println("Player one's dragon clawed the opponent. Dragon's energy is now at: "
                                + energy);
            }

        }

    }

    public void loadImage() {
        bg = new ImageIcon("C:\\res\\dragonDuelBackground.jpeg").getImage();
        loaded = true;
        repaint();
    }

    public windowBuild() {
        ButtonHandler bh;
        System.out.println("Starting frame...");
        bh = new ButtonHandler();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 800, 600);
        contentPane = new JPanel();
        contentPane.setBorder(new TitledBorder(null, "Dragon Duel",
                TitledBorder.CENTER, TitledBorder.TOP, null, Color.CYAN));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        btnClaw.setBounds(273, 511, 109, 39);
        contentPane.add(btnClaw);
        btnClaw.addActionListener(bh);

    }
//********************************************************************
//  public void paint(Graphics g) {
//      if (loaded) {
//          g.drawImage(bg, 400, 400, null);
//      }
//  }
//***************Uncomment this and the code won't work anymore**********
}

2 个答案:

答案 0 :(得分:2)

  

取消注释,代码将不再起作用

不要覆盖顶级容器的paint()(JFrame,JDialog ...)。通过覆盖JPanel(或JComponent)的paintComponent()方法来完成自定义绘制。然后将面板添加到框架中。不要忘记调用super.paintComponent(...)。

阅读Custom Painting教程中的Swing教程,了解更多信息和示例。

答案 1 :(得分:2)

  1. 避免直接从JFrame延伸。您没有向框架添加任何新功能,并且如果您这样做,则限制了UI的可重用性(因为您无法向其他任何内容添加框架)
  2. 不要覆盖顶级容器的paint。有很多很好的理由,但主要的问题是框架容器有许多不同的层(JLayeredPanecontentPane)可以涂抹任何你做的事情
  3. 您必须致电super.paintXxx以确保油漆链保持完整。
  4. 相反,创建一个单独的类(例如从JPanel扩展)并覆盖它的paintComponent方法。或者更好。简单地使用JLabel来显示图像

    请查看Performing Custom PaintingPainting in AWT and Swing了解详情。

    另外,我没有看到你在哪里调用loadImage,所以永远不会加载图像

    我还建议您使用ImageIO读取Reading/Loading an Image,当它无法读取图像文件时会抛出Exception,这比使用它更有用只是无声地失败的ImageIcon

    更新了简单示例

    enter image description here

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.border.TitledBorder;
    
    public class TestGraphics {
    
        public static void main(String[] args) {
            new TestGraphics();
        }
    
        public TestGraphics() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private int energy = 4;
            private JButton btnClaw = new JButton("Claw");
            private BufferedImage bg;
    
            public TestPane() {
                setBackground(Color.WHITE);
                try {
                    bg = ImageIO.read(new File("dragon.gif"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
    
                ButtonHandler bh;
                bh = new ButtonHandler();
                setBorder(new TitledBorder(null, "Dragon Duel",
                        TitledBorder.CENTER, TitledBorder.TOP, null, Color.CYAN));
                setLayout(new BorderLayout());
    
                JPanel buttonPane = new JPanel();
                buttonPane.setOpaque(false);
                buttonPane.add(btnClaw);
    
                add(buttonPane, BorderLayout.SOUTH);
                btnClaw.addActionListener(bh);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (bg != null) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    int x = (getWidth() - bg.getWidth()) / 2;
                    int y = (getHeight() - bg.getHeight()) / 2;
                    g2d.drawImage(bg, x, y, this);
                    g2d.dispose();
                }
            }
    
            private class ButtonHandler implements ActionListener {
    
                public void actionPerformed(ActionEvent e) {
                    String which = e.getActionCommand();
                    if (which.equals("Claw")) {
                        energy = energy - 1;
                        System.out
                                .println("Player one's dragon clawed the opponent. Dragon's energy is now at: "
                                + energy);
                    }
    
                }
            }
        }
    }
    

    Ps-你最好有充分的理由不使用布局管理器