无法显示字符串

时间:2013-07-29 06:15:51

标签: java swing jframe jpanel

我有以下代码。

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中显示String,我该怎么做?

1 个答案:

答案 0 :(得分: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. 您应该避免从顶级容器扩展。这将使您的组件更具可重用性和灵活性,因为您没有将自己锁定在部署要求中......
  4. 相反。将自己设为自定义组件,例如从JPanel扩展,覆盖它的paintComponent方法并在那里执行自定义绘制。

    你应该AWLAYS调用super.paintXxx因为绘制方法被链接在一起,没有调用一个可能会大大搞乱绘制过程,留下其他绘制组件的工件和残余......

    请查看Performing Custom Painting了解详情

    使用示例更新

    enter image description here

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