How can I get the ImageIcon displayed in a JButton? - java

public ImageIcon getIcon(){
return button.getIcon();
}
public void moveTo(Square j){
JButton current = new JButton();
current = button;
button.setIcon(j.getIcon());
button.setIcon(current.getIcon());
}
Here's the problem. Button is just a simple JButton without content, and with conditions I'm adding different content into Button. Though when I created the move method, which will switch the two images of two buttons, I failed to attempt to get the ImageIcon of the JButton. It reports this error in the first method:
Icon cannot be converted to ImageIcon
How can I solve that?

Icon is an interface which is implemented by the class ImageIcon so inherently every ImageIcon is an Icon so you can cast the Icon to imageIcon as follows
public ImageIcon getIcon(){
return (ImageIcon)button.getIcon();
/*getIcon() returns Icon and ImageIcon is child
of Icon so you can cast as you cast parent class reference to child class in this
case it is interface acting as parent*/
}

You can add it through the constructor:
JButton button = new JButton("text", icon);
The better way is to create an action and create the button from the action. Then you can update the icon of the action and it will be udpated everywhere that action is used: the button, menu bars, popup menus, etc.
Action action = new AbstractAction("text", icon) {
public void actionPerformed(ActionEvent e) {
}
}
//place the action in an ActionMap
Jbutton button = new JButton(action);
Then when you need to update the icon it would just be
getActionMap().get(key).putValue(Action.LARGE_ICON_KEY, icon); //for buttons
getActionMap().get(key).putValue(Action.SMALL_ICON_KEY, icon); //for menus

Related

Show picture when button is clicked

I am trying to get my action listener to show a picture when the button is clicked, but hide it until then. I also need it to only allow me to click it once. I have the button in a separate class that extends JButton so I'm unsure if that is affecting it. When I add the image using the action listener, it doesn't show the image whether I click it or not. When I add it to the button, it shows it before it is clicked(as expected). What is the best way to hide the image until the button is clicked? FYI, there are many instances of this button created, if that makes a difference.
This is the button class
import javax.swing.*;
public class EmptyButton extends JButton
{
public EmptyButton()
{
//add image to button
ImageIcon emptyImage = new ImageIcon("Empty.jpg");
JLabel empty = new JLabel(emptyImage);
}
}
This is the action listener
private class emptyButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
game.noTreasureFound();
treasuresFoundTextField.setText(String.valueOf(game.getTreasuresFound()));
treasuresLeftTextField.setText(String.valueOf(20-game.getTreasuresFound()));
triesLeftTextField.setText(String.valueOf(game.getTriesLeft()));
}
}
use JLabel#setVisible(true) to make image visible on click. Initially call setVisible(false) to hide it
use JButton#setEnabled(false) to disable button after click

How to getSource from a button object made from other class'

i am making a memory game using java swing. so far i have made a class that returns custom JButtons with an image already in them (unfliped). in the main class i am creating objects of that class and add them to the panel. everything works but when i am adding the action listeners the getSource method returns a JButton and as a result i cant use the methods from inside the custom buttons class. How can i use getSource and create a button from the custom buttons class?
i have tried casting the button returned from the getSource method to Buttons(custom buttons class) but it didnt work.
public class Buttons extends JButton{
int id;
JButton butt;
private static int x=0;
public Buttons() throws IOException{
butt=this.retButton();
}
public JButton retButton() throws IOException{
BufferedImage img =
ImageIO.read(getClass().getResourceAsStream("/folder/flipped.png"));
ImageIcon image = new ImageIcon(img);
JButton button = new JButton();
button.setName(Integer.toString(x));
button.setIcon(image);
button.setBackground(Color.white);
x+=1;
return button;
}
public JButton getButton(){
return this.butt;
}
public int getId() {
return id;
}
}
in the main class i am using:
for (int i=0; i<12; i++){
jb[i] = new Buttons();
jb[i].getButton().addActionListener(this);
jb[i].setId(cardNums.get(i));
panel.add(jb[i].getButton());
}
frame.add(panel, BorderLayout.CENTER);
frame.pack();
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source instanceof JButton) {
JButton btn = (JButton)source;
System.out.println("hey");}
action listener works but since btn is a JButton it wont let me use the getId method of the Buttons class.
Why do you want your Buttons instance to have a separate button as an attribute? You already ARE a button. This seems like a poor design choice.
That said, since you set the button name to be the creation index,you could just use source.getName() and convert it back to an int, then use that int as an index for the jb array.

Changing button color after click and resetting it Java

public class ButtonsActionListener implements ActionListener {
String[] buttons = { "Button1", "Button2", "Button3", "Button4"};
for (String btn: buttons ) {
JButton button = new JButton(btn);
this.add(button);
button.addActionListener(this);
}
}
#Override
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton)e.getSource();
btn.setBackground(Color.Red);
}
}
What Im trying to do is when the user clicks on for example Button1, Button1's color should turn to grey and when I click on BUtton3, Button1 color should go back to normal and Button3 should turn grey. I dont know how to check the previous click
Your actionPerformed function changes the background of what is currently clicked, so it will not allow you to change other JButton objects without a very rudimentary condition. You should store all of your buttons as unique variables for such cases.

Defining/Setting the color of JComboBox BasicArrowButton in case of disabling

I didn't like the standard arrow button of the JComboBox, because it didn't fit well in my GUI. So I changed it. To do this, I wrote a class, which is extending BasicComboUI. In the regular case, everything is like I am expecting it. But as soon as I am disabling the button, it stays the way it is, which means that the button doesn't get the grey background color anymore. Instead, the left part of the list does. So I would like to know, if there is a way to define or to modify the disabling-behavior of the arrow button.
Here is my current code:
public class CustomArrowUI extends BasicComboBoxUI{
private static Color buttonBackground;
private static Color borderBox;
private static Color arrowColor;
private static Color buttonBorder;
public static ComboBoxUI createUI(JComponent c, Color buttonBackground, Color borderBox, Color arrowColor, Color buttonBorder)
{
CustomArrowUI.buttonBackground = buttonBackground;
CustomArrowUI.borderBox = borderBox;
CustomArrowUI.arrowColor = arrowColor;
CustomArrowUI.buttonBorder = buttonBorder;
return new CustomArrowUI();
}
#Override
protected JButton createArrowButton()
{
JButton button = new BasicArrowButton(BasicArrowButton.SOUTH, buttonBackground, borderBox, arrowColor, buttonBorder);
LineBorder border = new LineBorder(buttonBorder, 1);
button.setEnabled(false);
button.setBorder(border);
return button;
}}
What I could do is setting the background light grey as default, and change the color in the ActionListener of the previous button, which is enabling my JComboBox. But I kinda don't like this solution. I would prefer to do it directly in my CustomArrowUI
I found one short way to solve this. I added a ChangeListener to my arrow button, which is checking if the button is enabled or not, and coloring the button:
#Override
protected JButton createArrowButton()
{
final JButton button = new BasicArrowButton(BasicArrowButton.SOUTH, buttonBackground, borderBox, arrowColor, buttonBorder);
LineBorder border = new LineBorder(buttonBorder, 1);
button.setEnabled(false);
button.setBorder(border);
button.addChangeListener(new ChangeListener(){
#Override
public void stateChanged(ChangeEvent arg0) {
if(button.isEnabled())
button.setBackground(Color.WHITE);
else
{
button.setBackground(ColorPalette.LIGHT_GREY);
button.setBorder(new LineBorder(ColorPalette.LIGHT_GREY, 1));
}
}
});
return button;
}
Above I changed the background of the button and the border color too make it look like the arrow is part of the JComboBox, and not like a separate button inside of it.
Since the disabling-behavior is inheritet from the JComboBox itself (I guess), I don't need to take care if the button is usable or not. All I need to define is the color.
Another important point is to make sure, to call the setEnabled()-method after setting the UI of the JComboBox, if the JComboBox should be disabled by default. Otherwise it will not react initially, and the arrow button will look enabled.

Change JButton ImageIcon on Click

I am attempting to create a JFrame Application in java that is similar to Minesweeper but with slightly different rules/goals.
I have created a grid of JButtons, 12x12 and have a JButton 2D array.
I'm trying to change the image of a button when it is clicked (make it an X or an image of a gold nugget). I know how to do this if I had an individual name for each button, but it seems not logical to create 144 individual buttons and name each of them.
So what I need to do is on the click event of that button, change/set the image of that button, but in my action listener I can only figure it out if I know the specific array coordinates of that button.
My question is how do I change the Image of that specific button? Or how do I get the values of the button[?][?] so I can change the image of that button?
Thanks!
public class GoldPanel extends JPanel{
ImageIcon xImage = new ImageIcon("x.png");
ImageIcon goldImage = new ImageIcon("");
losingButtonListener loseButton = new losingButtonListener();
winningButtonListener winButton = new winningButtonListener();
JButton[][] button = new JButton[12][12];
//creates the layout
GridLayout layout = new GridLayout(12,12);
Random myRand = new Random();
public GoldPanel(){
//creates panel for name/title/score/etc
JPanel titlePanel = new JPanel();
add(titlePanel);
JLabel title = new JLabel("Welcome to the Goldmine Game!");
titlePanel.add(title);
//creates panel for the game board
JPanel gamePanel = new JPanel();
add(gamePanel);
gamePanel.setLayout(layout);
for(int i=0;i<12;i++)
{
for(int j=0;j<12;j++)
{
button[i][j] = new JButton(" ");
gamePanel.add(button[i][j]);
button[i][j].addActionListener(loseButton);
}
}
button[0][0].addActionListener(winButton);
}//end constuctor
private class losingButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}//actionPerformed
}//buttonListener
private class winningButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("you win");
}//actionPerformed
}//winningButtonListener
}//end GoldPanel class
If you look at the ActionEvent Documentation Page you see that every action event is constructed with an Object source. This means that if the system registers a click on the button this button gets passed to the constructor of the ActionEvent as source.
So you're actually getting the right button by casting this object to the right class.
[...]
public void actionPerformed(ActionEvent ae) {
JButton theRightButton = (JButton) ae.getSource();
// do stuff with the button...
}
[...]
Use a toggle button
http://docs.oracle.com/javase/7/docs/api/javax/swing/JToggleButton.html
So swing keeps track of the state for you in the button model.
Extend the button to pass x,y coord in the constructor and store them as field
Attach the same event listener to all buttons, cast source to button class and retrieve x/y of the button having been clicked
Change on the fly the pressed icon to mine or number in the event
Call click to all neighbouring empty fields if you want to replicate this rule, but make sure to check the pressed state so you don't loop back over already processed neighbours.

Categories

Resources