如何在Java jPanel上打印一些文本?

如何在Java jPanel上打印一些文本?,java,swing,jframe,jpanel,Java,Swing,Jframe,Jpanel,对某些人来说,这可能是一个非常明显的问题,但我无法理解。我是Eclipse新手,只使用Dr.Java编程。 我正在创建一个mad libs程序,用户必须输入名词、形容词、名称、数字,最后它会在故事中显示出来 在用户输入了所有必需的信息后,我希望在jPanel中打开完成的故事。我不知道如何将文本添加到jPanel。(我希望在用户输入所有信息后,以c.代码开头的文本显示在窗口中) 代码如下: import java.util.Scanner; import java.awt.*; import

对某些人来说,这可能是一个非常明显的问题,但我无法理解。我是Eclipse新手,只使用Dr.Java编程。 我正在创建一个mad libs程序,用户必须输入名词、形容词、名称、数字,最后它会在故事中显示出来

在用户输入了所有必需的信息后,我希望在jPanel中打开完成的故事。我不知道如何将文本添加到jPanel。(我希望在用户输入所有信息后,以c.代码开头的文本显示在窗口中) 代码如下:

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

public class MadLibs{

 public static void Action1 () 
  {

    JFrame frame = new JFrame("Mad Libs");
    // Add a window listener for close button
    frame.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
        }
    });

    Scanner input = new Scanner(System.in);

    System.out.println("Male Friend:");
    String maleFriend = input.nextLine();
    System.out.println("Adjective:");
    String adjective1 = input.nextLine();
    System.out.println("Past Tense Verb:");
    String pastTenseVerb1 = input.nextLine();
    System.out.println("Past Tense Verb 2:");
    String pastTenseVerb2 = input.nextLine();
    System.out.println("Large Number:");
    String largeNumber = input.nextLine();
    System.out.println("Famous Female:");
    String famousFemale = input.nextLine();
    System.out.println("Adverb:");
    String adverb = input.nextLine();
    System.out.println("Place:");
    String place = input.nextLine();
    System.out.println("Body Part(singular):");
    String bodyPart = input.nextLine();
    System.out.println("Large Number:");
    String largeNumber2 = input.nextLine();
    System.out.println("Verb ending with -ing");
    String ingEnding1 = input.nextLine();
    System.out.println("Singular noun:");
    String singularNoun = input.nextLine();
    System.out.println("Plural Noun:");
    String pluralNoun = input.nextLine();



    // This is an empty content area in the frame
    JLabel jlbempty = new JLabel("");
    jlbempty.setPreferredSize(new Dimension(600, 800));
    frame.getContentPane().add(jlbempty, BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);

    //The story I want displayed on the jPanel:
    /*
     c.println("The Great Dough Disaster");
        c.println("\nLast summer, my friend "+ maleFriend + " got a job at the " + adjective1 +" Pastry Shop. For the first few");
        c.println("weeks, he " + pastTenseVerb1 + " the floors, " + pastTenseVerb2 + " on the shelves, and unloaded " + largeNumber + " pound sacks");
        c.println("of flour from the delivery trucks.\n");
        c.println("Finally, "+famousFemale+", the owner, told "+maleFriend+" that she would teach him to make bread. Now,"); 
        c.println("pay attention, "+maleFriend+",” she said every day. “I'll make the first batch of dough. Then you");
        c.println("can make the next batch while I go to "+place+".\n");
        c.println("Poor "+maleFriend+"! He had a habit of letting his "+bodyPart+" wander. When "  +famousFemale+ " left for "+place);
        c.println("he started to mix the ingredients. “Let me see,” he said. “I think she put in "+largeNumber2);
        c.println("packages of yeast.”\n");
        c.println("A short while later, the dough started "+ingEnding1+". It kept on "+ingEnding1+". "+maleFriend+" tried to"); 
        c.println("cover it with a(n) "+singularNoun+", but the dough wouldn't stop "+ingEnding1+". It was everywhere! ");
        c.println("“What can I do?” thought "+maleFriend+".\n");
        c.println("Just then, Tyana returned from toronto. “"+maleFriend+"” she screamed. “What have you done?”");
        c.println("“It's not my fault,” cried "+maleFriend+". “The dough just started "+ingEnding1+" and wouldn't stop.”");
        c.println(famousFemale + " had to let him go. Now "+maleFriend+" has a job making "+singularNoun+". I don't think he'll ever");
        c.print("eat bread again, let alone make it.");
      */


  }

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

}

另外,我对jPanel的工作原理有点困惑。我找到了很多在jPanel上显示东西的方法,但我不知道该用哪一种

我马上想到了两种方法

第一种方法要简单得多,即使用paintComponent(图形)方法。每当程序认为需要重新绘制对象时,就会自动调用此方法,例如最小化和ERMM取消最小化保存jpanel的窗口

下面是一个简单的例子

import javax.swing.JPanel;

import java.awt.Graphics;

import java.lang.Override; //for @Override

class yourClass extends JPanel { //yourClass is the JPanel
    @Override //if you aren't overriding correctly this makes the compiler tell you
    protected void paintComponent(Graphics gr){
        super.paintComponent(gr); 
        gr.drawString("string literal or a string variable", 0,10);
    }
}
import java.awt.GridLayout;
import java.awt.Graphics;

import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JFrame;

import java.lang.Override;

class YourMainClass {
    static JFrame mainFrame;
    static YourJLabel clsLabel;
    static JPanel pnlJPanel;
    public static void main(String[]args){
        mainFrame = new JFrame("Testing"); //initialize, and set size the frame
        mainFrame.setSize(500,500);
        pnlJPanel = new JPanel();//initialize our panel
        pnlJPanel.setLayout(new GridLayout(3,1));//set its layout to gridlayout, with grid of 3 rows and 1 column
        clsLabel = new YourJLabel(); //create a jlabel, add some text to it, then add it to the jpanel
        clsLabel.setText("some");
        pnlJPanel.add(clsLabel);
        clsLabel = new YourJLabel();
        clsLabel.setText("Text");
        pnlJPanel.add(clsLabel);
        clsLabel = new YourJLabel();
        clsLabel.setText("drawn");
        pnlJPanel.add(clsLabel);
        mainFrame.add(pnlJPanel);//add the jpanel to the frame
        mainFrame.pack();        //believe you already know these two lines
        mainFrame.setVisible(true);
    }
}
class YourJLabel extends JLabel {
    YourJLabel(){
        super();
        setOpaque(true); //going on memory, by default jlabels opaque is false, or transparent
    }
    protected void paintComponent(Graphics gr){
          super.paintComponent(gr);
    }
}
代码解释了

超级油漆组件(gr);在重写时应始终使用super命令,在本例中,您正在重写JPanel的paintComponent方法,因此您可以按图所示进行操作。这还支持增量绘制(我称之为增量绘制),这意味着程序不会将屏幕绘制为白色,然后绘制它要执行的操作。所以你可以画一个黑盒子,一分钟后画一个红盒子,黑盒子不会消失

gr.drawString(字符串strText,int x,int y);Graphic类的drawString方法。图形gr是由程序通过一系列隐藏方法创建的。所以不必担心创建它,只需将它放在paintComponent参数中,让程序调用paintComponent即可

对于drawString命令,x和y是坐标,我将y设置为10,因为根据我的经验,该方法的工作方式如下:从坐标(x,y)(这是相对于JPanel的)、向左和向上绘制。所以,如果y为0,文本将从JPanel中提取。这意味着您将无法看到它,因为在JPanel之外绘制的任何内容都不会出现。(我不知道具体原因)

这就是使用paintComponent,如果你使用一个循环来画每条线,它可以有效地工作;就像抽绳画一条线一样。这比下一个解决方案简单得多

下一个解决方案是使用布局。如果您希望以1乘1的方式绘制每条线,每次向下绘制一行,我建议使用gridLayout(行、列)。如果要有20行文本,该方法需要新的GridLayout(20,1)

这样做的目的是计算行和列的数量

 .    Column 1 
第1行

第2排

第3排

GridLayout的缺点是需要一个对象来保存每个字符串(在本例中,我建议使用JLabel)

您还需要启用增量绘制(或者我非常怀疑),这意味着创建一个扩展JLabel的类

最后,您还需要将JLabel作为子对象添加到JPanel中

JPanel.add(JLabel);
虽然您已经使用了一些布局材料,但这可能没有那么难

举个例子

import javax.swing.JPanel;

import java.awt.Graphics;

import java.lang.Override; //for @Override

class yourClass extends JPanel { //yourClass is the JPanel
    @Override //if you aren't overriding correctly this makes the compiler tell you
    protected void paintComponent(Graphics gr){
        super.paintComponent(gr); 
        gr.drawString("string literal or a string variable", 0,10);
    }
}
import java.awt.GridLayout;
import java.awt.Graphics;

import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JFrame;

import java.lang.Override;

class YourMainClass {
    static JFrame mainFrame;
    static YourJLabel clsLabel;
    static JPanel pnlJPanel;
    public static void main(String[]args){
        mainFrame = new JFrame("Testing"); //initialize, and set size the frame
        mainFrame.setSize(500,500);
        pnlJPanel = new JPanel();//initialize our panel
        pnlJPanel.setLayout(new GridLayout(3,1));//set its layout to gridlayout, with grid of 3 rows and 1 column
        clsLabel = new YourJLabel(); //create a jlabel, add some text to it, then add it to the jpanel
        clsLabel.setText("some");
        pnlJPanel.add(clsLabel);
        clsLabel = new YourJLabel();
        clsLabel.setText("Text");
        pnlJPanel.add(clsLabel);
        clsLabel = new YourJLabel();
        clsLabel.setText("drawn");
        pnlJPanel.add(clsLabel);
        mainFrame.add(pnlJPanel);//add the jpanel to the frame
        mainFrame.pack();        //believe you already know these two lines
        mainFrame.setVisible(true);
    }
}
class YourJLabel extends JLabel {
    YourJLabel(){
        super();
        setOpaque(true); //going on memory, by default jlabels opaque is false, or transparent
    }
    protected void paintComponent(Graphics gr){
          super.paintComponent(gr);
    }
}
这个例子有:

使用布局时,所有内容都是相对于其父级的

注意,我们不再有权访问前两个JLabel,如果您想在使用类实例时访问它们,您必须将实例存储在从您那里获取它们的位置。存储它们的最佳位置是阵列。一个简单的例子。。。 YourJLabel[]aryJLabel=新的YourJLabel[3]


[3]决定了数组的大小,一旦创建了数组,就不能更改它。[]在jLabel上表示您正在创建一个jLabel数组。

我立即想到了两种方法

第一种方法要简单得多,即使用paintComponent(图形)方法。每当程序认为需要重新绘制对象时,就会自动调用此方法,例如最小化和ERMM取消最小化保存jpanel的窗口

下面是一个简单的例子

import javax.swing.JPanel;

import java.awt.Graphics;

import java.lang.Override; //for @Override

class yourClass extends JPanel { //yourClass is the JPanel
    @Override //if you aren't overriding correctly this makes the compiler tell you
    protected void paintComponent(Graphics gr){
        super.paintComponent(gr); 
        gr.drawString("string literal or a string variable", 0,10);
    }
}
import java.awt.GridLayout;
import java.awt.Graphics;

import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JFrame;

import java.lang.Override;

class YourMainClass {
    static JFrame mainFrame;
    static YourJLabel clsLabel;
    static JPanel pnlJPanel;
    public static void main(String[]args){
        mainFrame = new JFrame("Testing"); //initialize, and set size the frame
        mainFrame.setSize(500,500);
        pnlJPanel = new JPanel();//initialize our panel
        pnlJPanel.setLayout(new GridLayout(3,1));//set its layout to gridlayout, with grid of 3 rows and 1 column
        clsLabel = new YourJLabel(); //create a jlabel, add some text to it, then add it to the jpanel
        clsLabel.setText("some");
        pnlJPanel.add(clsLabel);
        clsLabel = new YourJLabel();
        clsLabel.setText("Text");
        pnlJPanel.add(clsLabel);
        clsLabel = new YourJLabel();
        clsLabel.setText("drawn");
        pnlJPanel.add(clsLabel);
        mainFrame.add(pnlJPanel);//add the jpanel to the frame
        mainFrame.pack();        //believe you already know these two lines
        mainFrame.setVisible(true);
    }
}
class YourJLabel extends JLabel {
    YourJLabel(){
        super();
        setOpaque(true); //going on memory, by default jlabels opaque is false, or transparent
    }
    protected void paintComponent(Graphics gr){
          super.paintComponent(gr);
    }
}
代码解释了

超级油漆组件(gr);在重写时应始终使用super命令,在本例中,您正在重写JPanel的paintComponent方法,因此您可以按图所示进行操作。这还支持增量绘制(我称之为增量绘制),这意味着程序不会将屏幕绘制为白色,然后绘制它要执行的操作。所以你可以画一个黑盒子,一分钟后画一个红盒子,黑盒子不会消失

gr.drawString(字符串strText,int x,int y);Graphic类的drawString方法。图形gr是由程序通过一系列隐藏方法创建的。所以不必担心创建它,只需将它放在paintComponent参数中,让程序调用paintComponent即可

对于drawString命令,x和y是坐标,我将y设置为10,因为根据我的经验,该方法的工作方式如下:从坐标(x,y)(这是相对于JPanel的)、向左和向上绘制。所以,如果y为0,文本将从JPanel中提取。这意味着您将无法看到它,因为在JPanel之外绘制的任何内容都不会出现。(我不知道具体原因)

这就是使用paintComponent,如果你使用一个循环来画每条线,它可以有效地工作;就像抽绳画一条线一样。这比下一个解决方案简单得多

下一个解决方案是使用布局。如果您希望以1乘1的方式绘制每条线,每次向下绘制一行,我建议使用gridLayout(行、列)。如果要有20行文本,该方法需要新的GridLayout(20,1)

这样做的目的是计算行和列的数量

 .    Column 1 
第1行

第2排

第3排

GridLayout的特点是需要一个对象来容纳每条条纹