Java Key Event won't execute once I press a button - java

Hi hope someone can tell me what I am doing wrong with my Key Event.
I am using a Card Layout to navigate through two of my JPanels atm. To do so I use Action Events as well as Key Events. The action events will toggle between JPanels when a button is pressed while the key events will hide away the buttons when a key is pressed. All good with the key events, it does what I want (call a method on one of the panels to set the bounds of the buttons placed inside it eq: button.setBounds(-1, -1, 150, 40); but when I press any of the buttons the key event wont respond despite not having any event on the buttons that I press. Below is my code, for simplicity I removed the non relevant parts of the panels like what they are meant to do.
Thanks in advance and please let me know if I need to provide more clues or to edit the code more, I will try my best to make the code clearer.
public class PanelContainer extends JPanel implements ActionListener, KeyListener{
GamePanel game = new GamePanel();
MainMenuPanel mainMenu = new MainMenuPanel();
CardLayout cards = new CardLayout();
public PanelContainer(){
setLayout(cards);
this.setFocusable(true);
this.addKeyListener(this);
mainMenu.newGameButton.addActionListener(this);
add(mainMenu, "Card1");
add(game, "Card2");
}
#Override
public void actionPerformed(ActionEvent aevt){
cards.show(this, "Card2");
game.action();
}
#Override
public void keyTyped(KeyEvent kevt){
}
#Override
public void keyPressed(KeyEvent kevt){
}
#Override
public void keyReleased(KeyEvent kevt){
if(kevt.getKeyCode() == KeyEvent.VK_ESCAPE || kevt.getKeyChar() == 'O' || kevt.getKeyChar() == 'o'){
game.shw(); //shw() is a method inside GamePanel that sets the bounds of the buttons
}
else if (kevt.getKeyChar() == 'h' || kevt.getKeyChar() == 'H'){game.hid();}
}
}
public class MainMenuPanel extends JPanel
{
private URL workingDir = this.getClass().getResource("imgresources/brick_wall.png") ;
private ImageIcon icon = new ImageIcon(workingDir) ;
private Image img = icon.getImage();
//create and initiate buttons;
JButton newGameButton = new JButton("New Game");
JButton highScoreButton = new JButton("High Scores");
JButton controlsButton = new JButton("Controls");
Point[] points = new Point[1000];
public MainMenuPanel(){
add(newGameButton);
add(highScoreButton);
add(controlsButton);
setPoints();
}
public void setButtonsBounds(){
newGameButton.setBounds(450, 200, 200, 40);
highScoreButton.setBounds(450, 250, 200, 40);
controlsButton.setBounds(450, 300, 200, 40);
}
#Override
public void paintComponent(Graphics g){
try{
super.paintComponent(g);
Graphics2D d2 = (Graphics2D) g;
d2.setColor(new Color(0, 0, 0));
d2.fillRect(0, 0, this.getWidth(), this.getHeight());
setButtonsBounds();
for(int i=0; i<275; i++){
d2.drawImage(img, points[i].x +200, points[i].y, this);
}
}catch(Exception e){}
}
}
public class GamePanel extends JPanel implements Runnable{
JButton button = new JButton("Main Menu");
JButton button2 = new JButton("Exit Game");
void shw(){
add(button);
add(button2);
button.setBounds(400, 200, 150, 20);
button2.setBounds(400, 240, 150, 20);
}
void hid(){
button.setBounds(1, 1, 150, 20);
button2.setBounds(1, 40, 150, 20);
}
}

It's a focus issue. Use Key Bindings instead of a KeyListener so you don't have to worry about this issue (and for other benefits as well -- check the Key Bindings tutorial for details).
Here's my SSCCE that demonstrates what I'm talking about. Note that both KeyListener and key bindings work until you press a button, and then only bindings work:
import java.awt.event.*;
import javax.swing.*;
public class KeyBindingsEg {
private static void createAndShowGui() {
PanelContainer mainPanel = new PanelContainer();
JFrame frame = new JFrame("KeyBindingsEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class PanelContainer extends JPanel {
public PanelContainer() {
this.setFocusable(true);
this.addKeyListener(new MyKeyListener());
JButton newGameButton = new JButton("New Game");
newGameButton.addActionListener(new MyActionListener());
add(newGameButton);
setKeyBindings();
}
private void setKeyBindings() {
Action hideAction = new BindingAction(BindingAction.HIDE);
Action showAction = new BindingAction(BindingAction.SHOW);
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
actionMap.put(BindingAction.HIDE, hideAction);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_H, 0), BindingAction.HIDE);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_H, KeyEvent.SHIFT_DOWN_MASK),
BindingAction.HIDE);
int[] showKeys = { KeyEvent.VK_O, KeyEvent.VK_ESCAPE };
actionMap.put(BindingAction.SHOW, showAction);
for (int key : showKeys) {
inputMap.put(KeyStroke.getKeyStroke(key, 0), BindingAction.SHOW);
inputMap.put(KeyStroke.getKeyStroke(key, KeyEvent.SHIFT_DOWN_MASK),
BindingAction.SHOW);
}
}
private class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent aevt) {
System.out.println("button pressed");
}
}
private class MyKeyListener extends KeyAdapter {
public void keyReleased(KeyEvent kevt) {
if (kevt.getKeyCode() == KeyEvent.VK_ESCAPE
|| kevt.getKeyChar() == 'O' || kevt.getKeyChar() == 'o') {
System.out.println("KeyListener: show");
} else if (kevt.getKeyChar() == 'h' || kevt.getKeyChar() == 'H') {
System.out.println("KeyListener: hide");
}
}
}
private class BindingAction extends AbstractAction {
public static final String HIDE = "Hide";
public static final String SHOW = "Show";
public BindingAction(String text) {
super(text);
putValue(ACTION_COMMAND_KEY, text);
}
#Override
public void actionPerformed(ActionEvent evt) {
String actionCommand = evt.getActionCommand();
if (actionCommand.equals(HIDE)) {
System.out.println("key bindings: hide");
} else if (actionCommand.equals(SHOW)) {
System.out.println("key bindings: show");
}
}
}
}

Related

Calling non-local variable in ActionPerformed

I have a circle randomly painted with 3 different colors (BLUE, RED and GREEN) and 3 Buttons with this same colors(BLUE, RED and GREEN) and if the Circle is RED and I press the RED Button I need to show up in the Label YOU WON if you choose wrong color YOU LOSE. It's very simple but i can't call in the ActionPerformed the variable (that is the color to match with the button) from paintComponent. Sry for my language too.
Here is the CODE with 2 Classes:
PaintPanel.class
public class PaintPanel extends JPanel implements ActionListener {
int x = 200, y = 250;
private JButton b1 = new JButton("BLUE");
private JButton b2 = new JButton("RED");
private JButton b3 = new JButton("GREEN");
JLabel label = new JLabel("Choose the right Color");
JPanel subPanel = new JPanel();
private Color[] colors;
public PaintPanel() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(440, 440));
add(label, BorderLayout.NORTH);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
subPanel.add(b1);
b1.setForeground(Color.BLUE);
subPanel.add(b2);
b2.setForeground(Color.RED);
subPanel.add(b3);
b3.setForeground(Color.GREEN);
add(subPanel, BorderLayout.SOUTH);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Color[] colors = new Color[3];
colors[0] = Color.BLUE;
colors[1] = Color.RED;
colors[2] = Color.GREEN;
Color c1 = colors[randInt(colors.length)];
g.setColor(c1);
/* this.colors.equals(c1); !!!! HERE I TRIED !!!*/
g.fillOval(x, y, 30, 30);
}
private int randInt(int length) {
// TODO Auto-generated method stub
Random rand = new Random();
int randomColor = rand.nextInt(length);
return randomColor;
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
if (Color.BLUE.equals(colors)) {
label.setText("You WIN");
}
}else {
label.setText("You LOSE");
}
if (e.getSource() == b2) {
}
if (e.getSource() == b3) {
}
}
}
Another one - DrawCircle.class -
public class DrawCircle extends JFrame {
private JPanel painted;
public DrawCircle() {
painted = new PaintPanel();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new FlowLayout());
setBounds(0, 0, 800, 540);
add(painted);
setVisible(true);
}
public static void main(String[] args) {
new DrawCircle();
}
}
Just a couple notes: You cannot access a non-static method from a static context. Consider Placing your DrawCircle() method in a separate class. Create an instance of that class and call DrawCircle() from that instance.
Regarding PaintPanel.class please note that paintComponent() is called very frequently, and is not just called on initialization. The Colors you generate need to be saved in a place accessible by actionPerformed(). Consider creating a Color tmp member in your class structure and reference your correct answer from there. In addition, you appear to be missing a call to UpdateUI(). This code is not perfect, but it works well. Personally, I'd find a different way to generate new colors apart from overriding paintComponent(), but if you need it there, this example should prove helpful. Comment below with improvements:
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class PaintPanel extends JPanel implements ActionListener
{
int x = 200, y = 250;
private JButton b1 = new JButton("BLUE");
private JButton b2 = new JButton("RED");
private JButton b3 = new JButton("GREEN");
JLabel label = new JLabel("Choose the right Color");
JPanel subPanel = new JPanel();
private Color[] colors;
Color tmp = null;
public PaintPanel()
{
setLayout(new BorderLayout());
setPreferredSize(new Dimension(440, 440));
add(label, BorderLayout.NORTH);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
subPanel.add(b1);
b1.setForeground(Color.BLUE);
subPanel.add(b2);
b2.setForeground(Color.RED);
subPanel.add(b3);
b3.setForeground(Color.GREEN);
add(subPanel, BorderLayout.SOUTH);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
colors = new Color[3]; //Referencing Class member colors instead of local variable
colors[0] = Color.BLUE;
colors[1] = Color.RED;
colors[2] = Color.GREEN;
tmp = colors[randInt(colors.length)]; //Read into a class member instead of a local variable
g.setColor(tmp);
System.out.println("Paint Triggered. New Color is: " + tmp.toString()); //todo remove this debugging line
g.fillOval(x, y, 30, 30);
}
private int randInt(int length)
{
// TODO Auto-generated method stub
Random rand = new Random();
int randomColor = rand.nextInt(length);
return randomColor;
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == b1) {
if (Color.BLUE.equals(tmp)) {
label.setText("You WIN");
} else {
label.setText("You Loose");
}
} else if (e.getSource() == b2) {
if (Color.RED.equals(tmp)) {
label.setText("You WIN");
} else {
label.setText("You Loose");
}
} else if (e.getSource() == b3) {
if (Color.GREEN.equals(tmp)) {
label.setText("You WIN");
} else {
label.setText("You Loose");
}
}
updateUI(); //<---------------IMPORTANT To Sync What you see with each button press.
}
}
I think you've simply messed up your braces (and your indentation). Please use an auto-indent or auto-format tool in an IDE, it will locate these problems quickly.
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
if (Color.BLUE.equals(colors)) {
label.setText("You WIN");
}
// v Problem is this extra brace
}else {
label.setText("You LOSE");
}
Change to
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b1) {
if (Color.BLUE.equals(colors)) {
label.setText("You WIN");
}
else {
label.setText("You LOSE");
}
} else if( //...
Your colors array should not be created in the paintComponent() method. It should be declared as a PaintPanel instance variable, and should be created in the PaintPanel constructor.
Here is a possibility (you do not need a separate class; I added a main to PaintPanel):
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class PaintPanel extends JPanel implements ActionListener {
int x = 200, y = 250;
private JButton b1 = new JButton("BLUE");
private JButton b2 = new JButton("RED");
private JButton b3 = new JButton("GREEN");
JLabel label = new JLabel("Choose the right Color");
JPanel subPanel = new JPanel();
private Color circleColor;
public PaintPanel() {
setLayout(new BorderLayout());
setPreferredSize(new Dimension(440, 440));
add(label, BorderLayout.NORTH);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
subPanel.add(b1);
b1.setForeground(Color.BLUE);
subPanel.add(b2);
b2.setForeground(Color.RED);
subPanel.add(b3);
b3.setForeground(Color.GREEN);
add(subPanel, BorderLayout.SOUTH);
Random rand = new Random();
int rc = rand.nextInt(3);
switch (rc) {
case 1:
circleColor = Color.RED;
break;
case 2:
circleColor = Color.GREEN;
break;
default:
circleColor = Color.BLUE;
break;
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(circleColor);
g.fillOval(x, y, 30, 30);
}
#Override
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
if (b.getForeground().equals(circleColor)) {
label.setText("You WIN");
} else {
label.setText("You LOSE");
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// create the main frame
JFrame frame = new JFrame();
// create the component to display in the frame
PaintPanel comp = new PaintPanel();
frame.add(comp, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent arg0) {
System.exit(0);
}
});
}
});
}
}

change the contents of a JFrame by clicking keys

How would I change the contents of a JFrame by dynamically clicking keys, in this example I want to change the contents through two JPanels I have created, when i click up I want to change to Panel2, and when I click down I want to change to Panel3, but I want the JFrames contents only to change (I want to stay in the same JFrame) there is no errors with the code, I am just a bit confused on how to solve this issue.
class Drawing extends JFrame implements KeyListener{
int num = 1;
public Drawing() {
Panel2 jPanel2 = new Panel2();
Panel3 jPanel3 = new Panel3();
if(num == 1){
add(jPanel2);
remove(jPanel3);
pack();
}
if(num == 2){
add(jPanel3);
remove(jPanel2);
pack();
}
// be nice to testers..
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
addKeyListener(this);
}
and then i have the keypressed method to change num to either 1 or 2 depending on what key is pressed (i also implemented keyReleased and keyTyped but I didn't include them to add space)
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == e.VK_UP){
num = 1;
}
if(e.getKeyCode() == e.VK_DOWN){
num = 2;
}
}
public static void main(String args[]) {
new Drawing();
}
and here is the two panels that change the graphics of the page
class Panel2 extends JPanel {
Panel2() {
setPreferredSize(new Dimension(500,500));
}
public void paint(Graphics g) {
g.drawString("BLAH", 20, 20);
g.drawRect(200, 200, 200, 200);
repaint();
}
}
class Panel3 extends JPanel {
Panel3() {
// set a preferred size for the custom panel.
setPreferredSize(new Dimension(500,500));
}
public void paint(Graphics g) {
g.drawString("BURP", 20, 20);
g.drawRect(200, 200, 200, 200);
repaint();
}
}
Firstly, in your use case, don't use keyTyped event because it is only triggered
when the unicode character represented by this key is sent by the
keyboard to system input
. There is no system input in your UI. Checkout this for more details: KeyListener, keyPressed versus keyTyped
Instead, use keyPressed or keyReleased event.
Secondly, you need explicitly invoke add(jPanel2);remove(jPanel3); when you are handling the event. Set num = 1 doesn't do anything.
Thirdly, you need to call jPanel2.repaint(); after add(jPanel2);remove(jPanel3); to make sure the panel paint the content you want.
Fourthly, always call super.paint(g); to initialize the painting canvas correctly!
So, to put them all together, you have:
public class Drawing extends JFrame implements KeyListener {
int num = 1;
Panel2 jPanel2 = new Panel2();
Panel3 jPanel3 = new Panel3();
public Drawing() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
addKeyListener(this);
setSize(300, 300);
}
#Override
public void keyTyped(KeyEvent e) {
}
private void changePanel() {
if (num == 1) {
remove(jPanel3);
add(jPanel2);
jPanel2.repaint();
pack();
}
if (num == 2) {
remove(jPanel2);
add(jPanel3);
jPanel3.repaint();
pack();
}
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == e.VK_UP) {
num = 1;
}
if (e.getKeyCode() == e.VK_DOWN) {
num = 2;
}
changePanel(); // do the actual swap of the panels
}
public static void main(String args[]) {
new Drawing();
}
}
class Panel2 extends JPanel {
Panel2() {
setPreferredSize(new Dimension(500, 500));
}
public void paint(Graphics g) {
super.paint(g); //always call!
g.drawString("BLAH", 20, 20);
g.drawRect(200, 200, 200, 200);
}
}
class Panel3 extends JPanel {
Panel3() {
setPreferredSize(new Dimension(500, 500));
}
public void paint(Graphics g) {
super.paint(g); //always call!
g.drawString("BURP", 20, 20);
g.drawOval(200, 200, 200, 200);
}
}

Java hangman. How to create multiple buttons and actionlisteners?

I am trying to create a hangman game with a button for each letter of the alphabet. I have done this the hard way, using absolute positioning and multiple actionlisteners. Is there any way I can do both with a for loop?
Also, how can I implement my hangman using a polymorphic array? The way I have it now, I will use an if statement for each of the limbs. I'd wrather create the man on his own panel, then set the visibility for each limg to true as the use fails at guessing.
Any help is appreciated.
public class HangmanGui extends JFrame{
private JLabel headerLabel;
private JPanel man;
private Graphics gobj;
private JButton aButton ;
private JButton bButton ;
private JButton cButton ;
private JButton dButton ;
private JButton eButton ;
private JButton fButton ;
private JButton gButton ;
private JButton hButton ;
private JButton iButton ;
private JButton jButton ;
private JButton kButton ;
private JButton lButton ;
private JButton mButton ;
private JButton nButton ;
private JButton oButton ;
private JButton pButton ;
private JButton qButton ;
private JButton rButton ;
private JButton sButton ;
private JButton tButton ;
private JButton uButton ;
private JButton vButton ;
private JButton wButton ;
private JButton xButton ;
private JButton yButton ;
private JButton zButton ;
private JButton newWButton ;
private JButton showWButton ;
private JButton quitButton ;
private JButton startButton ;
private JLabel blankWord;
private JLabel titleWord;
private JFrame frame;
private JPanel hangman;
private FlowLayout layout;
private Container container;
/*
public static void main (String[] args){
GUITest gui = new GUITest();
gui.setSize(800,900);
gui.setVisible(true);
}
*/
//
// public GUITest()
// {
// }
public HangmanGui(){
buildGui();
}
public void buildGui(){
frame = new JFrame();
frame.getContentPane().setBackground(Color.WHITE);
frame.setBackground(Color.WHITE);
frame.setBounds(100, 100, 450, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
Font lblFont= new Font("Serif", Font.BOLD, 30);
JLabel[] uscore = new JLabel[15];
Man man = new Man();
titleWord = new JLabel("A Game of Hangman.");
titleWord.setBounds(260,10,500,150);
titleWord.setFont(lblFont);
add(titleWord);
// add(blankWord);
//frame.add(man);
this.add(man);
man.setBounds(100,100,400,400);
JPanel panel = new JPanel();
panel.setBounds(6, 232, 400, 400);
frame.getContentPane().add(panel);
layout = new FlowLayout();
container = getContentPane();
setLayout(null);
aButton = new JButton("A");
add(aButton);
aButton.setBounds(30, 520, 50, 29);
aButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
bButton = new JButton("B");
add(bButton);
bButton.setBounds(80, 520, 50, 29);
bButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
cButton = new JButton("C");
add(cButton);
cButton.setBounds(130, 520, 50, 29);
cButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
dButton = new JButton("D");
add(dButton);
dButton.setBounds(180, 520, 50, 29);
dButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
eButton = new JButton("E");
add(eButton);
eButton.setBounds(230, 520, 50, 29);
eButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
fButton = new JButton("F");
add(fButton);
fButton.setBounds(280, 520, 50, 29);
fButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
gButton = new JButton("G");
add(gButton);
gButton.setBounds(330, 520, 50, 29);
gButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
hButton = new JButton("H");
add(hButton);
hButton.setBounds(380, 520, 50, 29);
hButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
iButton = new JButton("I");
add(iButton);
iButton.setBounds(430, 520, 50, 29);
iButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
jButton = new JButton("J");
add(jButton);
jButton.setBounds(480, 520, 50, 29);
jButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
kButton = new JButton("K");
add(kButton);
kButton.setBounds(530, 520, 50, 29);
kButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
lButton = new JButton("L");
add(lButton);
lButton.setBounds(580, 520, 50, 29);
lButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
mButton = new JButton("M");
add(mButton);
mButton.setBounds(630, 520, 50, 29);
mButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
nButton = new JButton("N");
add(nButton);
nButton.setBounds(680, 520, 50, 29);
nButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
oButton = new JButton("O");
add(oButton);
oButton.setBounds(30, 550, 50, 29);
oButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
pButton = new JButton("P");
add(pButton);
pButton.setBounds(80, 550, 50, 29);
pButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
qButton = new JButton("Q");
add(qButton);
qButton.setBounds(130, 550, 50, 29);
qButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
rButton = new JButton("R");
add(rButton);
rButton.setBounds(180, 550, 50, 29);
rButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
sButton = new JButton("S");
add(sButton);
sButton.setBounds(230, 550, 50, 29);
sButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
tButton = new JButton("T");
add(tButton);
tButton.setBounds(280, 550, 50, 29);
tButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
uButton = new JButton("U");
add(uButton);
uButton.setBounds(330, 550, 50, 29);
uButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
vButton = new JButton("V");
add(vButton);
vButton.setBounds(380, 550, 50, 29);
vButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
wButton = new JButton("W");
add(wButton);
wButton.setBounds(430, 550, 50, 29);
wButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
xButton = new JButton("X");
add(xButton);
xButton.setBounds(480, 550, 50, 29);
xButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
yButton = new JButton("Y");
add(yButton);
yButton.setBounds(530, 550, 50, 29);
yButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
zButton = new JButton("Z");
add(zButton);
zButton.setBounds(580, 550, 50, 29);
zButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
startButton = new JButton("Start Game");
add(startButton);
startButton.setBounds(100, 700, 120, 29);
startButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
newWButton = new JButton("New Word");
add(newWButton);
newWButton.setBounds(250, 700, 120, 29);
newWButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
showWButton = new JButton("Show Word");
add(showWButton);
showWButton.setBounds(400, 700, 120, 29);
showWButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
quitButton = new JButton("Quit Game");
add(quitButton);
quitButton.setBounds(550, 700, 120, 29);
quitButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
}
}
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JPanel;
public class Man extends JPanel {
protected void paintComponent(Graphics g ){
super.paintComponent(g);
//gallows
g.fillRect(10, 250, 150, 20);
g.fillRect(40,70,10,200);
g.fillRect(40,70,60,10);
g.setColor(Color.yellow);
g.fillRect(95,70,5,25);
//head
g.setColor(Color.black);
g.drawOval(82,95,30,30);
//body
g.drawLine(97,125,97,150);
//left leg
g.drawLine(97,150,117,183);
//right leg
g.drawLine(97,150,77,183);
// right arm
g.drawLine(97,125,117,135);
//left arm
g.drawLine(97,125,77,135);
}
}
Use a layout manager to manage the sizing of your buttons, don't use setBounds(). You currently create one but don't set it and so its not used.
layout = new FlowLayout();
setLayout(null); // Why set null and not layout
Set the layout correctly and then you could can use a char in your for loop like
for(char c = 'A'; c <= 'Z'; c++)
{
JButton button = new JButton("" + c);
// add action listener also
add(button); // adding will add it using the layout manager
}
You can learn more about layout managers here.
You could try something like this:
// create a JPanel to hold the buttons that uses a GridLayout with 3 rows
JPanel buttonPanel = new JPanel(new GridLayout(3, ));
for (int i = 0; i < 26; ++i)
{
wButton = new JButton('A' + i);
buttonPanel.add(wButton);
// wButton.setBounds(30 + i * 50, 550, 50, 29); // avoid this
wButton.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
}
}
);
}
// here add the buttonPanel to the main GUI
To break this down:
1) We use a for loop to go thru the 26 letters of the alphabet.
2) We create a button with the title being the letter. Because characters are actually just integers, adding 1 to 'A' yields 'B'. So, we can use 'A'+i as a little trick. Also, you could use an array of all the letters instead and do something like letter[i] there.
3) Avoid use of setBounds but rather use the layout managers to more easily and simply place and size the buttons.
Disclaimer: I haven't actually tested this, it's just something to get you on the right track.
Suggestions:
Yes, use an array or a collection such as either a simple array of JButton or a List<JButton> or its concrete implementation, an ArrayList<JButton>
Yes, create your letter JButtons in a for loop as many have suggested.
But don't create your special buttons there, buttons such as your reset button or your exit button.
Create one AbstractAction or ActionListener class for all the letter buttons to share and a unique AbstractAction or ActionListener class for each special JButton
Use layout managers, but not just one -- nest them. For instance, the overall GUI can use a BorderLayout with the drawing held BorderLayout.CENTER and the buttons in the SOUTH or PAGE_END position, the JPanels that hold your buttons could be held in a BoxLayout using JPanel, the letter buttons in a GridLayout using JPanel and the same for the specialty buttons.
Use a separate JPanel for drawing the hangman image. Keep its logic separate from everything else. All it cares about is the number of wrong letters guessed, and then it should draw the appropriate images depending on this value. So I'd give it a public method for incrementing this number as well as a public method for resetting the number and its drawing.
For instance
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class LayoutFoo extends JPanel {
// using a List of JButtons to hold my collection
private List<JButton> letterButtons = new ArrayList<>();
private DrawingPanel drawingPanel = new DrawingPanel();
public LayoutFoo() {
JPanel letterButtonPanel = new JPanel(new GridLayout(3, 0, 3, 3));
letterButtonPanel.setBorder(BorderFactory.createTitledBorder("Letters"));
ButtonListener buttonListener = new ButtonListener();
for (char c = 'A'; c <= 'Z'; c++) {
String text = String.valueOf(c);
JButton button = new JButton(text);
button.addActionListener(buttonListener);
letterButtons.add(button); // add JButton to List<JButton>
letterButtonPanel.add(button); // and add to GridLayout-using JPanel
}
// JPanel to hold non-letter JButtons
JPanel specialBtnsPanel = new JPanel(new GridLayout(1, 0, 3, 3));
specialBtnsPanel.add(new JButton(new ResetAction("Reset", KeyEvent.VK_R)));
specialBtnsPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
// JPanel to hold non-drawing JPanels. It uses BoxLayout
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.PAGE_AXIS));
bottomPanel.add(letterButtonPanel);
bottomPanel.add(specialBtnsPanel);
// set layout and border of main JPanel and add other JPanels to it
setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
setLayout(new BorderLayout(3, 3));
add(drawingPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private class ButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button pressed: " + e.getActionCommand());
((AbstractButton) e.getSource()).setEnabled(false);
}
}
private class ResetAction extends AbstractAction {
public ResetAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
for (JButton button : letterButtons) {
button.setEnabled(true);
}
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component component = (Component) e.getSource();
Window win = SwingUtilities.getWindowAncestor(component);
win.dispose();
}
}
private static void createAndShowGui() {
LayoutFoo mainPanel = new LayoutFoo();
JFrame frame = new JFrame("LayoutFoo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class DrawingPanel extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private int wrongLetterCount = 0;
public DrawingPanel() {
setBorder(BorderFactory.createTitledBorder("Hang Man"));
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// TODO: draw hangman here based on wrong letter count!
}
public void incrementWrongLetterCount() {
wrongLetterCount++;
repaint();
}
public void reset() {
wrongLetterCount = 0;
repaint();
}
}

How to give JButtons different functionality?

How would give different JButtons using the same ActionPerformed function different functionality?
public class ToolBarExample extends JPanel implements ActionListener {
public JTextPane pane;
public JMenuBar menuBar;
public JToolBar toolBar;
public JButton Aster;
public JButton Azaleas;
public JButton ChristFern;
public JButton JapBarberry;
public ToolBarExample() {
toolBar = new JToolBar("Formatting", JToolBar.VERTICAL);
this.Aster = new JButton(new ImageIcon("images/PlantIcons/[Blueprint]_Aster.png"));
this.toolBar.add(Aster);
this.Aster.addActionListener(this);
this.Azaleas = new JButton(new ImageIcon("images/PlantIcons/[Blueprint]_Azaleas.png"));
this.toolBar.add(Azaleas);
this.Azaleas.addActionListener(this);
this.ChristFern = new JButton(new ImageIcon("images/PlantIcons/[Blueprint]_ChristmasFern.png"));
this.toolBar.add(ChristFern);
this.ChristFern.addActionListener(this);
this.JapBarberry = new JButton(new ImageIcon("images/PlantIcons/[Blueprint]_JapaneseBarberry.png"));
this.toolBar.add(JapBarberry);
this.JapBarberry.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
try {
if(e.getSource() == Aster) {
NativePlant plant1 = new NativePlant(4, 5, 600, "test", "images/[Blueprint]_Aster.png", 200, 600);
Game.setNatives(plant1);
}
if(e.getSource() == Azaleas) {
NativePlant plant1 = new NativePlant(4, 5, 600, "test", "images/[Blueprint]_Azaleas.png", 100, 600);
Game.setNatives(plant1);
}
if(e.getSource() == ChristFern) {
NativePlant plant1 = new NativePlant(4, 5, 600, "test", "images/[Blueprint]_ChristmasFern.png", 300, 600);
Game.setNatives(plant1);
}
if(e.getSource() == JapBarberry) {
NativePlant plant1 = new NativePlant(4, 5, 600, "test", "images/[Blueprint]_JapaneseBarberry.png", 400, 600);
Game.setNatives(plant1);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Right now I am trying to use the e.getSource to find out what button is being pushed,
and then execute something different for each button.
However, right now the only button that is working is the first one (Aster).
Does anyone know what I am doing wrong, or what I should be doing?
You can use the setActionCommand() of each button and call the respective getActionCommand from the actionPerformed. Using constants to define the actions would be a good approach in my opinion. A small sample as follows;
public class SwingTest extends JFrame implements ActionListener{
public SwingTest()
{
JButton btnOne = new JButton("test one");
btnOne.addActionListener(this);
btnOne.setActionCommand("TestOne");
JButton btnTwo = new JButton("test two");
btnTwo.addActionListener(this);
btnTwo.setActionCommand("TestTwo");
this.setLayout(new FlowLayout());
this.getContentPane().add(btnOne);
this.getContentPane().add(btnTwo);
}
public static void main(String[] args) {
SwingTest t = new SwingTest();
t.pack();
t.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
}
}
instead of having it be
e.getSource() == Aster
change it to:
e.getSource().equals(Aster)
it looks like the same thing, but it will give you the results your looking for...
because .equals() is checking for the state of an object, where as '==' is checking the actually instances.
http://www.javabeat.net/qna/13-what-is-difference-between-equals-and-/

JButton will work but won't display my icon when it is clicked on

I have a buttonlistener that removes the TextFields and the StartButton when it is clicked, but the last part of the code that tells it to run a method that is supposed to display the icon is screwing up only at the end, but is still deleting the TextFields and the JButton. Please help.
public class TypeInNames extends JApplet{
JButton StartButton;
JTextField name1, name2;
String player1, player2;
String reply;
boolean test = false;
ImageIcon myIcon;
Container cp = getContentPane();
public void init()
{
setSize(350, 400);
setLayout(null);
cp.setBackground(Color.black);
StartButton = new JButton("Start Game!");
name1 = new JTextField("Player 1",35);
name2 = new JTextField("Player 2",35);
//(x, y, width, height);
StartButton.setBounds(115,200,120,30);
name1.setBounds(115,140,120,20);
name2.setBounds(115,170,120,20);
startGame();
}
public void startGame()
{
add(StartButton);
add(name1);
add(name2);
StartButton.addActionListener(new ButtonListener());
}
public void game()
{
}
public void endGame()
{
myIcon = new ImageIcon("portal-cake.jpg");
test = true;
repaint();
}
public void paintComponent(Graphics g) {
super.paint(g);
if(test)
myIcon.paintIcon(this, g, 0, 0);
}
private class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == StartButton)
{
player1 = name1.getText();
player2 = name2.getText();
remove(StartButton);
remove(name1);
remove(name2);
endGame();
}
}
}
}
You don't have to override paintComponent() at all. Just use a JLabel and set the layout.
public void endGame() {
myIcon = new ImageIcon("portal-cake.jpg");
JLabel label = new JLabel(myIcon);
this.setLayout(new GridLayout());
this.add(label);
this.validate();
}
Addendum: Here's an alternate approach to collecting startup information.
import java.awt.*;
import javax.swing.*;
public class TypeInNames extends JApplet {
JTextField name1 = new JTextField("Player 1", 35);
JTextField name2 = new JTextField("Player 2", 35);
#Override
public void init() {
this.getContentPane().setBackground(Color.black);
Icon myIcon = new ImageIcon("portal-cake.jpg");
JLabel label = new JLabel(myIcon);
this.add(label);
startGame();
}
private void startGame() {
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(new JLabel("Player 1:"));
panel.add(name1);
panel.add(new JLabel("Player 2:"));
panel.add(name2);
int result = JOptionPane.showConfirmDialog(
this, panel, "Click OK to Start",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
System.out.println("Selected:"
+ " " + name1.getText()
+ " " + name2.getText());
} else {
System.out.println("Cancelled");
}
}
}
Are you sure you meant to override paintComponenet and not paint? Considering you're calling super.paint(g), I'd look there first.

Categories

Resources