How do I add multiple buttons to JFrame? - java

I need something really basic.
I tried this:
import java.*;
import javax.swing.*;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class thisthing
{
public static void main(String[]args)
{
boolean done = false;
while (!done)
{
JFrame frame = new JFrame();
JButton button= new JButton("Add Interest");
frame.add(button);
JButton button1 = new JButton("Other Button");
frame.add(button1);
class AddInterestListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("hello, I was pressed");
}
}
class OtherButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("The Other button was pressed");
}
}
ActionListener listener = new AddInterestListener();
button.addActionListener(listener);
ActionListener listener1 = new OtherButtonListener();
button1.addActionListener(listener1);
frame.setSize(100, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
}
But then my computer had trouble making two buttons on one window when I ran it, so it tried to make two windows. I really don't know how to describe it except to say that it was a mess and I did something wrong.
In the end I need to add 15 buttons in a triangle shape (the famous AP peg game project)..so is there any way I can also re-position the buttons and mess with their sizes?

You could either (recommended) use another layoutmanager (or define one on your own). Or (really NOT recommended and extremely ugly solution, but it works):
frame.setLayout(null);
JButton button = new JButton("Hello world");
button.setBounds(20 , 20 , 100 , 30);
frame.add(button);
this will position the button at the given location and with the given size. Alternatively you could use
button.setSize(100 , 30);
button.setLocation(20 , 20);
Note: without a layoutmanager, you can position your components freely, but they will by default have the bounds (0 , 0 , 0 , 0), so you will always have to set the position and size to get anything visible. I only provide this solution because you asked for it, you shouldn't use it though.

Related

Let the user place Buttons in Java

I want to code a little tool that simulates a deterministic, finite automaton (like JFLAP) for myself.
My JFrame is just blank. How can I let the user place buttons on left click? And how do I assign the right values to that button (like which function to call when pressed).
I know I can place a button with
JButton button = new JButton("Press me");
frame.add(button);
But I don't know how I could dynamically code that.
Any help is welcome. Also if you think it's stupid to solve my problem with buttons, I'd like to hear suggestions for improvement.
The following code will add a JButton to a "blank" JFrame every time the mouse is clicked inside the JFrame. The JButton will be placed where the mouse click occurred. The JButton text will be a number. Each JButton will display a different number.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class AdButton extends MouseAdapter implements Runnable {
private int counter;
private JFrame frame;
private JPanel contentPane;
public void mouseClicked(MouseEvent event) {
int x = event.getX();
int y = event.getY();
JButton button = new JButton(String.valueOf(++counter));
Dimension dim = button.getPreferredSize();
button.setBounds(x, y, dim.width, dim.height);
contentPane.add(button);
contentPane.revalidate();
contentPane.repaint();
}
#Override
public void run() {
showGui();
}
private void showGui() {
frame = new JFrame();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
contentPane = (JPanel) frame.getContentPane();
contentPane.setLayout(null);
contentPane.addMouseListener(this);
frame.setSize(400, 450);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new AdButton());
}
}

I can't move my JLabel with Key Binding?

I am trying to make a game in Java where pressing spacebar moves the box in the window. I am using Key Binding to accomplish this task. The problem is that I can't figure out how to use an ActionListener on the box itself, which is a JLabel. Here is the code below:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Game {
private static JFrame frame = new JFrame();
private static JPanel gamePanel = new JPanel();
private static Action playerAction = new PlayerListener();
private static JLabel box = new JLabel();
private static int x = 250;
private static int y = 250;
public static void main(String[] args) {
frame.add(boxPanel());
frame.setTitle("Block Game");
frame.setSize(500,500);
frame.setLocationRelativeTo(null);
frame.setFocusable(true);
box.addActionListener(playerAction);
frame.setVisible(true);
}
static JPanel boxPanel() {
ImageIcon boxIcon = new ImageIcon("box.png");
box.setIcon(boxIcon);
box.setSize(30,30);
box.setLocation(x,y);
box.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "doPlayerAction");
box.getActionMap().put("doPlayerAction", playerAction);
gamePanel.setLayout(null);
gamePanel.add(box);
frame.add(gamePanel);
return gamePanel;
}
static class PlayerListener extends AbstractAction {
public void actionPerformed(ActionEvent e) {
System.out.println("SPACEBAR");
}
}
}
I tried changing the box to a JButton and working with that instead, but I have found that "SPACEBAR" only prints out when I click on the box itself. Any help is greatly appreciated. Thanks!
Your "core" problem revolves around box.getInputMap(), change it to something more like box.getInputMap(WHEN_IN_FOCUSED_WINDOW) which will mean that the API will respond to key events whenever the window has focus, regardless what other components might have focus.
I'd also suggestsomething more like box.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "doPlayerAction"), as the mechanism which KeyStroke uses to parse String to a KeyStroke is more complicated then it might seem, normally requiring additional information like pressed, released or typed, it's just easier to use the virtual keys
I would also bind the keys to the gamePanel as a general preference, as it should be the container making decisions about what to do, but that's just me.
Have a look at How to Use Key Bindings for more details

JAVA JButton in a different class refuses to activate when pressed

I'm failing to understand why my yankee and whiskey JButtons aren't working. Right now I only want them to close the program when romeo is greater than 1 and sierra is greater than 1.
import java.awt.*;
import java.lang.*;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.*;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import java.util.Scanner;
public class AlphaMenu extends JFrame /*implements actionPerformed*/
{
private GraphicsDevice gamma;
public JButton charlie, zulu, yankee, xray;
public JFrame beta;
public JPanel delta, echo, foxtrot, golf, hotel;
public JTextArea whiskey, victor;
public BorderLayout uniform;
public ImageIcon bg;
public JLabel tango;
public int sierra, romeo;
public Integer quebec, papa;
public ActionEvent oscar;
public ActionEvent november;
public AlphaMenu()
{
//Initialization of Objects
charlie = new JButton("EXIT");
zulu = new JButton("Enter Time");
yankee = new JButton("Enter Amount of Money");
xray = new JButton("Calculate");
sierra = 0;
romeo = 0;
quebec = new Integer(0);
papa = new Integer(0);
whiskey = new JTextArea(2, 15);
victor = new JTextArea(2, 15);
bg = new ImageIcon("background.gif");
beta = new JFrame();
delta = new JPanel();
echo = new JPanel();
foxtrot = new JPanel();
golf = new JPanel();
hotel = new JPanel();
uniform = new BorderLayout();
ImageIcon bg = new ImageIcon("background.gif");
tango = new JLabel("");
tango.setIcon(bg);
//Modification of panels
beta.add(delta, uniform.PAGE_END);
beta.add(golf, uniform.PAGE_START);
beta.add(echo, uniform.LINE_START);
beta.add(foxtrot, uniform.LINE_END);
beta.add(hotel, uniform.CENTER);
golf.add(tango);
//Modification of JButton charlie & adding of JButtons
charlie.setPreferredSize(new Dimension(100, 50));
delta.add(charlie);
charlie.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
echo.add(whiskey);
echo.add(yankee);
foxtrot.add(victor);
foxtrot.add(zulu);
//Modification of JFrame beta
beta.setUndecorated(true);
beta.setExtendedState(JFrame.MAXIMIZED_BOTH);
beta.setResizable(false);
beta.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
beta.setVisible(true);
}
public void buttonSetup() throws NumberFormatException
{
//Modification of JButton yankee & JTextArea whiskey & int sierra
romeo = quebec.parseInt(whiskey.getText());
yankee.setPreferredSize(new Dimension(300, 50));
yankee.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent oscar)
{
System.exit(0);
}
});
//Modification of JButton zulu & JTextArea victor & int romeo
sierra = papa.parseInt(victor.getText());
zulu.setPreferredSize(new Dimension(300, 50));
zulu.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent november)
{
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent e)
{
}
public static void main(String[] args)
{
new AlphaMenu();
}
}
So, you have two JTextArea (JTextField would probably be better) and a button. you want some buttons to execute exit when the text of both textareas is an integer greater than 1.
seems that your buttonSetup() function isn't called anywhere.
Anyway, I'd create an ActionListener that reads the texts, converts to integer, tests your condition and executes exit(). This ActionListener should be added to all the buttons you want to perform the action
final ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
final int intRomeo = Integer.parseInt(romeo.getText());
final int intSierra = Integer.parseInt(sierra .getText());
if (intRomeo > 1 && intSierra > 1) {
// whatever you want to do
System.exit(0);
}
} catch (/*NumberFormat*/ Exception e) {
// ...not integers
}
};
}
whiskey.addActionListener(al);
yankee.addActionListener(al);
I have to add: the variable names you are using are really bad. Consider choosing something more significative.
For starters, readability...it would probably help the "sloppiness" if you used more appropriate names for your variables, indented different sections of code, and used comments to help describe sections in layman's terms. Maybe "btnExit" and "btnCalculate" would help make things a little easier to navigate.
Moving forward, you also don't have two different classes here, you have one class with several methods. Which is fine but wanted to inform you of that. I think maybe you need to add the buttons to their panels after your action listeners and formatting for each button. I'm just getting into some swing stuff myself and I've noticed moving the .add() functions around in the code has helped when I run into issues like this. Try the following bellow. I indented and used new naming conventions for the comments, but the code uses your convention.
//add the pnlEcho to frmBeta
beta.add(echo, uniform.LINE_START);
//format btnYankee
yankee.setPreferredSize(new Dimension(300, 50));
//btnYankee action listener
yankee.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { //default action event
System.exit(0); //you could use this
beta.dispose(); //or you could dispose the frame and
//do more work after it is gone
}
});
//add btnYankee to pnlEcho
echo.add(yankee);
I'm failing to understand why my yankee and whiskey JButtons aren't
working
The variable wiskey is not JButton type but JTextArea type.

Get KeyPressed when using JCanvas

I am creating a simple Java application using JCanvas, I need to get the key code of a key pressed by the user: The following is a simplified version of the Java Code
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.EventObject;
import java.awt.event.*;
// myJavaFiles project contains JCanvas & JEventQueue Classes
import myJavaFiles.*;
import javax.swing.*;
public static void main(String[] args) {
JCanvas canvas = new JCanvas();
JEventQueue events = new JEventQueue();
events.listenTo(canvas, "canvas");
JFrame frame = new JFrame();
frame.setSize(700, 700);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.add(canvas);
while (true) {
if (events.hasEvent()){
EventObject event = events.waitEvent();
if(JEventQueue.isKeyPressed(event)){
int keycode = events.getKeyCode(event);
// USE KEYCODE!!!
}
}
canvas.sleep(10);
canvas.clear();
}
}
Everything works, (I omitted a lot of the non relevant code), except for getting the key pressed, I did notice that events.hasEvent doesn't even seem to be true when I press a key!
Please help! What am I doing wrong?
It's a bit difficult without the code for JCanvas and JEventQueue, but normally I would use a key listener for a panel that contains the canvas:
//frame.add(canvas);
final JPanel panel = new JPanel();
panel.add(canvas);
frame.getContentPane().add(panel);
panel.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(final KeyEvent keyEvent) {
System.out.println("keyEvent.getKeyCode(): " + keyEvent.getKeyCode());
}
});

Java JDialog messes up JMenuBar on mac

I am having some problems regarding to the JMenuBar and I cant seem to figure it out.
I will start with an abriviation of the problem: The program consists of a JFrame, a JDialog and a JMenuBar. Initially, you will get to see a JFrame with the JMenuBar in the top. But at some point, the JDialog will pop up where a user can fill in some text fields. The problem that I'm having is that as soon as the focus goes to the JDialog, the JMenuBar disappears. What I want is that the JMenuBar stays in the top of the screen all the time, except if the whole program is NOT in focus. Here are 2 screenshots, in the first screen shot, the JFrame is selected and in the other one the JDialog is selected.
So what i actually want is instead of only seeing the JMenuBar when the focus is on the JFrame, i want to see the JMenuBar all the time. Since a JDialogs can not have the JMenuBar in the top, like a JFrame has, i decided not to have multiple JMenuBars, but just the one that should be visible all the time.
At last i will give a part of the code that is as small as possible (and still working) and also contains the problem:
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
/**
* #author Guus Leijsten
* #created Oct 27, 2012
*/
public class MenuBarProblem extends JFrame {
public MenuBarProblem() {
super("Frame");
this.setMinimumSize(new Dimension(270, 200));
this.setPreferredSize(new Dimension(800, 530));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JRootPane root = this.getRootPane();
//Menu
JMenu fileMenu = new JMenu("File");
JMenuItem file_exit = new JMenuItem("Exit");
file_exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_W, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
file_exit.setToolTipText("Exit application");
file_exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
fileMenu.add(file_exit);
JMenuBar menu = new JMenuBar();
menu.add(fileMenu);
root.setJMenuBar(menu);
this.setVisible(true);
JDialog d = new JDialog(this, "Dialog");
d.setSize(200, 100);
d.setLocation(0, (int)root.getContentPane().getLocationOnScreen().getY());
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
d.setVisible(true);
}
public static void main(String[] args) {
String os = System.getProperty("os.name").toLowerCase();
if(os.indexOf("mac") >= 0) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
}
new MenuBarProblem();
}
}
If I can be honoust, i think that the problem lies in the part of JRootPane. But we'll see ;)
Did anyone else encountered this problem and managed to solve it alrady, or is there anybody that wants to give it a shot?
Thanks in advance!
Added content:
In the following example I will show a version that gives some functionality to the play.
This is the program i'm making:
The second image shows the state in which the right menu is undocked.
Obviously the JMenuBar should still be visible and operational because without it, a lot of functionalities of the program will be disabled.
At this point i'm starting to think that it is impossible for the JMenuBar to stay visible when the dialog (undocked menu) is undocked, and focussed on.
I know that the JMenuBar on a JDialog can not be in the mac osx style (top of screen), so are there any other techniques i can use for undocking, which does give me a mac osx style JMenuBar?
One key to solving this problem, pun intended, is to let a key binding share a common menu action, as shown below. Note how a menu item, your dialog's content and an (otherwise superfluous) button can all use the same Action instance. A few additional notes:
Kudos for using getMenuShortcutKeyMask().
Swing GUI objects should be constructed and manipulated only on the event dispatch thread (EDT).
System properties should be set before starting the EDT.
Make the dialog's setLocation() relative to the frame after its geometry is known.
A common Mac idiom uses the following predicate:
if (System.getProperty("os.name").startsWith("Mac OS X") {…}
See also this example.
For local use in the dialog itself, also consider JToolBar.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
/**
* #see https://stackoverflow.com/a/13100894/230513
*/
public class MenuBarProblem extends JFrame {
private static final int MASK =
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private static final String exitName = "Exit";
private static final KeyStroke exitKey =
KeyStroke.getKeyStroke(KeyEvent.VK_W, MASK);
private final ExitAction exitAction = new ExitAction(exitName);
public MenuBarProblem() {
super("Frame");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
JMenu fileMenu = new JMenu("File");
JMenuItem fileExit = new JMenuItem(exitAction);
fileMenu.add(fileExit);
JMenuBar menu = new JMenuBar();
menu.add(fileMenu);
JDialog d = new JDialog(this, "Dialog");
JPanel p = new JPanel();
p.getInputMap().put(exitKey, exitName);
p.getActionMap().put(exitName, exitAction);
p.add(new JButton(exitAction));
d.add(p);
d.pack();
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
this.setJMenuBar(menu);
this.pack();
this.setSize(new Dimension(320, 240));
this.setLocationByPlatform(true);
this.setVisible(true);
d.setLocation(this.getRootPane().getContentPane().getLocationOnScreen());
d.setVisible(true);
}
private static class ExitAction extends AbstractAction {
public ExitAction(String name) {
super(name);
this.putValue(Action.MNEMONIC_KEY, exitKey.getKeyCode());
this.putValue(Action.ACCELERATOR_KEY, exitKey);
}
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
public static void main(String[] args) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new MenuBarProblem();
}
});
}
}
Solved!
Using a JFrame with the use of setAlwaysOnTop(true) gives me the desired effect of having a JMenuBar when the focus changes.

Categories

Resources