64173

How to add a new JFrame with buttons?

Question:

Whenever I create a new JFrame screen the game won't run on my computer for some reason and I don't know why. I have tried fixing this issue but I think it has something to do with the buttons or the placement of the screen. The startStage is what I need help on. If I'm missing something can you please tell me.

import java.awt.CardLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.HashSet; import java.util.Set; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; /** * This class demonstrates basic animation using a timer, an action listener, * and a key listener * * * */ public class GameWindow extends JPanel implements ActionListener, KeyListener { private static final long serialVersionUID = 1L; JLabel player = new JLabel(); int playerSpeed = 1; int FPS = 30; // The keys set holds the keys being pressed private final Set<Integer> keys = new HashSet<>(); public static void main(String[] args) { // Open the GUI window SwingUtilities.invokeLater(new Runnable() { @Override public void run() { // Create a new object and // run its go() method new GameWindow().go(); } }); } public GameWindow() { // Run the parent class constructor super(); // Allow the panel to get focus setFocusable(true); // Don't let keys change the focus setFocusTraversalKeysEnabled(false); //Make a new screen with a button and put it in the window JPanel startStage = new JPanel(); // Create a new JPanel and add it to the card layout startStage.setSize(getWidth(), getHeight()); // make the new JPanel fit the window startStage.setBackground(Color.BLUE); // set the JPanel background to blue startStage.setVisible(true); // show the JPanel JButton playButton = new JButton("Play"); // Add a button to the panel playButton.addMouseListener(new MouseAdapter() { // Set the button to switch to the game stage @Override public void mouseClicked(MouseEvent arg0) { ((CardLayout) getContentPane().getLayout()).show( getContentPane(), "game"); } }); startStage.add(playButton); // add the button to the stage add(startStage, "start"); // add the stage to the window } protected void go() { // Setup the window JFrame jf = new JFrame(); // Add this panel to the window jf.setContentPane(this); // Set the window properties jf.setTitle("Animation Demo"); jf.setSize(300, 200); jf.setLocationRelativeTo(null); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); // Setup the movable box player.setBounds(10, 10, 10, 10); player.setVisible(true); player.setBackground(Color.BLUE); // Opaque makes the background visible player.setOpaque(true); // Setup the key listener addKeyListener(this); // Null layout allows moving objects!!! setLayout(null); add(player); // Set the timer Timer tm = new Timer(1000 / FPS, this); tm.start(); } @Override public void actionPerformed(ActionEvent arg0) { // Move up if W is pressed if (keys.contains(KeyEvent.VK_W)) { player.setLocation(player.getX(), player.getY() - playerSpeed); } // Move right if D is pressed if (keys.contains(KeyEvent.VK_D)) { player.setLocation(player.getX() + playerSpeed, player.getY()); } // Move down if S is pressed if (keys.contains(KeyEvent.VK_S)) { player.setLocation(player.getX(), player.getY() + playerSpeed); } // Move left if A is pressed if (keys.contains(KeyEvent.VK_A)) { player.setLocation(player.getX() - playerSpeed, player.getY()); } } @Override public void keyPressed(KeyEvent e) { // Add the key to the list // of pressed keys if (!keys.contains(e.getKeyCode())) { keys.add(e.getKeyCode()); } } @Override public void keyReleased(KeyEvent e) { // Remove the key from the // list of pressed keys keys.remove((Integer) e.getKeyCode()); } @Override public void keyTyped(KeyEvent e) { } }

Answer1:

You seem to have issues with how container management works. Stop, take a step back for a second and re-think your approach.

You basically have a "menu" and a "game" panel. This should be two separate panels/class.

These should then be added to a "hub" panel, which manages when and how they are displayed.

MainPane

This is the "main", "hub" panel. It is responsible for displaying both the menu and the game panels. It's also responsible for deciding "how" this happens, in this example, I've simply used a CardLayout

public class MainPane extends JPanel { public MainPane() { setLayout(new CardLayout()); MenuPane menu = new MenuPane(); menu.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (getLayout() instanceof CardLayout) { CardLayout layout = (CardLayout) getLayout(); layout.show(MainPane.this, "game"); } } }); GamePane game = new GamePane(); add(menu, "menu"); add(game, "game"); ((CardLayout) getLayout()).show(this, "menu"); } }

MenuPane

The "menu" is pretty simple. It simply displays the available options and provides a means for interested parties to be notified when an option is selected

public class MenuPane extends JPanel { private JButton btn; public MenuPane() { setLayout(new GridBagLayout()); setBackground(Color.BLUE); btn = new JButton("Start"); add(btn); } public void addActionListener(ActionListener listener) { btn.addActionListener(listener); } public void removeActionListener(ActionListener listener) { btn.removeActionListener(listener); } }

I'm not going into a lot about this, but you should have a look at <a href="https://docs.oracle.com/javase/tutorial/uiswing/components/button.html" rel="nofollow">How to Use Buttons, Check Boxes, and Radio Buttons</a> and <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html" rel="nofollow">How to Write an Action Listener</a> for more details

<h2>Disclaimer...</h2>

I'm been lazy, attaching the ActionListeners directly to the buttons. Instead, you should manage the button listeners and the panel's listeners separately, this will prevent exposing the buttons and allow you better control over what to generate when a specific operation is executed.

GamePane

And finally, the "game" panel. As I've been saying for the last day, you should make use a <a href="https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html" rel="nofollow">custom painting route</a> and <a href="https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html" rel="nofollow">How to Use Key Bindings</a>. Together, they will solve a swagger of other issues we'd generally like not to have to be asked about, again

public interface Movable { public void changeLocation(int xDelta, int yDelta); } public class GamePane extends JPanel implements Movable { private Rectangle player; public GamePane() { String text = "X"; FontMetrics fm = getFontMetrics(getFont()); int width = fm.stringWidth(text); int height = fm.getHeight(); player = new Rectangle(0, 0, width, height); setupKeyBindings(); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } protected void setupKeyBindings() { InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); ActionMap am = getActionMap(); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right"); int xDelta = player.width; int yDelta = player.height; am.put("up", new MoveAction(this, 0, -yDelta)); am.put("down", new MoveAction(this, 0, yDelta)); am.put("left", new MoveAction(this, -xDelta, 0)); am.put("right", new MoveAction(this, xDelta, 0)); } @Override public void changeLocation(int xDelta, int yDelta) { int xPos = player.x + xDelta; int yPos = player.y + yDelta; if (xPos + player.width > getWidth()) { xPos = getWidth() - player.width; } else if (xPos < 0) { xPos = 0; } if (yPos + player.height > getHeight()) { yPos = getHeight() - player.height; } else if (xPos < 0) { yPos = 0; } player.setLocation(xPos, yPos); repaint(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(Color.RED); g2d.draw(player); FontMetrics fm = g2d.getFontMetrics(); g2d.drawString("X", player.x, player.y + fm.getAscent()); g2d.dispose(); } } public class MoveAction extends AbstractAction { private Movable movable; private int xDelta; private int yDelta; public MoveAction(Movable movable, int xDelta, int yDelta) { this.movable = movable; this.xDelta = xDelta; this.yDelta = yDelta; } @Override public void actionPerformed(ActionEvent e) { movable.changeLocation(xDelta, yDelta); } }

Runnable Example...

Putting it all together...

import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class Game { public static void main(String[] args) { new Game(); } public Game() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new MainPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class MainPane extends JPanel { public MainPane() { setLayout(new CardLayout()); MenuPane menu = new MenuPane(); menu.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (getLayout() instanceof CardLayout) { CardLayout layout = (CardLayout) getLayout(); layout.show(MainPane.this, "game"); } } }); GamePane game = new GamePane(); add(menu, "menu"); add(game, "game"); ((CardLayout) getLayout()).show(this, "menu"); } } public class MenuPane extends JPanel { private JButton btn; public MenuPane() { setLayout(new GridBagLayout()); setBackground(Color.BLUE); btn = new JButton("Start"); add(btn); } public void addActionListener(ActionListener listener) { btn.addActionListener(listener); } public void removeActionListener(ActionListener listener) { btn.removeActionListener(listener); } } public interface Movable { public void changeLocation(int xDelta, int yDelta); } public class GamePane extends JPanel implements Movable { private Rectangle player; public GamePane() { String text = "X"; FontMetrics fm = getFontMetrics(getFont()); int width = fm.stringWidth(text); int height = fm.getHeight(); player = new Rectangle(0, 0, width, height); setupKeyBindings(); } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } protected void setupKeyBindings() { InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); ActionMap am = getActionMap(); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right"); int xDelta = player.width; int yDelta = player.height; am.put("up", new MoveAction(this, 0, -yDelta)); am.put("down", new MoveAction(this, 0, yDelta)); am.put("left", new MoveAction(this, -xDelta, 0)); am.put("right", new MoveAction(this, xDelta, 0)); } @Override public void changeLocation(int xDelta, int yDelta) { int xPos = player.x + xDelta; int yPos = player.y + yDelta; if (xPos + player.width > getWidth()) { xPos = getWidth() - player.width; } else if (xPos < 0) { xPos = 0; } if (yPos + player.height > getHeight()) { yPos = getHeight() - player.height; } else if (xPos < 0) { yPos = 0; } player.setLocation(xPos, yPos); repaint(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setColor(Color.RED); g2d.draw(player); FontMetrics fm = g2d.getFontMetrics(); g2d.drawString("X", player.x, player.y + fm.getAscent()); g2d.dispose(); } } public class MoveAction extends AbstractAction { private Movable movable; private int xDelta; private int yDelta; public MoveAction(Movable movable, int xDelta, int yDelta) { this.movable = movable; this.xDelta = xDelta; this.yDelta = yDelta; } @Override public void actionPerformed(ActionEvent e) { movable.changeLocation(xDelta, yDelta); } } }

Remember, one of your goals should be about "separation of responsibility", creating classes/components which do there job and do it well. This way you can use them as building blocks to devise much more complex solutions

Recommend

  • Using UDP versus TCP for Wi-Fi comm - battery drain?
  • IE Print font size smaller
  • How to use actionbarsherlock for Google maps menu?
  • serializeData vs. templateHelpers?
  • More MLE troubles
  • Using Paxos to synchronize a large file across nodes
  • Compare 2 files and keep entries that are not common to both
  • Customize legend in ggplot
  • Navigation Buttons no whitespace underneathe
  • Legend label errors with glmnet plot in R
  • SceneKit: how to control size of imported assets, one DAE file creates SCNNode of huge size while an
  • How to fit image in full screen in ImageViewTouch
  • TimePickerDialog widget in landscape mode (PreferenceScreen)
  • R script - least squares solution to the following [duplicate]
  • Height of tableView's header
  • How to move move a rectangle in JFrame using KeyListener?
  • GUI not updating despite use of validate()
  • got OSError when use pillow to deal with my jpg image
  • Displaying and sizing a grayscale from a QImage in Qt
  • Java pong can't move both paddles at once
  • When i use auto bi = 123456789, in C++, is it always assigned as an int?
  • How to use a decaying learning rate with an estimator in tensorflow?
  • adding item to window Extjs 4
  • Why are my web pages zoomed in when I open them in Opera Mobile?
  • How to resize image if the image is bigger than Textbox.But it not increase scale if smaller
  • What is sun.awt.windows.WToolkit?
  • JTextArea setText(veryLongString) is taking too much time
  • How to merge keras sequential models with same input?
  • Prevent page break in text block with iText, XMLWorker
  • Can I read an iPhone beacon with Windows.Devices.Bluetooth.Advertisement.BluetoothLEManufacturerData
  • How can I speed up CURL tasks?
  • Google Custom Search with transparent background
  • Android fill_parent issue
  • Repeat a vertical line on every page in Report Builder / SSRS
  • javascript inside java/jsp code
  • Sending data from AppleScript to FileMaker records
  • How to apply VCL Styles to DLL-based forms in Inno Setup?
  • KeystoneJS: Relationships in Admin UI not updating
  • AngularJs get employee from factory
  • Load html files in TinyMce