Java- Adding Radio Buttons using AWT? - java

This program has 2 radio buttons. 1: for a circle and 2: for outputting a square.
This program is basically designed to either output a cirlce or square based off a radio button group.
My issue is that I don't know how to implement an action listener onto the buttons in-order to output the shape. There are errors within initializing the radio buttons when I invoked the method fm. Apparently I think I need a main method.
Bear in mind this is java AWT.
Please comment if you want me to add more details or clarify.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.applet.Applet;
public class RadioButton extends Applet
implements ActionListener
{
int choice;
Frame fm = new Frame ("RadioButton Group");
Label la = new Label ("What shape do you want to draw?:");
fm.setLayout (new GridLayout (0, 1));
CheckboxGroup cg1 = new CheckboxGroup ();
fm.add (la);
fm.add (new Checkbox ("CIRCLE", cg1, true));
fm.add (new Checkbox ("SQUARE", cg1, true));
fm.setSize (250, 200);
fm.setVisible (true);
fm.addWindowListener (new WindowAdapter ()
{
public void paint (Graphics g) // How can you 'update the drawing' or repaint it?
{
switch (choice) // Maybe for colors if all else fails you can add a switch 'within' a switch. Inefficient-yes but helps.
{
case 1:
if (choice == 1)
g.fillOval (30, 40, 20, 20);
case 2:
if (choice == 2)
g.fillRect (20, 40, 20, 20);
break;
}
}
public void actionPerformed (ActionEvent evt)
{
if (evt.getSource () == "CIRCLE")
choice = 1;
else
choice = 2;
}
public void windowClosing (WindowEvent we)
{
System.exit (0);
}
}
);
}
}

You can use an item Listener. This is a complete working example:
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JFrame;
public class Project1 extends JFrame implements ItemListener {
CheckboxGroup cg1 = new CheckboxGroup (); //create group
Checkbox c1 = new Checkbox("Circle",cg1,true); //circle button
Checkbox c2 = new Checkbox("Square",cg1,true); //square button
public Project1() {
setLayout(new FlowLayout());
//add listeners
c1.addItemListener(this);
c2.addItemListener(this);
//add to frame
add(c1);
add(c2);
//set visible
this.setVisible(true);
}
#Override
public void itemStateChanged(ItemEvent e)
{
//c1 = circle
//c2 = square
if(e.getSource() == c1)
System.out.println("Circle");
else
System.out.println("Square");
}
public static void main(String[] args) {
Project1 p = new Project1();
}
}
Save this to a .java full and run it. Should give you a decent example of how to accomplish what your looking for.

Related

class variable not updating after method call

I am quite new to Java and only after researching and googling and reading many answers, I am posting this. I am kinda lost. A little guidance would be of great help. The following is a method from a class that implements the "ActionListener" interface. What I am trying to do is this: There is a button which one clicked should open a new window with two options in the form of two Radio Buttons. I need to know the Radio Button which was selected for further use in my code. I declared, the "scoreOption" variable as a class variable and static, and then attempt to update it in the "actionPerformed" abstract method. But when I refer to it (after the method call), the value stays the same - null, or whatever I set it to initially. Here is the code:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class StartEvents implements ActionListener {
StartPanel startingPanel;
static String scoreOption;
public StartEvents(StartPanel startPanel) {
startingPanel = startPanel;
}
// Scoring System Window - 1
public void scoringSystem() {
startingPanel.scoringSystem.addActionListener(new ActionListener () {
#Override
public void actionPerformed(ActionEvent e) {
Panel scoringSystemPanel = new Panel();
JFrame scoreSystemFrame = scoringSystemPanel.frame(150, 250, "Scoring System", 2, true);
JPanel scoreSystemPanel = scoringSystemPanel.panel(Color.lightGray);
JButton confirmSelection = scoringSystemPanel.button(40, 20, "Confirm");
JRadioButton scoreSystem1 = scoringSystemPanel.radioButton("Option 1: Same Points Per Hit");
scoreSystem1.setActionCommand("Option 1");
JRadioButton scoreSystem2 = scoringSystemPanel.radioButton("Option 2: Unique Points Per Hit");
scoreSystem2.setActionCommand("Option 2");
ButtonGroup scoreSys = new ButtonGroup();
scoreSys.add(scoreSystem1);
scoreSys.add(scoreSystem2);
scoreSystemFrame.getContentPane().add(scoreSystemPanel);
scoreSystemPanel.add(scoreSystem1);
scoreSystemPanel.add(scoreSystem2);
scoreSystemPanel.add(confirmSelection);
// Get Selection Event
// Option 1
scoreSystem1.addActionListener(new ActionListener () {
#Override
public void actionPerformed(ActionEvent e) {
if (scoreSystem1.isSelected()) {
scoreOption = scoreSystem1.getActionCommand();
}
}
});
// Option 2
scoreSystem2.addActionListener(new ActionListener () {
#Override
public void actionPerformed(ActionEvent e) {
if (scoreSystem2.isSelected()) {
scoreOption = scoreSystem2.getActionCommand();
}
}
});
// Confirm Event
confirmSelection.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
scoreSystemFrame.dispose();
}
});
}
});
}
Main Game Class where the method scoringsystem is called.
import java.util.ArrayList;
public class Game {
public static void main(String[] args) {
StartPanel startingPanel = new StartPanel();
startingPanel.makeStartPanel();
StartEvents starter = new StartEvents(startingPanel);
starter.rulesButton();
starter.exitButton();
starter.highScoresButton();
ArrayList<Integer> dimensions = starter.boardSizeSelector();
// Problem Zone
System.out.println(StartEvents.scoreOption);
starter.scoringSystem();
System.out.println(StartEvents.scoreOption);
// The two values of scoreOption should be different
String[] playPanelDetails = {"970", "Player 1", "450"};
// Final Start of the Game
starter.startGameButton(playPanelDetails, dimensions);
}
}
Furthermore, could you please let me know regarding the following questions:
Implementing "ActionListener" within another "ActionListener" is recommended? Good Practice?
Can there only be one declaration of the "actionPerformed" method or can it be overloaded too?
Is it possible to get a return value from "actionPerformed" method?
I would be really grateful if even some hints could be provided. I really tried a lot and only then posting it here. Thank you very much in advance.
Small Edit: When I "System.out.println" the "actioncommand" there itself, it does work perfectly, printing in the console. But not when I try to update the class variable and then try to print it after the method call. Dunno if this helps.
JFrames are not modal -- you create one and display it, it does not block the code flow, and so you are extracting the value of scoreOption right as the JFrame is being displayed and before the user has had any chance to change it. You need to use a modal dialog such as a JDialog that is created as a modal dialog or use a JOptionPane (which is actually just a modal JDialog under the hood). This will block the flow of code so that you extract the data only after it has been changed by the user.
An example that proves the point:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FooGui01 extends JPanel {
private String frameTest = "";
private String dialogTest = "";
private JFrame mainFrame = new JFrame("Main GUI");
private JFrame subFrame;
private JDialog dialog;
public FooGui01() {
JButton showFrameBtn = new JButton("Show JFrame");
showFrameBtn.addActionListener(e -> {
changeTest1WithJFrame();
System.out.println("frameTest: " + frameTest);
});
JButton showDialogBtn = new JButton("Show JDialog");
showDialogBtn.addActionListener(e -> {
changeTest2WithModalDialog();
System.out.println("dialogTest: " + dialogTest);
});
JPanel panel = new JPanel();
panel.add(showDialogBtn);
panel.add(showFrameBtn);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.add(panel);
mainFrame.pack();
mainFrame.setLocationByPlatform(true);
mainFrame.setVisible(true);
}
public void changeTest1WithJFrame() {
if (subFrame == null) {
subFrame = new JFrame("Frame");
JButton button = new JButton("Press me");
button.addActionListener(e -> {
frameTest = "Hello World and frameTest";
subFrame.setVisible(false);
});
JPanel panel = new JPanel();
panel.add(button);
subFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
subFrame.add(panel);
subFrame.pack();
subFrame.setLocationByPlatform(true);
}
subFrame.setVisible(true);
}
public void changeTest2WithModalDialog() {
if (dialog == null) {
dialog = new JDialog(mainFrame, "Dialog", Dialog.ModalityType.APPLICATION_MODAL);
JButton button = new JButton("Press me");
button.addActionListener(e -> {
dialogTest = "Hello World and dialogTest";
dialog.setVisible(false);
});
JPanel panel = new JPanel();
panel.add(button);
dialog.add(panel);
dialog.pack();
dialog.setLocationByPlatform(true);
}
dialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new FooGui01());
}
}
If you run the code, when you show the sub JFrame, the test text is displayed immediately in the console before the dialog has been dealt with. If you press the button to show the dialog, the test text display is delayed until after the button has been pushed, changing the text.
Pressing the frame button twice will finally show the correct text since the text was set by the first time it was displayed.
A JDialig is just like a JFrame. That is you add components to it like you do any frame.
The difference is that you can make a JDialog modal. This means that when you use:
dialog.setVisible(true);
System.out.println("here");
The code after the setVisible(...) statement will not be executed until the dialog is closed. It also means you can't click on the parent JFrame until the dialog is closed.
An easy way to create a modal JDialog is to use a JOptionPane. It has some predefined methods that make prompting for user input easy.
For example in your case you could do something like:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE extends JPanel
{
private int scoringOption = -1;
public SSCCE()
{
JButton button = new JButton("Change Points Option");
add(button);
button.addActionListener((e) -> displayOptionDialog());
}
private void displayOptionDialog()
{
Window window = SwingUtilities.windowForComponent( this );
// Custom button text
Object[] options = {"Option 1: Same Points Per Hit", "Option 2: Unique Points Per Hit"};
scoringOption = JOptionPane.showOptionDialog(
window,
"Select your scoring option:",
"Scoring Option",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null,
options,
null);
System.out.println( scoringOption );
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE());
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
The above is also an example of an "MRE". The code is simple and contained in a single class that you can copy/paste/compile and test.
Read the section from the Swing tutorial on How to Use Dialogs for more examples of using a JOptionPane.
If you really want to use radio buttons, then you can create a panel with the radio buttons and display them on the option pane using the showConfirmDialog(...) method. When the dialog closes you would then need to get the action command from the ButtonModel of the ButtonGroup.
See: how to set & manage the layout of JOptionPane for a basic example of this approach to get you started.

I need help on a few things on Java JFrame

I have created this Progress Code and now I want it to close automatically after going to 100% and also open a new Frame with Text in the frame. So how do I do this?
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;
class Progress extends JFrame implements ActionListener {
JProgressBar pb;
JButton b1;
Progress() {
super("Progress");
setLayout(null);
b1 = new JButton("Start");
b1.setBackground(Color.LIGHT_GRAY);
pb = new JProgressBar(1,100);
pb.setValue(0);
pb.setStringPainted(true);
pb.setForeground(Color.green);
pb.setBackground(Color.pink);
b1.setBounds(20, 20, 80, 25);
pb.setBounds(110, 20, 200, 25);
pb.setVisible(false);
add(b1);
add(pb);
b1.addActionListener(this);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
int i=0;
if(e.getSource()==b1) {
pb.setVisible(true);
try {
while(i<=100) {
Thread.sleep(50);
pb.paintImmediately(0, 0, 200, 25);
pb.setValue(i);
i++;
}
} catch(Exception e1) {
System.out.print("Caughted exception is ="+e1);
}
}
}
public static void main(String arg[]) {
logindemo m=new logindemo();
m.setSize(400,250);
m.setVisible(true);
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - m.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - m.getHeight()) / 2);
m.setLocation(x, y);
}
}
This is the code for my Progress bar.
So a thing before the answer.
ProgressBar
In your code while progress is increasing rest of the application is frozen. If you want to avoid it, it's good to have progress bar code in another Thread. But remember to use SwingWorker instead of classic Threads.
Also read the thing what Andrew Thompson mentioned in his comments.
To "close" or rather hide main frame u can call one of these methods
setVisible(false);
or
dispose();
To open new Window/Frame or whatever, you have to put it after the while loop. You can check it with code below, just add this method to your class and call it after the loop.
private void dialogMessage() {
Object[] options = {"OK"};
int result = JOptionPane.showOptionDialog(this,
"Done!", "",
JOptionPane.OK_OPTION, JOptionPane.QUESTION_MESSAGE,
null,
options,
options[0]);
if (result == JOptionPane.OK_OPTION) {
System.exit(0);
}
}
To read more about JOptionPane check out this link How to Make Dialogs

Using removeActionListener but not removing - JAVA

I have created part of a Tic-Tac-Toe game, and I am trying to make sure the "Player VS Player" button becomes disabled once a game is started. I am new to Java swing and all of the graphics, so please, any help is appreciated. I have used .removeActionListener, but it seems to not do anything (or anything I notice). My code probably looks very bad to some of you, but as I said, I am new to this. Some of the imports may not be needed now, but I plan on using them later.
Thanks in advance!
import java.util.Scanner;
import java.lang.Object;
import java.awt.Component;
import java.awt.Container;
import java.awt.Window;
import java.awt.Frame;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.text.JTextComponent;
import javax.swing.JTextField;
import java.lang.Thread;
import java.util.EventObject;
import java.awt.AWTEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowEvent;
import java.awt.Font;
import javax.swing.*;
class ticTacToe implements ActionListener
{
public static JFrame menuFrame = new JFrame("Tic-Tac-Toe");
public static JPanel menu = new JPanel();
public static JButton instruct = new JButton("Instructions"), pvp = new JButton("Player VS. Player"), pvc = new JButton("Player VS. Computer");
public static String pOne = "bla", pTwo = "bla";
public static boolean namesEntered = false;
public static JFrame pvpFrame = new JFrame (pOne+" "+"VS."+" "+pTwo);
public static JPanel board = new JPanel (), turns = new JPanel();
public static JLabel turn1 = new JLabel (pOne+" has taken 0 turn(s)."), turn2 = new JLabel (pTwo+" has taken 0 turn(s).");
public static JButton btn1 = new JButton (), btn2 = new JButton (), btn3 = new JButton (), btn4 = new JButton (), btn5 = new JButton (), btn6 = new JButton (), btn7 = new JButton (), btn8 = new JButton (), btn9 = new JButton ();
public static int choice = 3;
public static Font f = new Font("Arial", Font.PLAIN, 40);
public static void main (String[]args)
{
instruct.addActionListener(new Instructions());
pvp.addActionListener(new playerVSPlayer());
pvc.addActionListener(new Action());
menu();
}
public static void menu ()//the main menu of the game
{
menu.setLayout(new FlowLayout());//arranges the layout of the buttons on the panel
menu.add(instruct);//adds the instruction button
menu.add(pvp);//adds the player vs player button
menu.add(pvc);//adds the player vs computer button
menuFrame.add(menu);//creates the panel
menuFrame.setSize(450, 78);
menuFrame.setLocationRelativeTo(null);//sets the location to the centre of the screen
menuFrame.setVisible(true);//makes the menu visible
menuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//extis program when window is closed
}
public void actionPerformed (ActionEvent e)//detection of the clicked button
{
if (e.getSource().equals(instruct))
{
instructions();
}
else if (e.getSource().equals(pvp))
{
if (e.getSource().equals(btn1))
{
btn1.setFont(f);
btn1.setText("X");
btn1.removeActionListener(new playerVSPlayer());
}
else
{
players();
if (!pOne.equals("0")&&!pTwo.equals("0"))
{
firstTurn();
}
if (namesEntered==true&&choice==1)
{
gameBoard();
btn1.addActionListener(new playerVSPlayer());
}
pvp.removeActionListener(new playerVSPlayer());
}
}
}
public static void instructions ()
{
JFrame frame = new JFrame ("Instructions");
frame.setVisible(true);
frame.setSize(300,145);
JLabel label = new JLabel ("The goal of this game is to be the first player that ");
JLabel label2 = new JLabel ("gets 3 X's or O's in a row diagonally, vertically, or");
JLabel label3 = new JLabel ("horizontally. It is possible to tie, by having all");
JLabel label4 = new JLabel ("spaces played with no spots left to win. Click a");
JLabel label5 = new JLabel ("space to enter your X or O.");
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
frame.add(panel);
panel.add(label);
panel.add(label2);
panel.add(label3);
panel.add(label4);
panel.add(label5);
}
public static void players ()
{
Scanner in = new Scanner (System.in);
System.out.println("Player One, please enter a word no longer than 4 letters, representing your username for this game.");
pOne = in.nextLine();
if (pOne.equals("0"))
{
System.out.println("You have cancelled the match. Please choose an option in the main menu, or close the main menu.");
}
else {
while (pOne.length()>4||pOne.length()<1)
{
System.out.println("Player One, your username MUST be between 1 and 4 letters long.");
pOne = in.nextLine();
}
}
if (!pOne.equals("0"))
{
System.out.println("Player Two, please enter a word no longer than 4 letters, representing your username for this game.");
pTwo = in.nextLine();
if (pTwo.equals("0"))
{
System.out.println("You have cancelled the match. Please choose an option in the main menu, or close the main menu.");
}
else {
while (pTwo.length()>4||pTwo.length()<1)
{
System.out.println("Player Two, your username MUST be between 1 and 4 letters long.");
pTwo = in.nextLine();
}
}
}
if (!pOne.equals("0")&&!pTwo.equals("0"))
{
namesEntered= true;
}
}
public static void gameBoard ()
{
pvpFrame = new JFrame (pOne+" "+"VS."+" "+pTwo);
pvpFrame.setLayout(new GridLayout());
pvpFrame.setVisible(true);
pvpFrame.setSize(600,400);
pvpFrame.setLocationRelativeTo(null);
board.setLayout(new GridLayout(3,3));
turns.setLayout(new FlowLayout());
pvpFrame.add(board);
pvpFrame.add(turns);
turn1 = new JLabel (pOne+" has taken 0 turns.");
turn2 = new JLabel (pTwo+" has taken 0 turns.");
turns.add(turn1);
turns.add(turn2);
board.add(btn1);
board.add(btn2);
board.add(btn3);
board.add(btn4);
board.add(btn5);
board.add(btn6);
board.add(btn7);
board.add(btn8);
board.add(btn9);
}
public static void firstTurn ()
{
Scanner in = new Scanner (System.in);
System.out.println(pOne+" will be X and "+pTwo+" will be O. Enter 1 if you would like to continue. Enter 0 if you would like to cancel this match and return to the main menu.");
choice = in.nextInt();
while (choice!=0&&choice!=1)
{
System.out.println("Your choice did not match 1 or 0. Please enter your choice again.");
choice = in.nextInt();
}
if (choice==0)
{
System.out.println("You have cancelled the match. Please choose an option in the main menu, or close the main menu.");
}
}
}
EDIT 1:
public void actionPerformed (ActionEvent e)//detection of the clicked button
{
if (e.getSource().equals(instruct))
{
instructions(); // This just runs the instruction panel
}
else if (e.getSource().equals(pvp))
{
if (e.getSource().equals(btn1))
{
btn1.setFont(f);
btn1.setText("X");
btn1.removeActionListener(new playerVSPlayer());
}
else
{
players();
if (!pOne.equals("0")&&!pTwo.equals("0"))
{
firstTurn();
}
if (namesEntered==true&&choice==1)
{
gameBoard();
pvp.setEnabled(false); // my goal here is to make the button no longer usable once the
//game starts, but I also need to make sure later that i can use the button once this game is closed
btn1.addActionListener(new playerVSPlayer());
}
}
}
}
The problem is, that does not disable the button
I have several issues with your code, but as far as your question is concerned, there are two main issues:
First as Christian points out, you are not adding and removing the same instance. I'm not sure if this can be alleviated by giving the class an equals and hashCode override, and I must test this.
But even more important, you seem to expect the class's actionPerformed to act, when you don't appear to add it to any buttons. No where do I see addActionListener(this). Having said that, I try to avoid making my GUI "view" classes implement listener interfaces.
A better solution perhaps would be swapping JButton AbstractActions via the setAction(...) method. Think of AbstractActions as if they were ActionListeners on steroids, since they can do everything that an ActionListener can do and then some. Do this and you won't have to worry about removing prior listeners since a button can have one and only one Action.
Other issues:
Your program grossly over-uses the static modifier. While static fields and methods probably won't matter in small programs, they're not a good habit to get into since they don't "scale" well. In other words, if you create large and complex programs (and if you stick with Java, you will), over-use of static fields and methods increases the potential complexity and limits the inheritance potential of your classes of your programs making them very difficult to debug or enhance. It's a good habit to avoid over-use of static modifier except in the certain situations where it is definitely called for.
You're mixing a Swing GUI with a console program which is a dangerous thing to do. Much better would be to get all user input via the GUI, and leave the console output for debugging purposes (if that) only.
Edit
Yep, if you override equals and hashCode so that all Listeners of one type are the same, then you can remove them as you're trying to do.
For example check this test code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class TestActionListeners extends JPanel {
private JButton button = new JButton("Button");
public TestActionListeners() {
add(button);
button.addActionListener(new Listener1());
}
private static void createAndShowGui() {
TestActionListeners mainPanel = new TestActionListeners();
JFrame frame = new JFrame("Test");
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 Listener1 implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("in listener 1");
AbstractButton button = (AbstractButton) e.getSource();
button.removeActionListener(new Listener1());
button.addActionListener(new Listener2());
}
#Override
public boolean equals(Object obj) {
return obj instanceof Listener1;
}
#Override
public int hashCode() {
return Listener1.class.hashCode();
}
}
class Listener2 implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("in listener 2");
AbstractButton button = (AbstractButton) e.getSource();
button.removeActionListener(new Listener2());
button.addActionListener(new Listener1());
}
#Override
public boolean equals(Object obj) {
return obj instanceof Listener2;
}
#Override
public int hashCode() {
return Listener2.class.hashCode();
}
}
Having said this, I don't recommend that you do this but rather swap AbstractActions via setAction(...).
Edit 2
I'm an idiot for not carefully reading your question. If this is your goal:
and I am trying to make sure the "Player VS Player" button becomes disabled once a game is started:
Then all you need to do is set the button or its Action disabled. i.e.,
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class DisableAButton extends JPanel {
private JButton disableMeButton1 = new JButton("Disable Me 1");
private JButton disableMeButton2 = new JButton(new DisableMe2Action("Disable Me 2"));
public DisableAButton() {
disableMeButton1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
AbstractButton buttonSource = (AbstractButton) e.getSource();
JOptionPane.showMessageDialog(buttonSource, "DisableMe1 ActionListener!");
buttonSource.setEnabled(false);
}
});
add(disableMeButton1);
add(disableMeButton2);
}
private static void createAndShowGui() {
DisableAButton mainPanel = new DisableAButton();
JFrame frame = new JFrame("DisableAButton");
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 DisableMe2Action extends AbstractAction {
public DisableMe2Action(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
JComponent source = (JComponent) e.getSource();
JOptionPane.showMessageDialog(source, "DisableMe2 Action!");
setEnabled(false);
}
}
you should use the same instance to call add and remove.
therefor store the listeners in a field

How to draw a rectangle in a JButton Action Listener

I'm trying to do something where the user gets a prompt where they can pick a colour from the JColorChooser and once they've done that, a rectangle pops up in the same JFrame and it has the same colour as what the user picked
Code so far:
import javax.swing.*;
import java.util.*;
import java.awt.*;
public class TestProjectDialog {
static String name;
public String getName(){
return name;
}
TestProjectJPanel jpp = new TestProjectJPanel();
public static void main(String[] args){
JOptionPane.showMessageDialog(null, "Just about to draw a REALLY GOOD 2D car \n just need input please.");
name= JOptionPane.showInputDialog("Imagine a car, what is it's name?");
if(name == null || (name != null && ("".equals(name))))
{
JOptionPane.showMessageDialog(null, "Invalid input/pressed cancel, closing program.");
System.exit(0);
}
JOptionPane.showMessageDialog(null, "Ah okay, so it's name is " + name);
JFrame f = new JFrame(name);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TestProjectJPanel jpp = new TestProjectJPanel();
jpp.setBackground(Color.WHITE);
f.setSize(1440,900);
f.add(jpp.panel, BorderLayout.CENTER);
f.add(jpp.b, BorderLayout.SOUTH);
f.setVisible(true);
}
}
And for the class which has the button, listener and where I want the Rectangle to appear
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TestProjectJPanel extends JFrame {
public JButton b;
public Color color = (Color.WHITE);
public JPanel panel;
public Color bodyColour;
public Color doorColour;
public Color wheelColour;
public void paintComponent(Graphics g){ // Surely this shouldn't be void as it's returning a Rectangle?
super.paintComponents(g);
Rectangle r = new Rectangle(430,50,250,400);
g.fillRect((int)r.getX(),(int)r.getY(),(int)r.getHeight(),(int)r.getWidth());
g.setColor(bodyColour);
}
public TestProjectJPanel(){
panel = new JPanel();
panel.setBackground(color);
// bodyColour button
b = new JButton("Choose a colour for the body of the car");
b.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
bodyColour = JColorChooser.showDialog(null, "Pick the colour", bodyColour);
if(bodyColour==null)
bodyColour = (Color.BLACK);
// TRYING TO DRAW THE RECTANGLE HERE ONCE THE USER PICKED THEIR COLOUR.
}
}
);
}
}
See Performing Custom Painting.
As a hint, don't override paint of top level containers like JFrame, create a custom JPanel and override it's paintComponent method and perform your custom painting there (don't forget to call super.paintComponent).
Provide methods to that allow you to change the color of the rectangle and call repaint to request that the panel should be updated.

Using two Frames in a GUI

I'm developing a GUI that is kinda like a menu to control an assembly line. When the program runs, it shows up the window with the first set of buttons. Clicking in a button should make this window disappear and should make another window appear with the previously chosen menu. How do I implement the action on the button? Both menus are in different classes and there's an extra class with the main function that, for now, only creates new objects and set the visibility of the first window to true.
Here are both of them:
Main one:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class InfInd {
public static void main(String[] args) {
Cliente c = new Cliente();
c.setVisible(true);
}
}
The first Menu:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Cliente extends JFrame implements ActionListener {
public JLabel titulo;
public JButton ordens;
public JButton listaordens;
public JButton stats;
public JButton desc;
public JButton sair;
public Cliente() {
titulo = new JLabel("Menu Cliente");
ordens = new JButton ("Ordens");
listaordens = new JButton("Lista Ordens");
stats = new JButton ("Estatísticas");
desc = new JButton ("Peças Descarregadas");
sair = new JButton ("Sair");
setLayout(null);
Dimension size1 = titulo.getPreferredSize();
Dimension size2 = ordens.getPreferredSize();
Dimension size3 = listaordens.getPreferredSize();
Dimension size4 = stats.getPreferredSize();
Dimension size5 = desc.getPreferredSize();
Dimension size6 = sair.getPreferredSize();
titulo.setBounds(100, 50, size1.width, size1.height);
ordens.setBounds(100, 100, size2.width, size2.height);
listaordens.setBounds(100, 150, size3.width, size3.height);
stats.setBounds(100, 200, size4.width, size4.height);
desc.setBounds(100, 250, size5.width, size5.height);
sair.setBounds(100, 300, size6.width, size6.height);
sair.addActionListener(this);
add(titulo);
add(ordens);
add(listaordens);
add(stats);
add(desc);
add(sair);
setSize(500, 500);
setTitle("Teste");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent out){
System.exit(0);
}
}
The second menu is similar to this one, only with different names for the buttons. The idea is to, for now, just show up the second menu by clicking on the "Ordens" button. Sorry of this seems quite noobish but I've only started with Java GUIs yesterday. Thank you all.
You could do something like this
public class MyFrame extends JFrame {
private JButton jbt = new JButton("Open Window");
private AnotherFrame jfrm = new AnotherFrame(); // another frame
public MyFrame(){
add(jbt);
add(jfrm); // add frame
jbt.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
jfrm.setVisibility(true); // when button clicked, set
} // visibility for other frame true
});
}
private AnotherFrame extends JFrame {
public AnotherFrame(){
}
}
}

Categories