【问题标题】:I'm trying to draw a string in JFrame, but it won't work.. Help please我正在尝试在 JFrame 中绘制一个字符串,但它不起作用..请帮助
【发布时间】:2014-06-19 07:07:47
【问题描述】:

我试图在按下按钮时显示一个字符串,但它不起作用。我不知道问题是什么。我没有收到任何错误,但这并不困扰我。我想我缺少一些基本的东西。请帮忙!!

//I'm trying to draw a string in the frame when a button is pressed, but it won't work..
//Can't figure out what the problem is.


import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

class AppletTwo extends JFrame implements ActionListener
{

    JFrame frameOne;
    JButton btnOne;

    AppletTwo()
    {

        frameOne = new JFrame("frameOne");
        frameOne.setSize(320,240);
        frameOne.setLayout(new FlowLayout(FlowLayout.LEFT));
        frameOne.setVisible(true);
        frameOne.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        btnOne = new JButton("Print");
        btnOne.addActionListener(this);
        frameOne.add(btnOne);
    }

    public void actionPerformed(ActionEvent ae)
    {

        if(ae.getSource() == btnOne)
        {
            repaint();
        }
    }

    public void paint(Graphics g)
    {
        g.drawString("Never Works",150,150);
    }

    public static void main(String[] args)
    {

        AppletTwo frame1 = new AppletTwo();
    }
}

【问题讨论】:

    标签: java swing jframe paint repaint


    【解决方案1】:

    “我想我错过了一些基本的东西。”

    是的,你是:

    主要问题:

    • 您的类是JFrame,这是您要为其覆盖paint 方法的组件。但是您创建了JFrame 的另一个实例,这是您setVisible 的实例。请记住,您还没有在此框架上绘制任何内容。因此,您看到的是新的框架实例,不是您正在为其绘制的类框架(并且您从未设置为可见)。

    其他问题:

    • 您应该始终在 paint[Component] 覆盖之后调用 super.paint[Component]

      @Override
      public void paint(Graphics g) {
          super.paint(g);
      }
      
    • 不要在像JFrame 这样的顶级容器上绘画。而是在JPanelJComponent 上绘制并覆盖paintComponent 方法并调用super.paintComponent,然后将该组件添加到框架中。见Performing Custom Painting

    • Swing 应用程序应在事件调度线程 (EDT) 上运行。您可以通过将 main 代码包装在 SwingUtilities.invokeLater(...) 中来做到这一点。见Initial Threads

      public static void main(String[] args) {
              SwingUtilities.invokeLater(new Runnable(){
              public void run() {
                  AppletTwo frame1 = new AppletTwo();
              }
          }); 
      }
      
    • 通常,您总是希望在添加组件后将框架设置为可见。

    其他说明:


    更新

    上面提到的所有点的例子。

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    
    public class SimpleDrawing {
    
        public SimpleDrawing() {
            final DrawingPanel panel = new DrawingPanel();
    
            final JTextField field = new JTextField(15);
    
            JButton button = new JButton("Change name");
            button.addActionListener(new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    String someString = field.getText();
                    if (!someString.isEmpty()) {
                        panel.setString(someString);
                    }
                }
            });
    
            JPanel bottomPanel = new JPanel();
            bottomPanel.add(field);
            bottomPanel.add(button);
    
            JFrame frame = new JFrame();
            frame.add(panel);
            frame.add(bottomPanel, BorderLayout.SOUTH);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
    
        }
    
        public class DrawingPanel extends JPanel {
            private String someString = "Stackoverflow";
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawString(someString, 75, 75);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension (300, 100);
            }
    
            public void setString(String someString) {
                this.someString = someString;
                repaint();
            }
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run() {
                    new SimpleDrawing();
                }
            });
        }  
    }
    

    【讨论】:

    • 感谢您澄清这个概念。我关于 Java 的基础知识很薄弱。另一个可能很愚蠢的问题:如果我为 JFrame 设置布局(无论是否继承)或添加一个组件,比如一个按钮,它是否会以某种方式阻止 drawString() 结果显示?我可以使用按钮来使用 drawString() 显示文本吗?如果可能的话,请包括或指出一个例子..
    • 否,但不建议将组件添加到绘图表面。我的回答确切地解释了是什么导致您的绘图不出现。请参阅主要问题部分
    • "我可以使用按钮通过 drawString() 显示文本吗?" .不要对drawString 中的字符串值进行硬编码。使用可以更新的变量,然后调用repaint()。例如,有些人在文本区域中输入一些文本。当您按下按钮时,文本区域中的文本将被放入该变量。当您重新绘制时,将绘制新文本
    • 创建面板时,需要先为其设置首选尺寸,然后再将其添加到框架中。对于某些布局,如果您没有设置您正在绘制的面板的首选大小,则面板将不会显示。
    • 我马上就要被淘汰了。也许明天我会给你一个完整的例子
    猜你喜欢
    • 2022-11-22
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多