Reputation: 25
This might be a very obvious question to some, but I cannot figure it out. I am new to Eclipse and have only been programming with Dr.Java. I am creating a mad libs program where the user has to enter nouns, adjectives, names, numbers and at the end it will display it inside a story.
After the user has entered all the required info, I want the finished story to open in a jPanel. I cannot figure out how to add the text to the jPanel.(I want the text beginning with the c. code to be displayed in a window after the user has entered all the info) Here's the code:
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();
}
}
Also, I am a little confused about how the jPanel works. I found many ways to display things on the jPanel and I don't know which one I should use.
Upvotes: 2
Views: 14528
Reputation: 986
I immediately think of two ways to do this.
The first is much more simple, that is to use the paintComponent(Graphics) method. This method is automatically called whenever the program thinks the object needs to be repainted, for example minimizing and ermmm de-minimizing the window that holds the jpanel.
here is a quick example...
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);
}
}
The code explained...
super.paintComponent(gr); Should always use the super command when overriding, in this case you are overriding JPanel's paintComponent method, so you do as shown. This also enables incremential painting (as I called it), which means the program does not paint the screen white, then paint what it is post to do. So you can draw a black box, then a minute later draw a red box and the black box won't disappear.
gr.drawString(String strText,int x,int y); Graphic class's drawString method. Graphics gr is created by the program through a bunch of hidden methods. So don't worry about creating it, just have it in the paintComponent parameters, and let the program call paintComponent.
For the drawString command, x and y is the coordinates, I have y at 10 because from my experiences the method works in the following way: From coordinate (x,y) (this is relative to the JPanel), draw to the left, and upwards. So if you have y at 0, your text will be drawn off of the JPanel. Which means you won't be able to see it, as anything drawn outside of the JPanel just doesn't appear. (I don't know why specifically)
That's using paintComponent, which could work effectively, if you use a loop to draw each line; as drawString draws a single line. This is a lot more simple than the next solution.
The next solution is using layouts. If you want to drawn each line 1 by 1, going down a row each time, I would recommend the gridLayout(rows, columns). If you were to have 20 lines of text, the method would like new GridLayout(20, 1);
The idea is you're counting the number of rows and columns.
. Column 1
Row 1
Row 2
Row 3
etc
The catch with the GridLayout is you need an object to hold each string (in this case, I would recommend JLabel).
You would also need to have incremential painting enabled, (or I would highly suspect so), which means creating a class that extends JLabel.
Lastly, you also need to add the JLabel as a child to JPanel
JPanel.add(JLabel);
Although seeing as you have already used some layout stuff, this might not be as hard.
As for an example...
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);
}
}
This example does:
When using layouts, everything is relative to its parent.
Note, we don't have access to the first two JLabels anymore, if you want to access them while using class instances, you'll have to store the instances somewheres that get them from you. The perfect place to store them is in an array. A quick example... YourJLabel[] aryJLabel = new YourJLabel[3];
The [3] determines the size of the array, you can not change this once it is made. [] on YourJLabel means you are creating an array of YourJLabel.
Upvotes: 6