Java 在 JPanel 中绘制文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1830603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:04:16  来源:igfitidea点击:

drawing text within a JPanel

javagraphicspaint

提问by danwoods

I'm looking for the most basic description of how to draw text within a JPanel. I know there are a billion tutorials out there but none of them are clicking with me and I have some specific questions which may help others who are confused. As a setup (a testing app) I have a single class which has a JLabel, a JTextField, a JButton, and a JPanel. The application reads in ints from an external file and should display their average in the panel when the JButton is pressed. I have all the underlying programing sorted out (that is, the button responds and prints the average to the command line) but I just cannot seem to sort out how to print the average to the panel. I guess my biggest question is how to incorporate the paint() or paintComponet() method in along with the rest of the code. Should it be it's own class? Should the JPanel be it's own class? It seems like that's what most of the tutorials are telling me, I'm just not sure what the first step is exactly. The code looks like:

我正在寻找有关如何在 JPanel 中绘制文本的最基本描述。我知道那里有 10 亿个教程,但没有一个是跟我一起点击的,我有一些具体的问题可能会帮助其他人感到困惑。作为设置(测试应用程序),我有一个类,其中包含 JLabel、JTextField、JButton 和 JPanel。应用程序从外部文件中读取整数,并应在按下 JButton 时在面板中显示它们的平均值。我已经整理了所有底层编程(即按钮响应并将平均值打印到命令行),但我似乎无法弄清楚如何将平均值打印到面板。我想我最大的问题是如何将paint() 或paintComponet() 方法与其余代码结合在一起。它应该是它自己的类吗?如果 JPanel 是它' 自己的班级?似乎这就是大多数教程告诉我的,我只是不确定第一步到底是什么。代码如下:

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

public class Main extends JFrame implements ActionListener {
  private int[] intArray = new int[10000];
  private int numOfInts = 0;
  private int avg = 0;

  protected JButton avgBtn;
  protected JTextField indexEntry;
  protected JLabel instructions;
  protected JPanel resultsPanel;

  public Main(){

    //create main frame
    this.setTitle("Section V, question 2");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(350, 250);
    this.setLayout(new GridLayout(4, 1));

    //create instruction label and add to frame
    instructions = new JLabel("Follow the instructions on the exam to use this program");
    this.add(instructions);

    //create textfield for index entry and add to frame
    indexEntry = new JTextField();
    this.add(indexEntry);

    //create button for average and add to frame
    avgBtn = new JButton("Click for Average");
    this.add(avgBtn);
    avgBtn.addActionListener(this);

    //create panel to display results and add to frame
    resultsPanel = new JPanel();
    resultsPanel.setBackground(Color.BLUE);
    this.add(resultsPanel);

    //read in from file
    readFromFile();

    //compute average
    computeAverage();
  }

  private void readFromFile() {
    try {
            // Open the file
            FileInputStream fstream = new FileInputStream("numbers.dat");
            BufferedReader br = new BufferedReader(new InputStreamReader(fstream));

            //create placeholder for read in ints
            String strLine;

            //Read File Line By Line
            int i = 0;
            while ((strLine = br.readLine()) != null) {
              //place ints in array and increament the count of ints
              System.out.println (strLine);
              intArray[i] = Integer.parseInt(strLine);
              numOfInts++;
              i++;
            }
            //Close the input stream
            in.close();
            System.out.println ("numOfInts = " + numOfInts);
    }
    catch (Exception e) {
            //Catch exception if any
            System.err.println("Error: " + e.getMessage());
    }
  }

  //compute averaage
  private void computeAverage() {
    int sum = 0;
    for (int i = 0; i < numOfInts; i++)
    sum += intArray[i];
    avg = sum/numOfInts;
    System.out.println("avg = " + avg);
  }

//event handling
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == avgBtn) {
            computeAverage();
    }
}

//"main" function
public static void main(String[] args) {
    Main m = new Main();
    m.setVisible(true);
}

//paint
public void paintComponent(Graphics g){
  g.drawString(avg, 75, 75);
}
}

Any and all help/direction is appreciated. I know I've used this code recently for other questions, I just want to know it all! Ideally the panel would display the average of the read in ints when the button was clicked, and display whatever was entered into the textfeild when the focus was on it and enter was pressed, but I'm taking baby steps, and like I said, I'd like for this thread to be a general tutorial for others with similar questions who aren't finding answers from sun docs or other sites. Thanks so much in advance. Dan :)

任何和所有帮助/方向表示赞赏。我知道我最近将这段代码用于其他问题,我只是想知道这一切!理想情况下,面板将在单击按钮时以整数形式显示读取的平均值,并在焦点位于文本字段上并按下 Enter 键时显示输入到文本字段中的任何内容,但我正在采取小步骤,就像我说的那样,我希望这个线程成为其他有类似问题的人的一般教程,他们没有从 sun 文档或其他网站上找到答案。非常感谢。丹 :)

采纳答案by David Robles

Create an inner class that extends JPanel inside your Main class:

创建一个在 Main 类中扩展 JPanel 的内部类:

class MyPanel extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawString(Integer.toString(avg), 75, 75);
    }

}

Then you need to call repaint on that panel after calling computeAverage() in actionPerformed:

然后,您需要在 actionPerformed 中调用 computeAverage() 后在该面板上调用 repaint:

//event handling
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == avgBtn) {
        computeAverage();
        panel.repaint();
    }
}

回答by Gunslinger47

Add a JLabel to the JPanel.

将 JLabel 添加到 JPanel。

Call setText(String) on the JLabel and your text will be drawn within the JPanel.

在 JLabel 上调用 setText(String),您的文本将在 JPanel 中绘制。

回答by camickr

1) A JFrame doesn't have a paintComponent() method so the code you posted won't do anything. You need to create a custom JPanel and override its paintComponent() method to do your custom painting.

1) JFrame 没有 paintComponent() 方法,因此您发布的代码不会执行任何操作。您需要创建一个自定义 JPanel 并覆盖其paintComponent() 方法来进行自定义绘制。

2) Even if you do the above, the painting will still not display because a panel by default has a zero size. So you will then need to set the preferred size of the panel to make sure it is visible.

2) 即使您执行上述操作,绘画仍然不会显示,因为面板默认大小为零。因此,您需要设置面板​​的首选大小以确保它可见。

3) Why are you even doing this. All you need to do is use a JLabel and set the text of the JLabel.

3)你为什么要这样做。您需要做的就是使用 JLabel 并设置 JLabel 的文本。

I find it hard to believe you looked at other tutorials. The Swing tutorial on Custom Paintinghas a 20 line program that shows the basics.

我发现很难相信你看过其他教程。自定义绘画的 Swing 教程有一个 20 行的程序,显示了基础知识。

回答by sateesh

I think you should not be subclassing JFrame. Make an instance of JFrame an instance
variable of Main class and add the JPanel etc. to it.

我认为你不应该继承 JFrame。使 JFrame 的实例
成为 Main 类的实例变量,并向其添加 JPanel 等。