I am trying to make a text-based RPG and have a question about how to proceed the story dialogue (I'm still quite new to Java).
I want to change the content of text area by pressing a button so the dialog continues everytime you press the button.
For example, if there's a dialog like this,
Hello. I have never seen your face before.
You look like an adventurer.
So you also came to kill that wizard?
I want to display these texts one by one, not at once.
Here's my code:
package test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.*;
public class Dialogue extends JFrame implements ActionListener
{
//Window
JFrame window;
Container con;
//Font
Font basicfont;
Font bigfont;
Font timesnewroman;
//Main game screen
JPanel storyP;
JPanel inputP;
JPanel enterP;
//Main game screen Panel 3
JTextArea storyT;
//Main game screen Panel 5
JLabel inputA;
JTextField input;
JButton enterB;
public static void main(String[]args)
{
Dialogue game = new Dialogue();
game.setup();
}
public void setup()
{
window = new JFrame();
window.setBounds(0,0,1200,950);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().setBackground(Color.black);
window.setLayout(null); //Disabling the default layout.
window.setVisible(true);
basicfont = new Font("MS Gothic", Font.PLAIN, 24);
bigfont = new Font("MS Gothic", Font.BOLD, 28);
con = window.getContentPane();
// Panel Setup
storyP = new JPanel(); //This is where story text is displayed.
storyP.setBounds(50, 500, 800, 320);
storyP.setBackground(Color.white);
storyP.setLayout(new GridLayout());
inputP = new JPanel();
inputP.setBounds(50, 830, 500, 50);
inputP.setBackground(Color.black);
inputP.setLayout(new BorderLayout());
//p5.setLayout(new GridLayout());
enterP = new JPanel();
enterP.setBounds(600, 830, 120, 50);
enterP.setBackground(Color.black);
//STORY TEXT SETUP
storyT = new JTextArea();
storyT.setFont(basicfont);
storyT.setBackground(Color.black);
storyT.setForeground(Color.white);
storyT.setEditable(false);
//INPUT BOX SETUP
inputA = new JLabel(">");
inputA.setBackground(Color.black);
inputA.setForeground(Color.white);
inputA.setFont(bigfont);
input = new JTextField(15);
input.setBackground(Color.black);
input.setForeground(Color.white);
input.setBorder(null);
input.setFont(bigfont);
input.addActionListener(this);
enterB = new JButton("ENTER");
enterB.setFont(timesnewroman);
enterB.addActionListener(this);
//ADDING
storyP.add(storyT);
inputP.add("West",inputA);
inputP.add(input);
enterP.add(enterB);
//VISIBILITY
con.add(storyP);
con.add(inputP);
con.add(enterP);
Opening();
}
public void Opening()
{
storyT.setText("Hello. I have never seen your face before.");
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==enterB)
{
storyT.setText("You look like an adventurer.");
}
}
}
I could change the text from "Hello. I have never seen your face before" to "You look like an adventurer" by pressing ENTER button that I created.
But I don't know how to go further(to display "So you also came to kill that wizard?") from this point since my ENTER button's action is assigned to display a specific text ("You look like an adventurer").
I don't even know where to write the 3rd line so it is not written in this code yet.
There could be a counter and a loooong switch:
counter++;
switch(counter){
case 0: storyT.setText("You look like an adventurer.");
case 1: storyT.setText("So you also came to kill that wizard?");
case 2: ....
}
But it will be quite bad if you will have hunderds of texts.
For this i would use array of Strings or an ArrayList. then you can use counter to get to index of text to print
It will be much better if you will have these texts in a file. Than you can read it line by line with Scanner class.
Scanner sc = new Scanner(new File("texts.txt"));
ArrayList<String> texts = new ArrayList<String>();
while(sc.hasNextLine())
text.add(sc.nextLine());
sc.close();
it throws FileNotFoundException I think
Than your linstener content could be:
storyT.setText(texts.get(counter++));
The variable texts should be declared as an instance variable, not in method body:
private ArrayList<String> texts;
....
....
....
texts=new ArrayList<String>();
In your case, I'd do this...
declare a Stack.
Stack<String> texts = new Stack<String>();
A stack is like a physical stack. It has two main methods. Push(String a) and pop(). Push will put a String on top of the stack and pop() will return the String that is on the bottom.
In your main method, you simply fill this stack with the texts you want.
e.g.
texts.push("you look like an adventurer");
texts.push("etc..");
texts.push("etc..");
then, in you actionlistener, you just do this instead of what you had:
storyT.setText(texts.pop());
if you want some safety measures, you can do this:
if (texts.hasnext())
storyT.setText(texts.pop());
This checks if the stack still has texts stored up in it. If not, the stack won't be popped, in which case you'll get null, which isn't good.
Related
I'm trying to add a .gif image to a JButton, but can't seem to get the image to load when i run the code. I've included a screenshot. Included is the frame that's created. I'd really appreciate any help that can be provided. Stack is telling me I can't enter images yet, so it created a link for it. I'm also going to enclose the actual code here:
package java21days;
import javax.swing.*;
import java.awt.*;
public class ButtonsIcons extends JFrame {
JButton load, save, subscribe, unsubscribe;
public ButtonsIcons() {
super("Icon Frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
//Icons
ImageIcon loadIcon = new ImageIcon("load.gif");
ImageIcon saveIcon = new ImageIcon("save.gif");
ImageIcon subscribeIcon = new ImageIcon("subscribe.gif");
ImageIcon unsubscribeIcon = new ImageIcon("unsubscribe.gif");
//Buttons
load = new JButton("Load", loadIcon);
save = new JButton("Save", saveIcon);
subscribe = new JButton("Subscribe", subscribeIcon);
unsubscribe = new JButton("Unsubscribe", unsubscribeIcon);
//Buttons To Panel
panel.add(load);
panel.add(save);
panel.add(subscribe);
panel.add(unsubscribe);
//Panel To A Frame
add(panel);
pack();
setVisible(true);
} //end ButtonsIcon Constructor
public static void main(String[] arguments) {
ButtonsIcons ike = new ButtonsIcons();
}
} //end ButtonsIcon Class
enter image description here
The easiest way is.
Label or Jbutton and what ever else supports HTML 3.5
JLabel a = new JLabel("");
add that to your container.
Haven't figured out how to enter code sorry
I am trying to create a path choosing game similar to ones like Oregon trail. I am trying to find out why when i try to to create a JLabel to show text, the text that I am setting it to is an array in a different class, called StoryLine. Whenever I add the Label to my frame the text doesn't pop up on the screen. I have changed the text to "hey" and it worked, but for some reason it doesn't work with my array.
Consider this code:
public static void intro() {
JFrame frame = new JFrame("Lost Boy");
JLabel textbox = Components.Textbox();
JLabel bed = Components.Bedroom();
JLabel text = Components.TextFormat(StoryLine.story[2]);
frame.setSize(1000, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
text.setBounds(10, -70,400,200);
frame.add(text);
frame.add(textbox);
frame.add(bed);
frame.setLayout(null);
frame.setVisible(true);
}
Class for Components.TextFormat
public static JLabel TextFormat(String stry) {
JLabel text = new JLabel();
text.setText(stry);
text.setFont(MyFont());
text.setForeground(Color.WHITE);
return text;
}
Class for StoryLine.string[]
public static void Script() {
story[2] = "You're just putting on your shoes before you walk out the\n"
+ "door. You see your dog sitting at the door wagging his tail\n"
+ "expecting to come. Do you choose to bring him?";
I don't know what I am doing wrong. I am trying to take a JTextField user input to be stored and displayed in a JList, but every time the button is pressed to store the user input the JList remains blank. Any help would be greatly appreciated.
DefaultListModel<String> model = new DefaultListModel<String>();
menuList = new JList<String>(model);
menuList.setBounds(500, 65, 300, 400);
menuList.setSelectionBackground(Color.LIGHT_GRAY);
menuList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
btnCreateMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
childFrame = new JFrame("New Menu");
childFrame.setBounds(340, 300, 400, 200);
childFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
childFrame.getContentPane().setLayout(null);
childFrame.setVisible(true);
lblNewMenu = new JLabel("Menu Name:");
lblNewMenu.setBounds(30, 60, 200, 20);
childFrame.getContentPane().add(lblNewMenu);
input = new JTextField();
String userInput = input.getText();
input.setBounds(lblNewMenu.getX() + 80, lblNewMenu.getY(), 250, 30);
childFrame.getContentPane().add(input);
btnMenuInput = new JButton("Create New Menu");
btnMenuInput.setBounds(120, 100, 200, 30);
btnMenuInput.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
model.addElement(userInput);
menuList.setModel(model);
childFrame.setVisible(false);
Entree selectedEntree = (Entree)cboEntrees.getSelectedItem();
Side selectedSide = (Side)cboSides.getSelectedItem();
Salad selectedSalad = (Salad)cboSalads.getSelectedItem();
Dessert selectedDessert = (Dessert)cboDesserts.getSelectedItem();
Menu menu = new Menu(userInput, selectedEntree, selectedSide, selectedSalad, selectedDessert);
menuArray.add(menu);
}
});
childFrame.getContentPane().add(btnMenuInput);
}
});
mainframe.setVisible(true);
This line
userInput = input.getText();
needs to be called first in the ActionListener. Otherwise you never get the latest String from the text field.
e.g.,
public void actionPerformed(ActionEvent e){
userInput = input.getText();
model.addElement(userInput);
//menuList.setModel(model); // not needed
Also, as mentioned by camickr in comment, avoid using null layouts and setBounds as this fights against the Swing GUI library rather than working with it, making it much harder to create flexible easy to update and edit GUI's.
Also, the childFrame top-level window should be a JDialog and not a second JFrame. Please see The Use of Multiple JFrames: Good or Bad Practice? for more on this.
Also note that you should create the entire dialog or Frame before you make it visible, or else some of the items may not be visible at first.
Another problem is the use of JFrame.HIDE_ON_CLOSE. You should probably be using DISPOSE_ON_CLOSE instead. Otherwise the frame will just be hidden, but will still exist, possibly for the life of the program.
I want to keep the values of Textarea1 after inputting them through the textfield1 via a button. Everytime I finish running it the value disappears for a new one. The first time I do it I get the value of the name I inserted, however when i do it a second time it erases. please help me, thanks. Here is the code:
import javax.swing.UIManager.LookAndFeelInfo;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.border.Border;
import javax.swing.*;
public class GUI_project2 extends JFrame {
private JMenuBar menuBar;
private JButton button1;
private JTextArea textarea1;
private JTextField textfield1;
static String MYARRAY[] = new String[4];
static int COUNTER = 0;
static String NEWITEM = null;
//Constructor
public GUI_project2(){
this.setTitle("GUI_project2");
this.setSize(1118,845);
//menu generate method
generateMenu();
this.setJMenuBar(menuBar);
//pane with null layout
JPanel contentPane = new JPanel(null);
contentPane.setPreferredSize(new Dimension(1118,845));
contentPane.setBackground(new Color(192,192,192));
button1 = new JButton();
button1.setBounds(206,109,90,35);
button1.setBackground(new Color(214,217,223));
button1.setForeground(new Color(0,0,0));
button1.setEnabled(true);
button1.setFont(new Font("sansserif",0,12));
button1.setText("Add Word");
button1.setVisible(true);
//Set methods for mouse events
//Call defined methods
button1.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
ButtonClicked(evt);
}
});
textfield1 = new JTextField();
textfield1.setBounds(203,46,90,35);
textfield1.setBackground(new Color(255,255,255));
textfield1.setForeground(new Color(0,0,0));
textfield1.setEnabled(true);
textfield1.setFont(new Font("sansserif",0,12));
textfield1.setText("");
textfield1.setVisible(true);
textarea1 = new JTextArea();
textarea1.setBounds(27,48,150,100);
textarea1.setBackground(new Color(255,255,255));
textarea1.setForeground(new Color(0,0,0));
textarea1.setEnabled(true);
textarea1.setFont(new Font("sansserif",0,12));
textarea1.setText("");
textarea1.setBorder(BorderFactory.createBevelBorder(1));
textarea1.setVisible(true);
//adding components to contentPane panel
contentPane.add(button1);
contentPane.add(textfield1);
contentPane.add(textarea1);
//adding panel to JFrame and seting of window position and close operation
this.add(contentPane);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.pack();
this.setVisible(true);
}
//Method mouseClicked for button1
private void ButtonClicked (MouseEvent evt) {
//TODO
NEWITEM = textfield1.getText();
if (NEWITEM.compareTo("end")!=0){
MYARRAY[COUNTER] = NEWITEM;
COUNTER++;
if (COUNTER == MYARRAY.length){
increaseArraySize();
}
}
String NEWITEM = "";
listArray();
}
public void listArray(){
for (int X=0;X<MYARRAY.length;X++){
textarea1.setText(textfield1.getText());
}
}
public static void increaseArraySize(){
System.out.print("Here we increase the size to ");
String TEMP[] = new String[MYARRAY.length*2];
System.arraycopy(MYARRAY, 0, TEMP, 0, MYARRAY.length);
MYARRAY = TEMP;
System.out.println(TEMP.length);
}
//method for generate menu
public void generateMenu(){
menuBar = new JMenuBar();
JMenu file = new JMenu("File");
JMenu tools = new JMenu("Tools");
JMenu help = new JMenu("Help");
JMenuItem open = new JMenuItem("Open ");
JMenuItem save = new JMenuItem("Save ");
JMenuItem exit = new JMenuItem("Exit ");
JMenuItem preferences = new JMenuItem("Preferences ");
JMenuItem about = new JMenuItem("About ");
file.add(open);
file.add(save);
file.addSeparator();
file.add(exit);
tools.add(preferences);
help.add(about);
menuBar.add(file);
menuBar.add(tools);
menuBar.add(help);
}
public static void main(String[] args){
System.setProperty("swing.defaultlaf", "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new GUI_project2();
}
});
}
}
The first time I do it I get the value of the name I inserted, however when i do it a second time it erases
What do you think the setText(..) method does? Did you read the API for a description of the method?
textarea1.setText(textfield1.getText());
should be:
textarea1.append(textfield1.getText());
You can't program if you don't read the API! Take the time now to read the JTextArea API for other methods you may find useful in the future.
Every time you call textarea1.setText(someText), you are setting a fresh new content on the textarea that comes and replaces any other text that was here before.
What you should do is:
final StringBuilder content = new StringBuilder();
for (int X=0;X<MYARRAY.length;X++){
sb.append(MYARRAY[X]);
//Add this line if you eventually want to add a new line
sb.append("\r\n");
}
textarea1.setText(sb.toString());
Hello CSStudent I tried to stay as close as your code as possible and edited your listArray method in order to achieve what you are Aiming for.
I want to keep the values of Textarea1 after inputting them through the textfield1 via a button. Everytime I finish running it the value disappears for a new one. The first time I do it I get the value of the name I inserted, however when i do it a second time it erases. please help me, thanks. Here is the code:
What your current code does is 'SETTING' the text of your textarea.
According to the Docs setText does this:
Sets the text of this TextComponent to the specified text. If the text is null or empty, has the effect of simply deleting the old text. When text has been inserted, the resulting caret location is determined by the implementation of the caret class.
So lets take a look at your listArray method.
public void listArray(){
for (int X=0;X<MYARRAY.length;X++){
textarea1.setText(textfield1.getText());
}
}
It loops through your String Array which starts at the Size of 4 and increases by *2 if required. The problem is that since the size of the Array is 4 and you add the String on position 0 the array looks like this {"First thing you insert",null,null,null} according to the quote from the docs if the value is null or empty it will simply delete the old text. This is why it erases as you say.
However if you slighty modify it you will achieve what you desire
public void listArray(){
textarea1.setText("");
for (int X=0;X<MYARRAY.length;X++){
if(MYARRAY[X] != null)
textarea1.append(MYARRAY[X]+"\n");
}
}
As stated earlier I tried to stay as close to your code as possible, let me explain what this does aswell.
First of all it clears the textarea by inserting "" which is a blank String, followed by that it will loop through your Array and only IF it IS NOT (!=) null it will append the saved String and a linebreak ("\n"). (This check prevents the textarea from getting erased)
If this reply solved your Problem please make sure to mark my answer as accepted, click on the check mark beside the answer to toggle it from hollow to green
I am making a Hangman game and one of the things I want to make is JLabel text , which updates with ex."_ _ _ _ ", depending on word.
I can share code if you want.
Try using setText(); with your JLabel.
JLabel.setText("ex."+text);
super.update(this.getGraphics());
This will create a new jLabel and set its text.
JLabel label = new JLabel();
label.setText("____");
You will need to add this label to something like a JFrame.
If you want to quick and easy, here is the code to make a simple window with a label.
import javax.swing.JFrame;
import javax.swing.JLabel;
public class App {
public static void main(String[] args) {
JFrame frame = new JFrame("Swing Frame");
JLabel label = new JLabel("This is a Swing frame", JLabel.CENTER);
label.setText("____"); // Look familiar? <----------
frame.add(label);
frame.setSize(350, 200); // width=350, height=200
frame.setVisible(true); // Display the frame
}
}
To update the text in a label you use label.setText("New text").
However, without seeing the code, it's hard to say why it doesn't update, as there may be other things wrong.
public void updatemylabel(String text){
JLabel.setText("ex."+text);
//place this method inside your Jframe class extend from javax.swing.Jframe
}