So, i made a button like this
parameter nomor in LoadPlanet and LoadRR is parameter to show some data to textbox.
my code is like this
the button appear correctly, but if i clicked the buttons, all of them show data from the last data which supposed to be data in last button.
-> a result from tblplanet.JmlPlanet() is 8, so the parameter was like LoadPlanet(8), so that every button show 8th data.
my question is how to make the parameter in sequence, so the button can show data correctly? Any ideas?
public void createButton() {
for (i = 0; i < tblplanet.JmlPlanet(); i++) {
tblplanet.draw(i + 1);
planet_name = tblplanet.getNama_planet();
JButton PlanetJButton = new JButton();
PlanetJButton.setBounds(10, 5 + (i * 35), 95, 26);
PlanetJButton.setText(planet_name);
PanelButton.add(PlanetJButton);
PlanetJButton.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
for (int i = 0; i < tblplanet.JmlPlanet(); i++) {
nomor = i;
LoadPlanet(nomor);
LoadRR(nomor);
}
}
});
}
}
Create a class which implements ActionListener and takes a parameter (int) of the planet that it represents
public class PlanetActionListener implements ActionListener {
private final int planet;
public PlanetActionListener(int planet) {
this.planet = planet;
}
#Override
public void actionPerformed(ActionEvent e) {
LoadPlanet(planet);
LoadRR(planet);
}
}
Then simply add the ActionListener to your button
PlanetJButton.addActionListener(new PlanetActionListener(i));
Depending on how you code is structured, you may need to make the PlanetActionListener an inner class so it can access the appropriate methods. See Nested Classes for more details
Related
I have 30 JToggleButton. If they get pressed, I want to pass the i and the title into another class .
confirm.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean buttonClicked = false;
for (i = 0; i < 30; i++) {
if (ButtonList[i].isSelected()) {
buttonClicked = true;
System.out.print(i+1);
System.out.println(title);
pass(title, ButtonList[i]);
}
}
if (!buttonClicked) {
JFrame parent= new JFrame();
JOptionPane.showMessageDialog(parent, "You haven't select a seat");
}
}
});
Before calling past() function, I did a test here. The number of title printed seems following the total number of toggleButton clicked. How to avoid this ?
The above code give me this output (Assume 2 toggle button clicked )
1Marvel's Captain America
2Marvel's Captain America
Are you trying to pass all the selected seats for the specified movie?
Set<Integer> selectedSeats = new LinkedHashSet<>();
for (int i = 0; i < 30; i++)
{
if (ButtonList[i].isSelected())
{
selectedSeats.add(i + 1);
}
}
if (selectedSeats.isEmpty())
{
JFrame parent= new JFrame();
JOptionPane.showMessageDialog(parent, "You haven't select a seat");
}
else
pass(title, selectedSeats);
My question is how can I store the array i into a object so that it
can pass with the title in a new function called pass() ?
so, I understood that you want to inform a method named "pass" with the title and the items that it was selected. If that's the case, you could do something like:
pass(list, title);
using the code below (using ArrayList you dont need to use the "buttonClicked" boolean):
confirm.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ArrayList<int> list = new ArrayList<int>();
for (i = 0; i < 30; i++) {
if (ButtonList[i].isSelected()) {
list.add(i);
}
}
if (list.size() == 0) {
JFrame parent= new JFrame();
JOptionPane.showMessageDialog(parent, "You haven't select a seat");
}
}
});
I hope this helps.
EDIT: Andy Turner you're right, I just changed it
The class that wants to receive the data could implement the the ActionListener interface. Then you could use that class instead of a new ActionListener.
Here how that could look like:
public class ClassThatWantsEvents implements ActionListener{
#Override
public void actionPerformed(ActionEvent e) { ...
and how you would use it in your current class:
confirm.addActionListener(ClassThatWantsEvents);
I'm very new to coding(2 months) and i attempted to make Tic-Tac-Toe in java. I'm in a little over my head but i managed to create it using swing. My main problem is in the button1 class. I was going to use the getText() method but ended up not needing it or so i thought. I tried deleting it but as it turns out my tictactoe buttons don't switch letters without it. The compiler told me it overrides AbstractButton's getText() method but i don't see why that should matter since i never actually used it i thought. I'm thinking it's maybe a scope issue handled by it being overwritten somehow but i'm not sure. I was trying to use the text variable to update the button with setText() and that doesn't seem to work like i thought it should. I also don't understand why the 3 by 3 gridlayout seems to work properly most of the time but sometimes the number of buttons added is wrong.
So in summation the program works(mostly) but i'm not fully understanding how the button1 class is working.
TicTacToe.java
import java.awt.*;
import java.util.*;
import javax.swing.*;
public class TicTacToe extends JFrame {
public static void main(String[] args) {
JFrame window = new JFrame("Tic-Tac-Toe");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.setSize(600, 600);
window.setLayout(new GridLayout(3, 3));
ArrayList<button1> buttonArrayList = new ArrayList<>(9);
for (int i = 0; i < 9; i++) {
button1 newbutton = new button1();
buttonArrayList.add(newbutton);
window.add(buttonArrayList.get(i));
}
}
}
button1.java
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
public class button1 extends JButton {
int value = 0;
String text = "";
public button1() {
class ButtonAction extends AbstractAction {
public ButtonAction() {}
#Override
public void actionPerformed(ActionEvent Switcher) {
System.out.println(text + " " + value);
value++;//value is a relic from earlier attempts that i just felt like keeping.
if (text.equals("O")) {
text = "X";
} else if (text.equals("X")) {
text = "";
} else if (text.equals("")) {
text = "O";
}
}
}
this.setAction(new ButtonAction());
this.setText(text);
this.setFont(new Font("Arial",Font.PLAIN,120));
}
public String getText()// <----culprit
{
return text;
}
}
A JButton class has a methods defined for it, including setText() (which will set the displayed text on the button) and getText() (which will return the current text that is displayed on the button).
You created a class button1 (note: classes should start with Capital Letters).
You added an Action to the button1 class, which means that when the action is activated, something happens. Note that in that actionPerformed method, you should call setText(text) to update the displayed value.
You have also defined a getText() method that overrides the getText() method defined in JButton. This approach is fine if it is a conscious design decision. As it is, I think you should remove the getText() method from the button1 class, and allow the standard JButton class to handle the update. Right now, you are attempting to keep an instance variable text with the value, but it is possible for that instance variable to not be in alignment with the actual displayed value of the button (consider another class calling .setText() on the button).
EDIT: It is true that this referring to the JButton in the ButtonAction is not available. However, the Action itself contains the button that was pressed.
#Override
public void actionPerformed(ActionEvent e)
{
JButton btn = (JButton)e.getSource();
// if desired, String cur = btn.getText() may be called to find the
// current setting; get and process if needed
btn.setText(WHAT_EVER_TEXT);
}
Unless it is a specific requirement to process the current text, however (allowing selecting an O to an X to a blank), I would implement something to keep track of the current turn. This code is something I was experimenting with, and has good and bad points to it (as it is illustrative):
static class TurnController
{
// whose turn it is; start with X
private Player whoseTurn = Player.X;
// the instance variable
private static final TurnController instance = new TurnController();
private TurnController()
{
}
public static Player currentTurn()
{
return instance.whoseTurn;
}
public static Player nextTurn()
{
switch (instance.whoseTurn) {
case X:
instance.whoseTurn = Player.O;
break;
case O:
instance.whoseTurn = Player.X;
break;
}
return instance.whoseTurn;
}
public static String getMarkerAndAdvance()
{
String marker = currentTurn().toString();
nextTurn();
return marker;
}
enum Player
{
X,
O,
;
}
}
Using this TurnController, the actionPerformed becomes:
#Override
public void actionPerformed(ActionEvent e)
{
JButton btn = (JButton)e.getSource();
btn.setText(TurnController.getMarkerAndAdvance());
}
and the Button1 class may have the String text instance variable removed.
What you have tried is Try to make a Custom Button Class and its EventHandler just by extending AbstractAction namee button1 as we See in Your Question.
You have Override the method actionPerformed(ActionEvent Switcher) which actually belongs to Class AbstractAction by your own definition (What should Performed on Action Event of Every Button).
class ButtonAction extends AbstractAction {
public ButtonAction() {}
#Override
public void actionPerformed(ActionEvent Switcher) { // Your Definition For actionPerformed..
System.out.println(text + " " + value);
value++;//value is a relic from earlier attempts that i just felt like keeping.
if (text.equals("O")) {
text = "X";
} else if (text.equals("X")) {
text = "";
} else if (text.equals("")) {
text = "O";
}
}
}
this.setAction(new ButtonAction()); // add ActionListener to each Button.
this.setText(text); // Setting Text to each Button
this.setFont(new Font("Arial",Font.PLAIN,120)); //add Font to each Button.
}
Now In this Code.
ArrayList buttonArrayList = new ArrayList<>();
for (int i = 0; i < 9; i++) {
button1 newbutton = new button1(); // Creating 9 new buttons.
buttonArrayList.add(newbutton); // add each button into the ArrayList.
window.add(buttonArrayList.get(i)); // each Button to the the AWT Window.
}
Above Code will generate 9 Button and add it to Your AWT Window. each button have actionPerformed() method which contains the overrided Definition.
Now Each button will performed action as per the definition you give to actionPerformed() Method.
Thank You.
Suppose I have an array of buttons
private JButton[] myButtons = new JButton[5];
for (int i=0; i<5; i++)
{
myButtons[i] = new JButton(Integer.toString(i));
myButtons[i].setSize(50, 50);
panel.add(myButtons[i]);
}
How can I add a listener to these buttons so that when I click on one of them, I know at which array position index it is at?
You kind of don't care, start by adding an ActionListener to the buttons
myButtons[i].addActionListener(this); // Or some other ActionListener
In the actionPeformed method, you can look up which button it is using the ActionEvent#getSource
#Override
public void actionPerformed(ActionEvent evt) {
for (JButton btn : myButtons) {
if (btn.equals(evt.getSource()) {
// Do what ever you need
break;
}
}
}
You can also use the actionCommand property of the JButton
for (int i=0; i<5; i++)
{
myButtons[i] = new JButton(Integer.toString(i));
myButtons[i].setActionCommand("button " + i);
myButtons[i].addActionListener(this);
panel.add(myButtons[i]);
}
And when actionPeformed is called, use ActionEvent#getActionCommand to figure out which button was pressed.
A better idea might be to create a dedicated ActionListener for each button...
public class ButtonActionHandler implements ActionListener {
private final JButton button;
public ButtonActionHandler(JButton button) {
this.button = button;
}
public void actionPerformed(ActionEvent evt) {
// Do what ever you need to do with the button...
}
}
for (int i=0; i<5; i++)
{
myButtons[i] = new JButton(Integer.toString(i));
myButtons[i].addActionListener(new ButtonActionHandler(myButtons[i]));
panel.add(myButtons[i]);
}
Another idea would be to make use of the Action API which would allow you to define a self contained entity which was capable of configuring the button and handling the associated action event by itself. See How to Use Actions for more details
But which you might use will come down to why you need to identify the buttons in the first place.
You can add listener in loop, like below if you implement ActionListener interface with class. For example,
class TestGUI extends JPanel implements ActionListener{
public TestGUI(){
for(int i=0; i< 5; i++){
....
myButtons[i].addActionListener(this);
}
}
or, if you have separate Listener class or method.
myButtons[i].addActionListener(new MyListener());
Than at actionPerformed method you can check with button is clicked,
public void actionPerformed(ActionEvent e){
if("0".equals(e.getActionCommand())){
System.out.println("First button is clicked");
}
... so on
}
I'm creating a basic calculator using MVC. So far I'm adapting a tutorial which merely sums two user entered values together.
Currently each button I'm adding to the view has it's own listener, which is ok. However, the controller as per the tutorial has a single ActionListener inner class per button. This repeats a huge amount of code.
How can I create a single ActionListener class for all buttons pressed, and use a case statement on the id of the button pressed?
Registering the oneButton in the View
void oneListener(ActionListener listenForOneButton){
oneButton.addActionListener(listenForOneButton);
}
Implementing the ActionListener for the oneButton in the Controller inner class
class oneListener implements ActionListener{
public void actionPerformed(ActionEvent e){
int previousNumber, displayNumber = 0;
try{
previousNumber = theView.getPreviousDisplayNumber();
displayNumber = previousNumber+1;
theView.setDisplayNumber(displayNumber);
}
catch(NumberFormatException ex){
System.out.println(ex);
theView.displayErrorMessage("You Need to Enter Integers");
}
}
}
Start with class which implements ActionListener...
public class CalculatorHandler implements ActionListener{
public static final String ADD_ACTION_COMMAND = "Action.add";
public void actionPerformed(ActionEvent e){
if (ADD_ACTION_COMMAND.equals(e.getActionCommand()) {
// Do your addition...
} else if ...
}
}
It's best to define the action commands that this class can handle is constants, thus removing any ambiguity...
Next, in the class that holds the buttons, create an instance of the ActionListener...
CalculatorHandler handler = new CalculatorHandler();
Then create you buttons as per usual and register the handler...
JButton plus = new JButton("+");
plus.setActionCommand(CalculatorHandler.ADD_ACTION_COMMAND);
plus.addActionListener(handler);
The only problem with this approach, IMHO, is that it can create a monster if-else statement which may become difficult to maintain.
To my mind, I'd create some kind of model/builder that contained a series of helper methods (like add(Number), subtract(Number) etc) and use Actions API for the individual actions for each button...but that's just me...
public class SingleActionListener implements ActionListener {
public void initializeButtons() {
JButton[] buttons = new JButton[4];
String[] buttonNames = new String[] {"button1", "button2", "button3", "button4"};
for (int i = 0; i < 4; i++) {
buttons[i] = new JButton(buttonNames[i]);
}
}
public void addActionListenersToButtons() {
for (int i = 0; i < 4; i++) {
buttons[i].addActionListener(this);
}
}
public void actionPerformedd(ActionEvent actionEvent) {
if (actionEvent.getSource() == buttons[0]) {
//Do required tasks.
}
if (actionEvent.getSource() == buttons[1]) {
//Do required tasks.
}
if (actionEvent.getSource() == buttons[2]) {
//Do required tasks.
}
if (actionEvent.getSource() == buttons[3]) {
//Do required tasks.
}
}
}
Okay so I am making a 2d array of JToggleButtons. I got the action listener up and going, but I have no way to tell which button is which.
If I click one, all it returns is something like
javax.swing.JToggleButton[,59,58,19x14,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource#53343ed0,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=]
Is there anyway to stick some sort of item or number in the button object to associate each button?
And then when the button is clicked I can retrieve that item or number that was given to it?
Here is my button generator code. (How could I make "int l" associate (and count) to each button made, when it is called, it will return that number, or something along those lines.
JToggleButton buttons[][] = new JToggleButton[row][col];
int l = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
buttons[i][j] = new JToggleButton("");
buttons[i][j].setSize(15,15);
buttons[i][j].addActionListener(new e());
panel.add(buttons[i][j]);
l++;
}
}
ActionListner
public class e implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
System.out.println(source);
}
}
variable "source" is what I use to get my data, so how can int l, be returned through "source" (as its unique value for the unique button clicked) as a button is clicked?
Thanks,
-Austin
very simple way is add ClientProperty to the JComponent, add to your definition into loop e.g.
buttons[i][j].putClientProperty("column", i);
buttons[i][j].putClientProperty("row", j);
buttons[i][j].addActionListener(new MyActionListener());
rename e to the MyActionListener and change its contents
public class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JToggleButton btn = (JToggleButton) e.getSource();
System.out.println("clicked column " + btn.getClientProperty("column")
+ ", row " + btn.getClientProperty("row"));
}
EDIT:
for MinerCraft clone isn't required to implements ony of Listeners, there is only about Icon, find out that in this code (don't implement any of Listeners anf remove used ItemListener)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonsIcon extends JFrame {
private static final long serialVersionUID = 1L;
private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ButtonsIcon t = new ButtonsIcon();
}
});
}
public ButtonsIcon() {
setLayout(new GridLayout(2, 2, 4, 4));
JButton button = new JButton();
button.setBorderPainted(false);
button.setBorder(null);
button.setFocusable(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setIcon((errorIcon));
button.setRolloverIcon((infoIcon));
button.setPressedIcon(warnIcon);
button.setDisabledIcon(warnIcon);
add(button);
JButton button1 = new JButton();
button1.setBorderPainted(false);
button1.setBorder(null);
button1.setFocusable(false);
button1.setMargin(new Insets(0, 0, 0, 0));
button1.setContentAreaFilled(false);
button1.setIcon((errorIcon));
button1.setRolloverIcon((infoIcon));
button1.setPressedIcon(warnIcon);
button1.setDisabledIcon(warnIcon);
add(button1);
button1.setEnabled(false);
final JToggleButton toggleButton = new JToggleButton();
toggleButton.setIcon((errorIcon));
toggleButton.setRolloverIcon((infoIcon));
toggleButton.setPressedIcon(warnIcon);
toggleButton.setDisabledIcon(warnIcon);
toggleButton.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton.isSelected()) {
} else {
}
}
});
add(toggleButton);
final JToggleButton toggleButton1 = new JToggleButton();
toggleButton1.setIcon((errorIcon));
toggleButton1.setRolloverIcon((infoIcon));
toggleButton1.setPressedIcon(warnIcon);
toggleButton1.setDisabledIcon(warnIcon);
toggleButton1.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton1.isSelected()) {
} else {
}
}
});
add(toggleButton1);
toggleButton1.setEnabled(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
Just add the row and column data to each listener. You could add an explicit constructor, but I suggest adding a little method (which may have more added to it later).
buttons[i][j].addActionListener(e(i, j));
...
private ActionListener e(final int i, final int j) {
return new ActionListener() {
// i and j available here
...
(In JDK8 you should be able to use a lambda to reduce the syntax clutter.)
And then renaming it with a better name.
I made a minesweeper game and ran into a similar problem. One of the only ways you can do it, is to get the absolute location of the clicked button, then divide that by the x and y between buttons, so for me it was
if ((e.getComponent().getX() != (randx) * 25 && e.getComponent().getY() != (randy) * 25) &&bomb[randx][randy] == false) {
This code was to check if the area had bombs. So I had 25 x and y difference between location of bombs. That will just give you a general idea on how to do this.
I believe: (x - x spacing on left side) / buffer - 1 would work.
Instead of 'e.getSource()' you can always call 'e.getActionCommand()'. For each button you can specify this by:
JButton button = new JButton("Specify your parameters here"); /*you get these from getActionCommand*/
button.setText("title here"); /*as far as I remember*/