I'm working on a textbased simple roleplaying game for my exame, but i have ran into some problems with my gui.
When the player registers, he can spend some attribute points in 3 categories. The gui is programmed to show the Raise Strength etc. button, if the player have any attribute points.
And that works cool, but then when the player clicks on a raise button, an attributepoint is taken for him, the problem is, that the gui doesn't seem to update.
if(Controller.player.getAttributePoints() > 0) {
JLabel attriL = new JLabel("You have " + Controller.player.getAttributePoints() + " unspent Attribute points.");
attriL.setBounds(110, 30, 250, 30);
hPanel.add(attriL);
JButton setStrB = new JButton("Raise Strength");
setStrB.setBounds(125, 60, 200, 30);
setStrB.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// tabbedPane.removeAll();
Controller.player.setAttributePoints(Controller.player.getAttributePoints()-1);
Controller.player.setStrength(Controller.player.getStrength()+1);
gameCtn.validate();
gameCtn.repaint();
System.out.println(Controller.player.getStrength());
}
});
hPanel.add(setStrB);
}
As you can see i have tried using repaint and validate on my container but with no luck, also i have tried on the Frame, and the panel, nothing seems to work?
Am i doing something wrong?
Thx
not clear if Controller... didn't invoked long timed and hard taks, basically (if you remove and then add new JComponents) to the GUI then you have to call
revalidate();
repaint();// not required on all cases
simple demonstrations what's happens, what's possible or most completed here
Sorry about that.
You have no code that says to make the button invisible.
public void actionPerformed(ActionEvent evt) {
...
if (whateverIsLeft < 1) {
JButton src = (JButton)evt.getSource();
src.setVisible(false);
}
attriL.setText("You have " + whateverIsLeft + " attribute points left");
}
Related
I am trying to create RedPraire system that we use on my warehouse as a training and i am stuck for 3 days with changing from create account screen to error screen if you enter less than 3 characters. Am i missing something?
tried calling frame to make it not visible and make other visible also tried to just make it new JLabel somehow wouldnt work as well in actionPerformer...
frameCreate.add(c1);
frameCreate.add(c2);
frameCreate.add(c4);
frameCreate.add(ca1);
frameCreate.add(pc1);
frameCreate.add(c5);
frameCreate.add(c99);
frameCreate.setVisible(true);
frameCreate.setSize(600, 450);
frameCreate.setResizable(false);
frameCreate.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameCreate.setLocationRelativeTo(null);
frameCreate.getContentPane().setBackground(Color.black);
// ERROR USERNAME FRAME
c6 = new JLabel("Username too short. Press Enter");
c6.setBounds(250, 200, 100, 100);
frErrUs.add(c6);
frErrUs.setVisible(false);
frErrUs.setSize(600, 450);
frErrUs.setResizable(false);
frErrUs.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frErrUs.setLocationRelativeTo(null);
frErrUs.getContentPane().setBackground(Color.black);
}
public void actionPerformed(ActionEvent e) {
String getT = e.getActionCommand();
if(getT.length() < 3) {
frameCreate.setVisible(false);
frErrUs.setVisible(true);
}
I've expected it to change beetween frames showing only error frame but cant really figure it out
If the frames do not appear/disappear as you expect, that suggests that your actionPerformed method is not being called. Check that the right add listener method has been called.
But instead of creating a second frame to display an error message, perhaps you should use a dialog. Here's a simple way to do that:
JOptionPane.showMessageDialog(frameCreate, "Username too short", "Error", JOptionPane.ERROR_MESSAGE);
I have an existing frame with 2 panels on it.
When the user presses one of the JButtons found on the JPanel, I need to handle the event by opening a JDialog box that allows the user to set settings - settings that include 3 sliders and 2 drop lists, when the user saves the settings I need to pull them from this dialog and use them later.
I'm new to GUI and for the past 2 and a half days I have searched for many ways to create this such of thing, and I have succeeded to make a slider and a drop list each one by its own, but I still haven't figured out how to handle an event while a frame is open, because from what I have seen I need a new JFrame, but what happens to the one alrady open? In addition, how can I make this dialog with these sliders and drop lists?
Here is the code I wrote for the slider:
public void setSlider()
{
optionPane = new JOptionPane();
JSlider slider = getSlider(optionPane);
JSlider slider2=getSlider(optionPane);
optionPane.setMessage(new Object[] { "Select animal's speed: ", slider });
optionPane.setMessageType(JOptionPane.QUESTION_MESSAGE);
optionPane.setOptionType(JOptionPane.OK_CANCEL_OPTION);
dialog = optionPane.createDialog(Frame, "Set speed");
dialog.pack();
dialog.setVisible(true);
int speed = (int) optionPane.getInputValue();
}
static JSlider getSlider(final JOptionPane optionPane) {
JSlider slider = new JSlider();
slider.setMajorTickSpacing(1);
slider.setMaximum(10);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent) {
JSlider theSlider = (JSlider) changeEvent.getSource();
if (!theSlider.getValueIsAdjusting()) {
optionPane.setInputValue(new Integer(theSlider.getValue()));
}
}
};
slider.addChangeListener(changeListener);
return slider;
}
I hope this post is specified enough.
Thanks!!!
As you want the dialog's results "only after it closes," simply collect the results at that time. Starting from this complete example, the following update produces the output and appearance shown:
…
JSlider slider = new JSlider();
panel.add(slider);
int result = JOptionPane.showConfirmDialog(null, panel, "Test",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
System.out.println(combo.getSelectedItem()
+ " " + field1.getText()
+ " " + field2.getText()
+ " " + slider.getValue());
} else {
…
One 1234.56 9876.54 50
I am writing a Blackjack program using JFrame and trying to keep it as simple as possible. My JButton, jbHit works with a single click, however it overwrites the playersHand and playerSide slot with every click. I would like it to work with multiple clicks (3 clicks - since that is the max number of cards you can get after the first two are dealt) options It should count them so to speak so that the array index can record the card image. Here is my ActionListener code that I have so far. I am afraid I am stuck. Should I use some sort of for loop with an int i++?
//Hit Button ActionListener
jbHit.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if ( playerValue < 21 ) {
//Draw a card
Card c = deck.drawCard();
playersHand.add(c);
playerSide[2].setIcon( new ImageIcon( c.getFilename() ) );
}
//If playerValue > 21, bust
else if ( playerValue > 21 ) {
//Toggle Buttons
jbDeal.setEnabled(true);
jbHit.setEnabled(false);
jbStand.setEnabled(false);
jbDoubleDown.setEnabled(false);
message = "You bust.";
}
}
});
You could create an array of "action commands" and every time you click the button, the action command changes to the next. If you reach the end, set the index back to zero. Perhaps something like this:
public static void main(String[] args)
{
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Action");
String[] commands = {"command1", "command2", "command3"};
button.setActionCommand(commands[0]);
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JButton btn = (JButton)e.getSource();
String cmd = btn.getActionCommand();
System.out.println("Command: " + cmd);
if(cmd.equals("command1"))
{
btn.setActionCommand(commands[1]);
System.out.println("Command 1 was pressed");
}
else if(cmd.equals("command2"))
{
btn.setActionCommand(commands[2]);
System.out.println("Command 2 was pressed");
}
else if(cmd.equals("command3"))
{
btn.setActionCommand(commands[0]);
System.out.println("Command 3 was pressed");
}
else
System.out.println("Something went wrong!");
}
});
panel.add(button);
frame.add(panel);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
If you are using Java 7 or later, you can replace the if/else with a Switch statement.
I believe you're looking for a logical flag based on an integer, for example:
if(cardsDealt < 3) {
// DoThings();
} else {
return;
}
Which would require you to do
cardsDealt++;
at the bottom of your button click handle.
If this is not what you're asking, please re-explain the question.
It sounds like you might be a little confused about how jbHit will be called. Realize that it will be called one complete time every time the mouse is clicked. It's not like it inherently knows that it is on the second or third click. Add a class member like int clickCount; that you increment at the appropriate point inside of jbHit. Then you can alter your method's response depending on the value of clickCount.
I created a frame. within the frame there is a combobox.
I am trying that each option from the combobox will create something else (JCheckBox,JRadioButton).
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
String selection = comboBox.getSelectedItem().toString();
label3.setText(input[comboBox.getSelectedIndex()]);
//panel_mid.removeAll();
if(comboBox.getSelectedItem().toString().equals("Pilot")){
panel_mid.removeAll();
panel_mid.add(label3,BorderLayout.WEST);
panel_mid.add(text_bottom);
panel_mid.setBorder(new TitledBorder(comboBox.getSelectedItem().toString() + " options"));
panel_mid.add(jchkCaptain);
}
if(comboBox.getSelectedItem().toString().equals("Host")){
panel_mid.removeAll();
panel_mid.add(label3,BorderLayout.WEST);
panel_mid.add(text_bottom);
panel_mid.setBorder(new TitledBorder(comboBox.getSelectedItem().toString() + " options"));
panel_mid.add(regular = new JRadioButton("Regular"));
panel_mid.add(bachir = new JRadioButton("Bachir"));
panel_mid.add(calcelan = new JRadioButton("Calcelan"));
}
if(comboBox.getSelectedItem().toString().equals("Office")){
panel_mid.removeAll();
panel_mid.add(label3,BorderLayout.WEST);
panel_mid.add(text_bottom);
panel_mid.setBorder(new TitledBorder(comboBox.getSelectedItem().toString() + " options"));
}
}
});
when picked Pilot only JCheckBox shuold appear.
when picked Host only JRadioButton shuold appear.
when picked Office nothing shuold appear.
the problem is when i pick host and then pilot and then host it doesnt show the JRadioButton.
thanks for help.
you have to tell the LayoutManager something is/are changed, LayoutManager haven't any notifier about, you have to notify programatically about this changes
use container.revalidate() and container.repaint(variable for JPanels in your case) as last code line, only one time ,after all changes to the already visible Swing GUI are done
use CardLayout for to switch between views (JPanels in your case)
I'm currently working on a java project to keep me busy for the summer. I've just finished my first year of University so I have a basic knowledge of Java and how it works. For my project I've decided to make a choose you own adventure game sort of thing. Where the user is given some dialogue then they are given two options of how to proceed. So far it's going well and I've came to a flaw that I can't get my head around solving. Below is my code for my primary class.
public DisplayPanel() {
core = new Core();
stat = new StatusPanel();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Quest!");
middle = new JPanel();
bottom = new JPanel();
left = new JButton("Explore");
right = new JButton("Think");
textArea = new JTextArea();
middle.setLayout(new GridLayout(1, 1));
middle.add(textArea);
bottom.add(stat);
left.addActionListener(this);
right.addActionListener(this);
setLayout(new BorderLayout());
add(left, BorderLayout.WEST);
add(right, BorderLayout.EAST);
add(middle, BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH);
changeText("You wake up in a strange woods and walk forwards into the mist\n " +
"You decide whether it's best to think how you got here " +
"\n or search the area for clues");
setSize(600, 700);
setResizable(false);
setVisible(true);
}
public static void changeText(String newText) {
textArea.setText(newText);
}
public static void appendText(String newText) {
textArea.append(newText);
}
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
Monsters m = new Monsters();
try {
core.load("goblinstier1.txt");
} catch (IOException e1) {
e1.printStackTrace();
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////LEFT/////OPTION1////////////////////////////
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
//////////////////////////////ORIGINAL CHOICE////////////////////////////
/////////////////////////////////////////////////////////////////////////
if(e.getSource() == left) {
textArea.setText("You explore the area for clues and hear a rustling in a bush.\n " +
"It might be someone who can help? Or it could be a monster! \n" +
"You ready your knife in preperation!\n");
stat.incrementClickCount();
option2a = new JButton("Talk");
option2a.addActionListener(this);
option2a.setActionCommand("left2a");
add(option2a, BorderLayout.WEST);
option2b = new JButton("Leave");
option2b.addActionListener(this);
option2b.setActionCommand("right2b");
add(option2b, BorderLayout.EAST);
right.setVisible(false);
left.setVisible(false);
}
/////////////////////////////////////////////////////////////////////////
////////////////////////////LEFTA/////OPTION2////////////////////////////
/////////////////////////////////////////////////////////////////////////
Monsters temp = null;
temp = core.anyMonster();
if(cmd == "left2a") {
option2a.setText("Attack!");
option2b.setText("Flee!");
stat.incrementClickCount();
fightClick++;
if(fightClick >=2) {
appendText("You grip your shiv and cleave!");
temp.cleave();
if(temp.getHealth()<=0) {
appendText("You have " +stat.getHealth2()+ " health remaining ");
stat.gold();
stat.xp();
}else {
stat.hit();
}
}
}
My problem lies within LEFTA Option two I've tried to script a sort of fight system where the user has the chance to fight or flee. The way this works is by a method in my core class called anyMonster I will display it below.
public Monsters anyMonster() {
int index = randomGenerator.nextInt(monsters.size());
Monsters monsters1 = monsters.get(index);
DisplayPanel.changeText("A monster appears! It's a " + monsters1 + "!\n What shall you do?\n");
return monsters1;
}
The method loops through a pre set arrayList and picks a "Monster" at random. As you can see in the DisplayPanel I tried to call this in the actionPerformed class and then if the user presses a button it will attack the monster, code below.
public void cleave()
{
randomNum = 7 + (int)(Math.random() * ((10 - 7) + 1));
newHealth=health-randomNum;
health=newHealth;
DisplayPanel.appendText(" You attack for " +randomNum+ " Damage, it has " +health+ " health remaining!\n ");
if(health<=0){
DisplayPanel.appendText("The monster falls to the ground");
}
}
}
The way i made this work in DisplayPanel was assigning the method to a temp value and then calling the cleave() method from that which works. The problem is that every time i click the button it will select a new monster each time. I realise why this is happening, of course it's a button it will just do the same action each time. The problem is I'm completely out of ideas on how to solve this. Which is frustrating, I'd really like to continue with my project and any help you can give to a newbie would be highly appreciated. Thanks in advance, Rob.
Rather than create your minsters in actionPerformed, you should create this as a field, that way your monsters are only created once.