I'm trying to move a robot represented by a JLabel into a GridLayout. The move is made but the display of the JLabel is only done for the final finishing square. I would like to see the move from box to box. I try to use javax.swing.Timer but it's not working.
import java.awt.Color;
import java.awt.Component;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serializable;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.LayoutStyle;
import javax.swing.Timer;
// Robot
public class Robot extends Case implements Serializable {
private ImageIcon imageRobot;
private Color couleur;
public Robot () {
imageRobot = new ImageIcon("./assets/balle.png");
setIcon(imageRobot);
}
public void seDeplacer (JPanel panel) {
Robot currentRoot = this;
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
for (int i=0; i<5; i++) {
panel.remove(panel.getComponent(i));
panel.add(currentRoot, i);
panel.doLayout();
}
}
};
new Timer(delay, taskPerformer).start();
}
public void detruire () {
}
public void setCouleur (Color couleur) {
this.couleur=couleur;
}
public Color getCouleur () {
return this.couleur;
}
}
This block
public void seDeplacer (JPanel panel) {
Robot currentRoot = this;
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
for (int i=0; i<5; i++) {
panel.remove(panel.getComponent(i));
panel.add(currentRoot, i);
panel.doLayout();
}
}
};
new Timer(delay, taskPerformer).start();
says literally "move my robot 5 times every second" thus robots moves 5 in blink of an eye every second.
What you wat is to move robot 1 time every second. To do that you need to introduce delay between robot moves.
You & the current commentators are over (or under - shrugs) thinking this. It is not necessary to add or remove components or change Z order to move the robot, just change the label text of the place moved from " " and the new label text to `"🤖".
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class MovingBot {
private JComponent ui = null;
String bot = new String(Character.toChars(129302));
Font font;
JLabel[] labels = new JLabel[100];
MovingBot() {
initUI();
}
public void initUI() {
if (ui!=null) return;
Font[] fonts = GraphicsEnvironment.
getLocalGraphicsEnvironment().getAllFonts();
for (Font font : fonts) {
if (font.canDisplay(129302)) {
this.font = font.deriveFont(20f);
}
}
ui = new JPanel(new GridLayout(0,20,2,2));
ui.setBorder(new EmptyBorder(4,4,4,4));
for (int ii=0; ii<labels.length; ii++) {
JLabel l = new JLabel(" ");
l.setFont(font);
ui.add(l);
labels[ii] = l;
}
labels[0].setText(bot);
ActionListener moveListener = new ActionListener() {
int count = 0;
#Override
public void actionPerformed(ActionEvent e) {
int indexLast = count%100;
labels[indexLast].setText(" ");
count++;
int indexCurrent = count%100;
labels[indexCurrent].setText(bot);
}
};
Timer timer = new Timer(50, moveListener);
timer.start();
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
MovingBot o = new MovingBot();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
Related
I've written a test program with making the jButton invisible and visible:
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
public class Blink
{
private JButton btn;
private static JFrame f;
public static void delay(int ms)
{
try
{
Thread.sleep(ms);
}
catch(InterruptedException ex)
{
Thread.currentThread().interrupt();
}
}
public Blink()
{
f = new JFrame("Blink");
f.setPreferredSize(new Dimension(500, 500));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
btn = new JButton("Click me and I'll blink!");
f.add(btn);
btn.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
buttonClicked();
}
});
f.pack();
f.setVisible(true);
}
private void buttonClicked()
{
for (int i = 0; i < 5; i++)
{
delay(300);
btn.setVisible(false);
delay(300);
btn.setVisible(true);
}
}
public static void main(String[] args)
{
new Blink();
}
}
Unfortunately, the jButton does not blink. And when the buttonClicked() function is changed, so that the jButton is set invisible 5 times and is not set visible back, the jButton disappears only when the for-loop finishes. How to make the jButton disappear an reappear instantaneously?
You cannot use Thread.sleep method in Swing Thread (all listeners are called in Event Dispatcher Thread - EDT). To achieve blinking you must use javax.swing.Timer class. For more information look here and here
Here is your reworked example:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Blink {
private JButton btn;
private JFrame f;
public void delay(int ms, boolean show) {
Timer timer = new Timer(ms, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
btn.setVisible(show);
btn.getParent().revalidate();
btn.getParent().repaint();
}
});
timer.setRepeats(false);
timer.start();
}
public Blink() {
f = new JFrame("Blink");
f.setPreferredSize(new Dimension(500, 500));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
btn = new JButton("Click me and I'll blink!");
f.add(btn);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
buttonClicked();
}
});
f.pack();
f.setVisible(true);
}
private void buttonClicked() {
for (int i = 1; i <= 10; i += 2) {
delay(300 * i, false);
delay(300 * (i + 1), true);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Blink();
}
});
}
}
For some complicated layouts, call setVisible(false) may have side-effects. In this case the CardLayout with your component and an empty panel should be used.
Here is the variant with CardLayout
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Blink {
private static final String BUTTON_CARD = "button";
private static final String EMPTY_CARD = "empty";
private JButton btn;
private JFrame f;
private final CardLayout cardLayout = new CardLayout();
public void delay(int ms, boolean show) {
Timer timer = new Timer(ms, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
cardLayout.show(btn.getParent(), show ? BUTTON_CARD : EMPTY_CARD);
btn.getParent().revalidate();
btn.getParent().repaint();
}
});
timer.setRepeats(false);
timer.start();
}
public Blink() {
f = new JFrame("Blink");
f.setPreferredSize(new Dimension(500, 500));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(cardLayout);
btn = new JButton("Click me and I'll blink!");
f.add(btn, BUTTON_CARD);
f.add(new JPanel(), EMPTY_CARD);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
buttonClicked();
}
});
f.pack();
f.setVisible(true);
}
private void buttonClicked() {
for (int i = 1; i <= 10; i += 2) {
delay(300 * i, false);
delay(300 * (i + 1), true);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Blink();
}
});
}
}
As #Sergiy points out - make sure you're running from the EDT, and don't sleep on the EDT, use a swing timer instead.
To make your jButton appear "invisbile", you can do something like this:
public void setInvisible(jButton jb) {
jb.setOpaque(false);
jb.setContentAreaFilled(false);
jb.setBorderPainted(false);
jb.setText("");
}
// Assuming you have the original text saved in a variable
public void setRevisible(jButton jb) {
jb.setOpaque(true);
jb.setContentAreaFilled(true);
jb.setBorderPainted(true);
jb.setText(originalString);
}
Depending on if you want the button to be clickable when it's invisible, you can also add btn.setEnabled(bool);
Im creating a program in which I must from time to time reset a button Array and display it on a jPanel. The function below adds the jButtons to my panel and displays them perfectly the first time that it is called, but from then on, every time I call it (after emptying the jButton array and applying .removeAll() to the panel) it wont let me change the background color of the jButton. Some assistance to help me find out why this is would be great, thanks.
import java.awt.*;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import javafx.scene.layout.Border;
import javax.swing.*;
/**
*
* #author Luis
*/
public class MineSweeper extends JFrame implements ActionListener {
int int_dim = 11;
int int_cellsShown = 0;
JButton[][] arr_btnField = new JButton[int_dim][int_dim];
int[][] arr_solution = new int[int_dim][int_dim];
Color[] clr_palette = {Color.white, new Color(0X00, 0X94, 0XFF), new Color(0X00, 0X26, 0XFF), new Color(0X00, 0XAA, 0X0A), Color.red, Color.MAGENTA, new Color(0XFF, 0X00, 0X00), new Color(0X9B, 0X00, 0X00)};
boolean bool_change = false;
boolean bool_won = false;
boolean bool_firstround = false;
javax.swing.border.Border border = BorderFactory.createLineBorder(Color.darkGray, 1, true);
MenuBar menu_bar;
Menu menu;
MenuItem optionNew;
//boolean[][] arr_boolShowed=new boolean[int_dim][int_dim];
int int_mines = 8;
ArrayList<Integer> arl_field = new ArrayList<Integer>();
JPanel jpanel = new JPanel();
JPanel jpanel2 = new JPanel();
//ArrayList<Boolean> arl_boolShowed = new ArrayList<Boolean>();
/**
* #param args the command line arguments
*/
public MineSweeper() throws FontFormatException, IOException {
resetGame();
//JFrame frame = new JFrame("");
this.getContentPane().add(jpanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(true);
this.setTitle("Minesweeper");
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setSize(500, 500);
menu_bar = new MenuBar();
menu = new Menu("File");
optionNew = new MenuItem("Win");
optionNew.addActionListener(this);
menu.add(optionNew);
menu_bar.add(menu);
this.setMenuBar(menu_bar);
}
public void resetGame() {
jpanel.removeAll();
arl_field.clear();
arr_btnField = new JButton[int_dim][int_dim];
arr_solution = new int[int_dim][int_dim];
bool_change = false;
bool_won = false;
//arl_field = new ArrayList<Integer>();
for (int i = 0; i < arr_solution.length; i++) {
for (int j = 0; j < arr_solution[i].length; j++) {
arr_solution[i][j] = 1;
}
}
jpanel.setLayout(new GridLayout(0, int_dim));//if(bool_firstround==false)jpanel.setLayout(new GridLayout(0,int_dim));
for (int i = 0; i < arr_btnField.length; i++) {
for (int j = 0; j < arr_btnField[i].length; j++) {
arr_btnField[i][j] = new JButton();////if(bool_firstround==false)arr_btnField[i][j] = new JButton();//arl_field.get(i*int_dim+j)+"");
arr_btnField[i][j].setText("");
arr_btnField[i][j].setBackground(new Color(0X00, 0X94, 0XFF));
arr_btnField[i][j].setBorder(border);
arr_btnField[i][j].setForeground(clr_palette[1]);
arr_btnField[i][j].addMouseListener(listener);
arr_btnField[i][j].setFocusable(false);
jpanel.add(arr_btnField[i][j]);
}
}
jpanel.revalidate();
jpanel.repaint();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MineSweeper();
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
}
});
}
MouseListener listener = new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
outerloop:
for (int i = 0; i < arr_btnField.length; i++) {
for (int j = 0; j < arr_btnField[i].length; j++) {
if (e.getSource() == arr_btnField[i][j]) {
if (SwingUtilities.isLeftMouseButton(e)) {
labelText(i, j);
}
if (SwingUtilities.isRightMouseButton(e)) {
arr_btnField[i][j].setBackground(Color.red);
}
//bool_won=false;
break outerloop;
}
}
}
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
if (bool_won == true)
gameWon();
}
#Override
public void mouseExited(MouseEvent e) {
}
};
public void labelText(int i, int j) {
if (bool_won == false) {
arr_btnField[i][j].setText("1");
arr_btnField[i][j].setBackground(Color.white);
if (arr_btnField[i][j].getBorder() == border) {
int_cellsShown++;
System.out.println("Cells shown: " + int_cellsShown);
if (int_cellsShown >= (int_dim * int_dim - int_mines)) {
bool_won = true;
}
}
if (bool_won == false)
arr_btnField[i][j].setBorder(BorderFactory.createLineBorder(Color.darkGray, 1, true));
}
}
public void gameWon() {
int dialogResult = JOptionPane.showConfirmDialog(null, "You Won! Do you want to start a new game?", "Congratulations!", JOptionPane.YES_NO_OPTION);
if (dialogResult == JOptionPane.YES_OPTION) {
bool_won = false;
int_cellsShown = 0;
resetGame();
}
}
#Override
public void actionPerformed(ActionEvent e) {
int_cellsShown = 0;
int_dim++;
resetGame();
for (int i = 0; i < arr_btnField.length; i++) {
for (int j = 0; j < arr_btnField[i].length; j++) {
arr_btnField[i][j].setBackground(Color.red);
}
}
}
}
Display after the first time:
Display after the second time:
I invoke .revalidate in the fourth line of the method.
That doesn't do anything since there on no components added to the panel. The revalidate() needs to be done AFTER the components have been added.
The displayed panel is not jpanel, the displayed panel is jpanel2, thats why I assign jpanel2 to the value of jpanel in the end of the method.
You can't just change a reference and expect the components to be moved from one panel to another.
The components need to be added to the panel that is added to the GUI.
Edit:
First of all Swing components start with "J". Don't use AWT components (MenuBar, Menu, MenuItem) in a Swing application.
The problem is your LAF:
new MineSweeper();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
The components are created with the current LAF. When you first create the game, the default LAF is used to create all the buttons (and other components). This LAF allows you to change the background color of the buttons.
However, then you change the LAF. So when you reset the game board the buttons are now created with the System LAF. This LAF apparently does not allow you to change the background color of the button.
This should be easy to test. Create a GUI:
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
JButton button = new JButton("testing");
button.setBackground(Color.RED);
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( button );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
First test the code as above to see if the background of the button changes.
Then uncomment the LAF change and retest.
A possible solution so you are not dependent on the LAF is to use an Icon to represent the background color of the button. Then you can center any text on top of the Icon. Something like:
import java.awt.*;
import javax.swing.*;
public class ColorIcon implements Icon
{
private Color color;
private int width;
private int height;
public ColorIcon(Color color, int width, int height)
{
this.color = color;
this.width = width;
this.height = height;
}
public int getIconWidth()
{
return width;
}
public int getIconHeight()
{
return height;
}
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.setColor(color);
g.fillRect(x, y, width, height);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
JPanel panel = new JPanel( new GridLayout(2, 2) );
for (int i = 0; i < 4; i++)
{
Icon icon = new ColorIcon(Color.RED, 50, 50);
JLabel label = new JLabel( icon );
label.setText("" + i);
label.setHorizontalTextPosition(JLabel.CENTER);
label.setVerticalTextPosition(JLabel.CENTER);
panel.add(label);
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(panel);
f.setSize(200, 200);
f.setLocationRelativeTo( null );
f.setVisible(true);
}
}
Yep, I too just noticed, that the problem is here:
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MineSweeper();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
}
});
}
If you comment out the UIManager line, your code works. This line is only valid after the GUI has been created, and so doesn't take effect until new components are created. Note that I was working on minimizing your code to discover this, and was cutting out code to see what caused the problem until this was all that was left.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;
#SuppressWarnings("serial")
public class MineSweeper extends JFrame implements ActionListener {
private static final Color BTN_COLOR = new Color(0X00, 0X94, 0XFF);
int int_dim = 11;
JButton[][] arr_btnField = new JButton[int_dim][int_dim];
JMenuBar menu_bar;
JMenu menu;
JMenuItem optionNew;
JPanel jpanel = new JPanel();
public MineSweeper() {
resetGame();
this.getContentPane().add(jpanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(true);
this.setTitle("Minesweeper");
menu_bar = new JMenuBar();
menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
optionNew = new JMenuItem("Win");
optionNew.setMnemonic(KeyEvent.VK_W);
optionNew.addActionListener(this);
menu.add(optionNew);
menu_bar.add(menu);
this.setJMenuBar(menu_bar);
this.setPreferredSize(new Dimension(500, 500));
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void resetGame() {
jpanel.removeAll();
arr_btnField = new JButton[int_dim][int_dim];
jpanel.setLayout(new GridLayout(0, int_dim));
for (int i = 0; i < arr_btnField.length; i++) {
for (int j = 0; j < arr_btnField[i].length; j++) {
arr_btnField[i][j] = new JButton();
arr_btnField[i][j].setBackground(BTN_COLOR);
jpanel.add(arr_btnField[i][j]);
}
}
jpanel.revalidate();
jpanel.repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
resetGame();
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new MineSweeper();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
}
});
}
}
Hi I have the following code where I have a start and stop button . when start is pressed canvas starts painting but I cannot press stop button until the start operation is done . I need to stop and resume the paint on the button press . Once the start button is pressed the other buttons cannot be pressed till the canvas is painted.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Hashtable;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.Timer;
public abstract class JUIApp extends JPanel implements ActionListener {
public static CACanvas cacanvas= null;
public ArrayList<int[]> genL;
public JFrame frame = null;
protected JPanel mainPanel = null;
private JButton btn0 = null;
private JButton btn1 = null;
private JButton btn2 = null;
#SuppressWarnings("rawtypes")
DefaultComboBoxModel rules = null;
#SuppressWarnings("rawtypes")
JComboBox rulesCombo =null;
JScrollPane ruleListScrollPane=null;
JLabel lable=null;
JTextField generation=null;
JLabel gLable=null;
public static String Rule;
public static String Generations;
public boolean isChanged =false;
public int gridCellSize=4;
private static final long serialVersionUID = 1L;
public int genCurrent=0;
public int posCurrent=0;
public int i;
public Color cellColor= null;
public Timer waitTimer;
public static boolean waitFlag;
public static boolean alert1Flag=false;
public boolean stopFlag=false;
public JLabel Alert1=new JLabel();
public int genCheck=0;
//private List<Point> fillCells;
public JUIApp() {
initGUI();
}
public void initGUI() {
//fillCells = new ArrayList<>(25);
frame = new JFrame();
frame.setTitle("Cellular Automata Demo");
frame.setSize(1050, 610);
frame.setResizable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(getMainPanel(),BorderLayout.NORTH);
frame.setVisible(true);
Toolkit.getDefaultToolkit().setDynamicLayout(false);
cacanvas=new CACanvas();
frame.add(cacanvas);
}
#SuppressWarnings({ "unchecked", "rawtypes" })
public JPanel getMainPanel() {
mainPanel = new JPanel();
mainPanel.setLayout(new FlowLayout());
//cacanvas=new CACanvas();
btn0 = new JButton("Start");
btn0.addActionListener(this);
//waitTimer = new Timer(1000, this);
mainPanel.add(btn0);
JButton btn2 = new JButton("Stop");
btn2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent s)
{
stopFlag=true;
//cacanvas.repaint();
}
});
mainPanel.add(btn2);
btn1 = new JButton("Clear");
btn1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
CACanvas.clearFlag=true;
generation.setText("");
alert1Flag=true;
rulesCombo.setSelectedIndex(0);
Alert1.setText("Please enter the number of generations");
Alert1.setBounds(30, 20, 5, 5);
Alert1.setVisible(alert1Flag);
mainPanel.add(Alert1);
cacanvas.repaint();
frame.setSize(1060, 610);
}
});
mainPanel.add(btn1);
lable=new JLabel();
lable.setText("Select Rule :");
mainPanel.add(lable);
rules=new DefaultComboBoxModel();
for (int i=0;i<=100;i++)
{
String p=String.valueOf(i);
rules.addElement(p);
}
rules.addElement("250");
rules.addElement("254");
rulesCombo = new JComboBox(rules);
rulesCombo.setSelectedIndex(0);
ruleListScrollPane = new JScrollPane(rulesCombo);
mainPanel.add(ruleListScrollPane);
//mainPanel.revalidate();
gLable=new JLabel();
gLable.setText("Enter the number of Generations (Max 64)");
generation=new JTextField(2);
mainPanel.add(gLable);
mainPanel.add(generation);
// mainPanel.add(cacanvas);
return mainPanel;
}
public abstract void run();
#Override
public void actionPerformed(ActionEvent arg0) {
Alert1.setVisible(false);
waitFlag=false;
System.out.println("We received an ActionEvent " + arg0);
Generations=generation.getText();
System.out.println(Generations);
Rule = "";
if (rulesCombo.getSelectedIndex() != -1) {
Rule =
(String) rulesCombo.getItemAt
(rulesCombo.getSelectedIndex());
}
System.out.println(Rule);
int rule=Integer.parseInt(Rule);
Hashtable<String,Integer> rules= new Hashtable<String,Integer>();
CARule ruleClass=new CARule();
rules=ruleClass.setRule(rule);
CAGenetationSet sa =new CAGenetationSet(100, false,rules);
genL=new ArrayList<int[]>();
genL=sa.runSteps(Integer.parseInt(Generations));
System.out.println("calling pattern set");
for(int i=0;i<=genL.size()-1;i++)
{
System.out.println("Painting generation :"+i);
if(stopFlag==false)
{
cacanvas.repaint();
}
//genPaint();
//sleep();
int[] newCell=genL.get(i);
for(int r=0;r<newCell.length;r++)
{
if(newCell[r]==1)
{
System.out.println("Generaton is"+i+"CellLife is"+r);
cacanvas.fillCell(i,r);
}
}
}
/*cacanvas.patternSet(genL);
waitFlag=true;
System.out.println("run completed");
// cacanvas.clearFlag=true;
*/
}
public void genPaint()
{
cacanvas.repaint();
}
public void sleep()
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
JUIApp app = new JUIApp() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Run method");
}
};
}
}
Seems like you are using the current Thread on that task, you should create another Thread and add one listeners code to the new Thread.
I need to make a slot machine that implements thread in java and jframe
this is what iv'e done so far kindly tell me what i need to do in order make the images change per .5 seconds when i press the the play and stop when i press stop. If all the three images are the same it'll say you won. This is what iv'e got so far how will i change this numbers or text to images in jlabel.
public class MySlotNumber extends JFrame{
private MyJLabel x;
private MyJLabel y;
private MyJLabel z;
private JButton btn;
public MySlotNumber(){
super("ABC");
setLayout(new FlowLayout());
Font font = new Font("arial",Font.ITALIC,50);
x = new MyJLabel();
x.setFont(font);
y = new MyJLabel();
y.setFont(font);
z = new MyJLabel();
z.setFont(font);
btn = new JButton("PLAY");
btn.setFont(font);
add(x);
add(y);
add(z);
add(btn);
final Thread thx = new Thread(x);
final Thread thy = new Thread(y);
final Thread thz = new Thread(z);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("PLAY")){
if(thx.isAlive()){
thx.resume();
thy.resume();
thz.resume();
} else {
thx.start();
thy.start();
thz.start();
}
btn.setText("STOP");
} else {
thx.suspend();
thy.suspend();
thz.suspend();
btn.setText("PLAY");
System.out.println(x.getText());
}
}
});
}
- - - - - - --
public class MyJLabel extends JLabel implements Runnable{
private Random r;
private int ctr;
private final int T = 500;
public MyJLabel(){
setText("0");
ctr = 0;
r= new Random();
}
#Override
public void run() {
while(true){
try {
Thread.sleep(T);
} catch (InterruptedException ex) {
Logger.getLogger(MyJLabel.class.getName()).log(Level.SEVERE, null, ex);
}
//ctr++;
ctr = r.nextInt(9)+1;
setText(String.valueOf(ctr));
}
}
}
Here is one way to put a picture on a JLabel and change it when you click a button. (I am using window builder for eclipse, so it may look a little odd.) It is not recommended you use absolute paths because when you move your project or the file, it breaks (I did this just for proof of concept).
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Test {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Test window = new Test();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Test() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 1379, 643);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setIcon(new ImageIcon("C:\\Users\\Andrew\\Pictures\\Random Pictures\\Capture.JPG"));
frame.getContentPane().add(lblNewLabel, BorderLayout.CENTER);
JButton btnClickMe = new JButton("click me");
btnClickMe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
lblNewLabel.setIcon(new ImageIcon("C:\\Users\\Andrew\\Pictures\\Random Pictures\\I'm pretty sure he did.JPG"));
}
});
frame.getContentPane().add(btnClickMe, BorderLayout.EAST);
}
}
First Time three random images shown on Jframe from three diffrent arrays.
even MouseClicked Method triggered but images does not refresh in Frame.
I want to refresh three random images each time i click on Frame.
Please help
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.*;
public class Cards extends JFrame implements MouseListener {
public static void main(String[] args) {
JFrame frame = new Cards();
frame.setTitle("Cards");
frame.setSize(500, 500);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
new Cards();
}
public Cards() {
this.getContentPane().addMouseListener(this);
cards1();
cards2();
cards3();
}
public void cards1() {
ImageIcon[] images = new ImageIcon[10];
for (int i = 1; i < images.length; i++) {
images[i] = new ImageIcon("Drawables//Images//" + i + ".png");
}
int[] threeRandoms = new int[1];
Random ran = new Random();
for (int i = 0; i < threeRandoms.length; i++) {
threeRandoms[i] = ran.nextInt(10);
}
setLayout(new GridLayout(1, 4, 5, 5));
add(new JLabel(images[threeRandoms[0]]));
}
public void cards2() {
ImageIcon[] images = new ImageIcon[10];
for (int i = 1; i < images.length; i++) {
images[i] = new ImageIcon("Drawables//Images1//" + i + ".png");
}
int[] threeRandoms = new int[1];
Random ran = new Random();
for (int i = 0; i < threeRandoms.length; i++) {
threeRandoms[i] = ran.nextInt(10);
}
setLayout(new GridLayout(1, 4, 5, 5));
add(new JLabel(images[threeRandoms[0]]));
}
public void cards3() {
// this.getContentPane().addMouseListener(this);
ImageIcon[] images = new ImageIcon[10];
for (int i = 1; i < images.length; i++) {
images[i] = new ImageIcon("Drawables//Images2//" + i + ".png");
}
int[] threeRandoms = new int[1];
Random ran = new Random();
for (int i = 0; i < threeRandoms.length; i++) {
threeRandoms[i] = ran.nextInt(10);
}
// Labels with gridLayout
setLayout(new GridLayout(1, 4, 5, 5));
add(new JLabel(images[threeRandoms[0]]));
}
public void mouseClicked(MouseEvent e) {
System.out.println("The frame was clicked.");
new Cards();
}
public void mouseEntered(MouseEvent e) {
System.out.println("The mouse entered the frame.");
}
public void mouseExited(MouseEvent e) {
System.out.println("The mouse exited the frame.");
}
public void mousePressed(MouseEvent e) {
System.out.println("The left mouse button was pressed.");
}
public void mouseReleased(MouseEvent e) {
System.out.println("The left mouse button was released.");
}
}
I'm sorry, but I'm confused by your code. For one thing your cards1(), cards2() and cards3() methods look to be all the very same, and if so, why 3 different methods? Why not just one method? In those methods you appear to be trying to add JLabels repeatedly. Are you trying to add many many JLabels to the GUI? Or are you simply trying to display 3 images that change randomly on mouse action?
I would recommend structuring things a bit differently:
If possible, read all necessary images in once in your class's constructor, put the images into ImageIcons and then add them to an ArrayList or several ArrayLists if need be.
Don't add new JLabels each time a mouseClick occurs.
Create a JPanel give it a GridLayout and in your class constructor add to it three JLabels that are either instance fields or in an array or ArrayList.
Add this JPanel to your JFrame.
Add a MouseListener to each JLabel
in that MouseListener's mousePressed(MouseEvent e) method (not mouseClicked) randomize your number and use that number to call setIcon(...) on the JLabel source, obtained by calling getSource() on your MouseEvent parameter.
For example:
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class RandomImages extends JPanel {
private static final int LABEL_COUNT = 3;
private Random random = new Random();
public RandomImages() {
setLayout(new GridLayout(1, 3));
for (int i = 0; i < LABEL_COUNT; i++) {
final List<Icon> iconList = new ArrayList<>();
// TODO: get images for the ith list
// and fill iconList with ImageIcons from the first grouping
// create JLabel and give it the first Icon from the List above
final JLabel label = new JLabel(iconList.get(0));
label.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
// get random number from random object using iconList.size()
// get random Icon from list
// set label's icon via setIcon(...)
}
});
// add to GUI
add(label);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("RandomImages");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new RandomImages());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Concrete example 2:
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class RandomChessMen extends JPanel {
// for this example I get a sprite sheet that holds several sprite images in it
// the images can be found here: http://stackoverflow.com/questions/19209650
private static final String IMAGE_PATH = "http://i.stack.imgur.com/memI0.png";
private static final int LABEL_COUNT = 2;
private static final int ICON_COLUMNS = 6;
private Random random = new Random();
public RandomChessMen() throws IOException {
URL url = new URL(IMAGE_PATH);
BufferedImage largeImg = ImageIO.read(url);
setLayout(new GridLayout(1, 0));
// break down large image into its constituent sprites and place into ArrayList<Icon>
int w = largeImg.getWidth() / ICON_COLUMNS;
int h = largeImg.getHeight() / LABEL_COUNT;
for (int i = 0; i < LABEL_COUNT; i++) {
final List<Icon> iconList = new ArrayList<>();
int y = (i * largeImg.getHeight()) / LABEL_COUNT;
// get 6 icons out of large image
for (int j = 0; j < ICON_COLUMNS; j++) {
int x = (j * largeImg.getWidth()) / ICON_COLUMNS;
// get subImage
BufferedImage subImg = largeImg.getSubimage(x, y, w, h);
// create ImageIcon and add to list
iconList.add(new ImageIcon(subImg));
}
// create JLabel
final JLabel label = new JLabel("", SwingConstants.CENTER);
int eb = 40;
label.setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
// get random index for iconList
int randomIndex = random.nextInt(iconList.size());
Icon icon = iconList.get(randomIndex); // use index to get random Icon
label.setIcon(icon); // set label's icon
label.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
Icon secondIcon = label.getIcon();
// so we don't repeat icons
while (label.getIcon() == secondIcon) {
int randomIndex = random.nextInt(iconList.size());
secondIcon = iconList.get(randomIndex);
}
label.setIcon(secondIcon);
}
});
// add to GUI
add(label);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("RandomImages");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
frame.getContentPane().add(new RandomChessMen());
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I have made these changes to your code:
Instead of having three methods cards1() cards2() cards3(), i have just made one cards() method.
Everytime you click on the frame, three random images get loaded.
I have set every image inside a JLabel in order to make it easy to update it.
The code below works perfectly according to your needs.
package example;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
public class Cards extends JFrame implements MouseListener {
JPanel subPanel1;
JLabel label1, label2, label3;
static ImageIcon[] images ;
static Random ran ;
static int[] threeRandoms;
public Cards() {
super("Cards");
subPanel1 = new JPanel();
// Set up first subpanel
subPanel1.setPreferredSize (new Dimension(400, 400));
//subPanel1.setBackground (Color.cyan);
label1 = new JLabel ("image 1",SwingConstants.CENTER);
label2 = new JLabel ("image 2", SwingConstants.LEFT);
label3 = new JLabel ("image 3", SwingConstants.CENTER);
subPanel1.add (label1);
subPanel1.add (label2);
subPanel1.add (label3);
add(subPanel1);
addMouseListener(this);
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
System.out.println("Success.....");
}
public void cards() {
for (int i = 0; i < threeRandoms.length; i++)
threeRandoms[i] = ran.nextInt(3);
label1.setIcon(images[threeRandoms[0]]);
label2.setIcon(images[threeRandoms[1]]);
label3.setIcon(images[threeRandoms[2]]);
}
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked");
cards();
}
#Override
public void mouseEntered(MouseEvent e) {
System.out.println("mouseEntered");
}
#Override
public void mouseExited(MouseEvent e) {
System.out.println("mouseExited");
}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("mousePressed");
}
#Override
public void mouseReleased(MouseEvent e) {
System.out.println("mouseReleased");
}
public static void loadImages(){
images = new ImageIcon[4];
ran = new Random();
threeRandoms = new int[3];
for (int i = 1; i <= images.length; i++) {
images[i-1] = new ImageIcon("Drawables//Images//" + i + ".png");
}
}
public static void main(String[] args) {
loadImages();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Cards();
}
});
}
}