0

我有以下代码。

package lab1;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.metal.DefaultMetalTheme;
import javax.swing.plaf.metal.MetalLookAndFeel;

public class Snake extends JFrame {

private static final long serialVersionUID = 1L;
private JPanel jp;
private JFrame jf;

public Snake() {

    initlookandfeel();

    jf = new JFrame();
    jf.setVisible(true);
    jf.setBounds(200, 200, 500, 500);
    jp = new JPanel();
    jp.setVisible(true);
    jf.setContentPane(jp);
    jp.setLayout(null);
    jp.setBounds(0, 0, jf.getWidth(), jf.getHeight());
    jf.setTitle("NIRAV KAMANI");
    jp.repaint();

}

public static void main(String[] args) {

    JFrame.setDefaultLookAndFeelDecorated(true);
    Snake sn = new Snake();
}

public void paint(Graphics g) {

    g.setColor(Color.red);
    g.drawString("NIRAV KAMANI", 50, 50);

}

public void initlookandfeel() {
    String lookandfeel;
    lookandfeel = "javax.swing.plaf.metal.MetalLookAndFeel";

    try {
        UIManager.setLookAndFeel(lookandfeel);
        MetalLookAndFeel.setCurrentTheme(new DefaultMetalTheme());
        UIManager.setLookAndFeel(new MetalLookAndFeel());
    } catch (Exception e) {
        System.out.println("" + e);
    }

}
}

我知道我犯了一些与 JPanel 或 JFrame 相关的错误。但我无法理解我在做什么错误?为什么?我认为有一个层被另一个覆盖,所以字符串不会显示。但是如果我想在 JPanel 中显示字符串,我必须做什么?

4

1 回答 1

2

您遇到问题的主要原因是屏幕上显示的框架不是您认为要绘制的框架...

基本上,您创建了一个从JFrame

public class Snake extends JFrame {

在您的构造函数中完全忽略了它......

public Snake() {

    initlookandfeel();

    // I'm a new instance of a JFrame which has nothing to do with the
    // instance of Snake...
    jf = new JFrame();
    jf.setVisible(true);
    jf.setBounds(200, 200, 500, 500);
    jp = new JPanel();
    jp.setVisible(true);
    jf.setContentPane(jp);
    // Bad idea, JFrame uses a `BorderLayout` anyway, which will do the job you want
    jp.setLayout(null);
    // Bad idea
    // The frame contains a border, possibly a menu bar and other components.  The
    // visible size of the frame will actually be smaller then it's size...
    jp.setBounds(0, 0, jf.getWidth(), jf.getHeight());
    jf.setTitle("NIRAV KAMANI");
    jp.repaint();

}

现在。在您启动编辑器进行更正之前,让我们看看我们是否可以让它变得更好......

  1. 使用布局管理器。让生活更轻松。
  2. 您正在覆盖paint顶级容器的方法,这通常是一个坏主意,您发现这是原因之一。框架上有很多内容,通常它有JLayeredPane一个内容窗格和一个内容窗格,但您还在其上添加了另一个面板。
  3. 您应该避免从顶级容器扩展。这将使您的组件更具可重用性和灵活性,因为您不会将自己锁定在部署要求中......

反而。让你自己成为一个自定义组件,比如说从类似的东西扩展JPanel,覆盖它的paintComponent方法并在那里执行你的自定义绘画。

您应该调用 AWLAYS 调用super.paintXxx,因为绘制方法是链接在一起的,如果不调用一个可能会严重扰乱绘制过程,留下工件和其他绘制组件的残余物......

看看Performing Custom Painting了解更多细节

更新示例

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class CustomPainting {

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

    public CustomPainting() {
        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 {

        public TestPane() {
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            FontMetrics fm = g2d.getFontMetrics();
            String text = "Hello world";
            int x = (getWidth() - fm.stringWidth(text)) / 2;
            int y = ((getHeight() - fm.getHeight()) / 2) + fm.getAscent();
            g2d.drawString(text, x, y);
            g2d.dispose();
        }
    }
}
于 2013-07-29T06:23:57.540 回答