I have an array of JLabels[7] and I filled all JLabels with same image and added them to a JPanel.
When I click on a JLabel position(e.g I click on JLabel[5]) the console will print out "you have clicked JLabel 5" and change the JLabel image from imageOne to imageTwo.
I realized something about my codes which is after I clicked on a JLabel (e.g I click on JLabel[5]), the image changes from imageOne to imageTwo and the console print out "you have clicked JLabel 5" but if I clicked again and again on JLabel[5], the program will not detect my mouse click event and the console will not print out "you have clicked JLabel 5".
How do I make it such a way that after image has changed on the first click on a JLabel, it will still contiune and detect no mater how many times I clicked on the same JLabel again?.
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class LearningSwing {
public Image imageOne() {
BufferedImage img = null;
try {
img = ImageIO.read(new File("imageOne.jpg"));
} catch (Exception e) {
}
return img;
}
public Image imageTwo() {
BufferedImage img = null;
try {
img = ImageIO.read(new File("imageTwo.jpg"));
} catch (Exception e) {
}
return img;
}
public static void main(String[] args) {
final JLabel[] jLabelArr = new JLabel[7];
final JPanel jPanel = new JPanel(new FlowLayout());
JFrame frame = new JFrame();
final LearningSwing learningSwing = new LearningSwing();
for(int i = 0; i< 7; i++) {
jLabelArr[i] = new JLabel(new ImageIcon(learningSwing.imageOne()));
jPanel.add(jLabelArr[i]);
jLabelArr[i].addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
for(int i = 0; i < 7; i ++) {
if(e.getSource() == jLabelArr[i]) {
System.out.println("You clicked on JLabel" + i);
jPanel.remove(i);
jLabelArr[i] = new JLabel(new ImageIcon(learningSwing.imageTwo()));
jPanel.add(jLabelArr[i],i);
jPanel.revalidate();
jPanel.repaint();
}
}
}
});
}
frame.add(jPanel);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setSize(400,600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
In your code you are removing the old JLabel when the listener invokes mouseClicked, and you are recreating it again with the new image. This causes the JLabel to lose the listener.
You could instead change the image of the label as follows:
#Override
public void mouseClicked(MouseEvent e) {
for (int i = 0; i < 7; i++) {
if (e.getSource() == jLabelArr[i]) {
System.out.println("You clicked on JLabel" + i);
jLabelArr[i].setIcon(new ImageIcon(learningSwing.imageTwo()));
}
}
}
No, you don't need to re-add any listeners. You need to not swap JLabels. Instead, keep your JLabels where they are and just swap ImageIcons. The key here is this: don't make things more difficult for yourself.
e.g.,
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class LearningSwing2 extends JPanel {
private static final String[] IMAGE_PATHS = {"imageOne.jpg", "imageTwo.jpg"};
private static final int LABEL_COUNT = 7;
private List<Icon> icons = new ArrayList<>();
private JLabel[] imageLabels = new JLabel[LABEL_COUNT];
public LearningSwing2() throws IOException {
for (String imagePath : IMAGE_PATHS) {
BufferedImage img = ImageIO.read(new File(imagePath));
icons.add(new ImageIcon(img));
}
for (int i = 0; i < imageLabels.length; i++) {
imageLabels[i] = new JLabel(icons.get(0));
imageLabels[i].addMouseListener(new LabelListener());
}
}
private class LabelListener extends MouseAdapter {
#Override
public void mousePressed(MouseEvent mEvt) {
JLabel label = (JLabel) mEvt.getSource();
for (int i = 0; i < imageLabels.length; i++) {
if (label == imageLabels[i]) {
System.out.println("You pressed image label " + i);
}
}
label.setIcon(icons.get(1));
}
}
private static void createAndShowGui() {
LearningSwing2 mainPanel;
try {
mainPanel = new LearningSwing2();
JFrame frame = new JFrame("LearningSwing2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Related
I got this code witch creates a clickable grid that shows the mouse position, altough i am not able to get the position in the grid in where the mouse is clicked, trying to be both X and Y position. Any ideas? This is how the grid looks:
Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
public class TestGrid02 {
public TestGrid02() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private static final int ROWS = 20;
private static final int COLUMNS = 20;
private static GridBagConstraints gbc;
public TestPane() {
setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
for (int row = 0; row < ROWS; row++) {
for (int col = 0; col < COLUMNS; col++) {
gbc.gridx = col;
gbc.gridy = row;
CellPane cellPane = new CellPane();
Border border = null;
if (row < ROWS-1) {
if (col < COLUMNS-1) {
border = new MatteBorder(1, 1, 0, 0, Color.GRAY);
} else {
border = new MatteBorder(1, 1, 0, 1, Color.GRAY);
}
} else {
border = new MatteBorder(1, 1, 1, 0, Color.GRAY);
}
cellPane.setBorder(border);
add(cellPane, gbc);
}
}
}
}
public class CellPane extends JPanel {
private Color defaultBackground;
public CellPane() {
addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
defaultBackground = getBackground();
setBackground(Color.RED);
}
#Override
public void mouseExited(MouseEvent e) {
setBackground(defaultBackground);
}
#Override
public void mouseClicked(MouseEvent e){
//Here is where it is supposed to be
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(30, 30);
}
}
}
In the CellPane class, witch is intended to be the one that listens to the mouse it is supposed to be the function that i need, at the mouseClicked listener, however i have tried with e.getX() or e.getLocationOnScreen() and these values were changing everytime i click in the same grid.
Well, that looks familiar 🤣
So, the basic idea would be to pass in the cell it's coordinates (ie, row/column) value via the constructor, for example...
public class CellPane extends JPanel {
private Color defaultBackground;
private Point cellCoordinate;
public CellPane(Point cellCoordinate) {
this.cellCoordinate = cellCoordinate;
addMouseListener(new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
defaultBackground = getBackground();
setBackground(Color.RED);
}
#Override
public void mouseExited(MouseEvent e) {
setBackground(defaultBackground);
}
#Override
public void mouseClicked(MouseEvent e) {
//Here is where it is supposed to be
System.out.println("Did click cell # " + getCellCoordinate().x + "x" + getCellCoordinate().y);
}
});
}
public Point getCellCoordinate() {
return cellCoordinate;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(30, 30);
}
}
The cell itself doesn't really care, not does it have any reasonable information available to it to determine how it's been laid out, so your best bet is to "tell" it the information you want it to represent.
For me, I'd just pass in the GridBagLayout row/col information, for example...
gbc.gridx = col;
gbc.gridy = row;
CellPane cellPane = new CellPane(new Point(col, row));
This way you remove all concept (and the issues associated with it) of how the cell is laid out
This approach (using buttons and action listeners) is better IMO. It uses the getButtonRowCol method to return a string indicating the button's location in an array (the buttonArray).
Use b.setBorderPainted(false); (uncomment that code line) to get rid of the borders around each button. Look to the values passed to the constructor of the GridLayout to remove the space between buttons.
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
public class GameGridLayout {
int size = 40;
int iconSize = 10;
JButton[][] buttonArray = new JButton[size][size];
ActionListener actionListener;
JLabel output = new JLabel("Click somewhere on the GUI");
GameGridLayout() {
JPanel gui = new JPanel(new BorderLayout(2,2));
gui.setBorder(new EmptyBorder(4,4,4,4));
gui.add(output,BorderLayout.PAGE_END);
JPanel gameContainer = new JPanel(new GridLayout(0,size,2,2));
gui.add(gameContainer);
actionListener = e -> output.setText(getButtonRowCol((JButton)e.getSource()));
for (int ii=0; ii<size*size; ii++) {
JButton b = getButton();
gameContainer.add(b);
buttonArray[ii%size][ii/size] = b;
}
JFrame f = new JFrame("GameGridLayout");
f.add(gui);
f.pack();
f.setMinimumSize(f.getSize());
f.setLocationByPlatform(true);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
private String getButtonRowCol(JButton button) {
StringBuilder sb = new StringBuilder();
for (int xx=0; xx<size; xx++) {
for (int yy=0; yy<size; yy++) {
if (button.equals(buttonArray[xx][yy])) {
sb.append("User selected button at: ");
sb.append(xx+1);
sb.append(",");
sb.append(yy+1);
break;
}
}
}
return sb.toString();
}
private JButton getButton() {
JButton b = new JButton();
b.setIcon(new ImageIcon(
new BufferedImage(iconSize,iconSize,BufferedImage.TYPE_INT_ARGB)));
b.setRolloverIcon(new ImageIcon(
new BufferedImage(iconSize,iconSize,BufferedImage.TYPE_INT_RGB)));
b.setMargin(new Insets(0,0,0,0));
//b.setBorderPainted(false);
b.setContentAreaFilled(false);
b.addActionListener(actionListener);
return b;
}
public static void main(String[] args) {
Runnable r = () -> new GameGridLayout();
SwingUtilities.invokeLater(r);
}
}
I have created a 3x3 memory game with colors. The program runs and displays the colors, but the JMenuBar is not working correctly. The button new board, play and end game are not working. Is there something wrong with my Actionlistener?
This is how the code should be working : https://gyazo.com/9bf3e073a9c455e56d9b4403586bfaf5?fbclid=IwAR3Zk1BZvRj49CtAz01h95zic8tk74UmyUcU2HrY3VY8XcARoD14Ke6tcoQ
This is StartPlayer
import gui.MemoryGameWindow;
import gui.ColoredPanel;
import gui.GamePanel;
public class StartPlayer {
public static void main(String[] args) {
new MemoryGameWindow();
}
}
This is ColoredPanel
package gui;
import java.awt.Color;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
public class ColoredPanel extends JPanel {
private Color thisColor = null;
private Color challenge = null;
public ColoredPanel(Color color) {
this.thisColor = color;
setBackground(color);
}
public void setGameMode(Color c, MouseListener ml) {
setBackground(Color.LIGHT_GRAY);
this.challenge = c;
System.out.println("Coloredpanel says challenge is " + this.challenge);
addMouseListener(ml);
}
public void restoreBackground() {
setBackground(this.thisColor);
}
}
This is GamePanel
package gui;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GamePanel extends JPanel {
private Color[] colors = new Color[] { Color.GREEN, Color.YELLOW, Color.MAGENTA };
private Random r = new Random();
private int square = 9;
private Color challenge;
private int countOfPossibleHits = 0;
private int countOfWinnerHits = 0;
private JPanel challengeDisplay;
public GamePanel(JPanel cd) {
this.challengeDisplay = cd;
setLayout(new GridLayout(3, 0, 2, 2));
for (int i = 0; i < this.square; i++)
add(new ColoredPanel(this.colors[this.r.nextInt(this.colors.length)]));
}
public Color startGame() {
Color[] existingColors = new Color[getComponentCount()];
int i;
for (i = 0; i < getComponentCount(); i++)
existingColors[i] = ((ColoredPanel)getComponent(i)).getBackground();
this.challenge = existingColors[this.r.nextInt(existingColors.length)];
this.countOfPossibleHits = 0;
for (i = 0; i < getComponentCount(); i++) {
if (((ColoredPanel)getComponent(i)).getBackground() == this.challenge)
this.countOfPossibleHits++;
}
for (i = 0; i < getComponentCount(); i++)
((ColoredPanel)getComponent(i)).setGameMode(this.challenge, new TheMouselistener());
return this.challenge;
}
class TheMouselistener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
ColoredPanel clickedObject = (ColoredPanel)e.getSource();
clickedObject.restoreBackground();
if (clickedObject.getBackground() != GamePanel.this.challenge) {
clickedObject.add(new JLabel("Game Over!"));
GamePanel.this.challengeDisplay.add(new JLabel("Game Over!"));
System.out.println("Game Over");
GamePanel.this.updateUI();
} else {
GamePanel.this.countOfWinnerHits = GamePanel.this.countOfWinnerHits + 1;
if (GamePanel.this.countOfWinnerHits == GamePanel.this.countOfPossibleHits) {
clickedObject.add(new JLabel("You won!"));
GamePanel.this.challengeDisplay.add(new JLabel("You Won!"));
GamePanel.this.updateUI();
}
}
}
}
}
This is MemoryGameWindow
package gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class MemoryGameWindow extends JFrame implements ActionListener {
private JMenuItem newgame = null;
private JMenuItem playgame = null;
private JMenuItem exit = null;
private GamePanel gamepanel = null;
private JPanel challengeDisplay;
public MemoryGameWindow() {
setTitle("memory game");
setLayout(new BorderLayout(5, 5));
add(this.challengeDisplay = new JPanel() {
}, "North");
add(this.gamepanel = new GamePanel(this.challengeDisplay));
setJMenuBar(new GameMenubar(this));
setSize(600, 600);
setLocationRelativeTo((Component)null);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
Object s = e.getSource();
if (s == this.newgame) {
remove(this.gamepanel);
remove(this.challengeDisplay);
add(this.challengeDisplay = new JPanel() {
}, "North");
add(this.gamepanel = new GamePanel(this.challengeDisplay));
this.playgame.setEnabled(true);
this.gamepanel.updateUI();
}
if (s == this.playgame) {
Color challenge = this.gamepanel.startGame();
this.challengeDisplay.setBackground(challenge);
this.playgame.setEnabled(false);
this.gamepanel.updateUI();
}
if (s == this.exit)
System.exit(0);
}
class GameMenubar extends JMenuBar {
public GameMenubar(MemoryGameWindow memoryGameWindow) {
JMenu file;
add(file = new JMenu("File"));
MemoryGameWindow.this.newgame = new JMenuItem("new board");
file.add(new JMenuItem("new board"));
MemoryGameWindow.this.playgame = new JMenuItem("play");
file.add(new JMenuItem("play"));
MemoryGameWindow.this.exit = new JMenuItem("end program");
file.add(new JMenuItem("end program"));
MemoryGameWindow.this.newgame.addActionListener(memoryGameWindow);
MemoryGameWindow.this.playgame.addActionListener(memoryGameWindow);
MemoryGameWindow.this.exit.addActionListener(memoryGameWindow);
}
}
}
Have a look at these two lines:
MemoryGameWindow.this.playgame = new JMenuItem("play");
file.add(new JMenuItem("play"));
First, you set the value of playgame to new JMenuItem. Later in the code, you add an ActionListener to it. That is all correct.
The problem is, the JMenuItem with the ActionListener added to it is not what you’re adding to the menu bar. Instead, you’re adding a brand new JMenuItem, which has no ActionListeners added to it.
The fix is as simple as:
file.add(MemoryGameWindow.this.playgame);
Obviously, you will need to do this for your other menu items too.
Hello and thanks for your assistance in advance.
My goal is to load a directory called resource to create an array. After doing that the program should use a "Next" and "Previous" button to cycle both forwards and backwards through the array by using a counter. Cycling through the array should display the appropriate picture (without knowing what the picture is, just the order that it is in the array).
My code this far:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.BoxLayout;
import javax.swing.JTextField;
import java.io.IOException;
import javax.swing.ImageIcon;
import java.io.*;
import java.util.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.awt.*;
import java.awt.event.*;
public class viewer extends JFrame implements ActionListener
{
int counter = 0; //Initial counter value
int maxItems = 0; // Set it equal to the length of the array
int minItems = 0; //Minimum items for previous button
JPanel botPanel = null;
JPanel midPanel = null;
JLabel midLabel = null;
ImageIcon image;
String[] picture = new String [1000];
public viewer()
{
setTitle ("Roberts Viewer");
setSize (1000, 1000);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Allow the X button to close the program and not just the frame
JPanel midPanel = new JPanel ();
JPanel botPanel = new JPanel ();
midLabel = new JLabel();
JButton prv = new JButton("Previous"); botPanel.add(prv); prv.addActionListener(this);
JButton nxt = new JButton("Next"); botPanel.add(nxt); nxt.addActionListener(this);
JButton quitButton = new JButton ("Quit Program"); botPanel.add(quitButton); quitButton.addActionListener(this);
add(midPanel, BorderLayout.CENTER);
add(botPanel, BorderLayout.SOUTH);
File dir = new File ("resource");
File[] picture = dir.listFiles();
for (int maxItems = 0;maxItems < picture.length; maxItems++);
midPanel.add(midLabel);
setVisible(true);
}
public static void main(String[] args)
{
viewer v = new viewer();
}
public void actionPerformed (ActionEvent e)
{
String action = e.getActionCommand();
if (action.equals("Quit Program"))
{
System.exit(0);
}
if(action.equals("Next"))
{
if (counter < 0){counter = 0;}
if (counter> maxItems) {counter = 0;}
String pictureString = String.format("resource/%s", picture[counter]);
System.out.printf("Retrieving[%s]\n",pictureString);
try
{
image = new ImageIcon(getClass().getClassLoader().getResource(pictureString));
}
catch (Exception xu)
{
System.out.println("Woops");
}
midLabel.setIcon(image);
counter++;
}
if(action.equals("Previous"))
{
if (counter < 0) {counter = maxItems;}
if (counter < minItems) {counter = maxItems;}
String pictureString = String.format("resource/%s",picture[counter]);
System.out.printf("Retrieving[%s]\n", pictureString);
try
{
image = new ImageIcon(getClass().getClassLoader().getResource(pictureString));
}
catch (Exception xu)
{
System.out.println("Woops");
}
midLabel.setIcon(image);
counter--;
}
}
}
The problem was solved. I had some bugs but here is the fixed code.
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.BoxLayout;
import javax.swing.JTextField;
import java.io.IOException;
import javax.swing.ImageIcon;
import java.io.*;
import java.util.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.awt.*;
import java.awt.event.*;
public class viewer extends JFrame implements ActionListener
{
int counter = 0; //Initial counter value
int maxItems = 0; // Set it equal to the length of the array
int minItems = 0; //Minimum items for previous button
JPanel botPanel = null;
JPanel midPanel = null;
JLabel midLabel = null;
ImageIcon image;
File[] picture;
public viewer()
{
setTitle ("Roberts Viewer");
setSize (500, 500);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel midPanel = new JPanel ();
JPanel botPanel = new JPanel ();
midLabel = new JLabel();
JButton prv = new JButton("Previous"); botPanel.add(prv); prv.addActionListener(this);
JButton nxt = new JButton("Next"); botPanel.add(nxt); nxt.addActionListener(this);
JButton quitButton = new JButton ("Quit Program"); botPanel.add(quitButton); quitButton.addActionListener(this);
add(midPanel, BorderLayout.CENTER);
add(botPanel, BorderLayout.SOUTH);
File dir = new File ("resource");
picture = dir.listFiles();
midPanel.add(midLabel);
image = new ImageIcon("resource/"+picture [0].getName());
midLabel.setIcon(image);
setVisible(true);
}
public static void main(String[] args)
{
viewer v = new viewer();
}
public void actionPerformed (ActionEvent e)
{
String action = e.getActionCommand();
if (action.equals("Quit Program"))
{
System.exit(0);
}
if(action.equals("Next"))
{
counter++;
if (counter>= picture.length) {counter = 0;}
try
{
image = new ImageIcon("resource/"+picture[counter].getName());
midLabel.setIcon(image);
}
catch (Exception xu)
{
System.out.println("Woops");
}
System.out.printf("Exit next: " + counter + "\n");
}
if(action.equals("Previous"))
{
counter--;
if (counter < 0) {counter = picture.length-1;}
String.format("resource/%s",picture[counter].getName());
try
{
image = new ImageIcon("resource/"+picture[counter].getName());
midLabel.setIcon(image);
}
catch (Exception xu)
{
System.out.println("Woops");
}
System.out.printf("Exit prev: " + counter + "\n");
}
}
}
I have a JLabel[10] and I want to detect which label has been clicked and print which label of the label that has been clicked.
I created a JLabel array of 10.
Wrote a for loop to place an Image to every position of the label.
Added a MouseListener to check which label has been clicked.
The problem is I can't do this to get the source of my jLabelArr. The program will ask me to change my it to final.
if(e.getSource() == jLabelArr[i])
Full code
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class JavaLabels extends JFrame {
private JLabel[] jLabelArr;
private JPanel jLabelPanel = new JPanel();
public JavaLabels() {
setLayout(new FlowLayout());
jLabelArr = new JLabel[10];
for(int i =0; i < 10; i++) {
jLabelArr[i] = new JLabel(new ImageIcon("resources/image"));
jLabelPanel.add(jLabelArr[i]);
jLabelArr[i].addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if(e.getSource() == jLabelArr[i]) {
System.out.println("Label" + i + "was clicked");
}
}
});
}
add(jLabelPanel);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
pack();
setSize(400,600);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new JavaLabels();
}
}
For what you wanted there's nothing more than create a final int variable that will equal to the position of the for cycle
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class JavaLabels extends JFrame {
private JLabel[] jLabelArr;
private JPanel jLabelPanel = new JPanel();
public JavaLabels() {
setLayout(new FlowLayout());
jLabelArr = new JLabel[10];
for(int i =0; i < 10; i++) {
jLabelArr[i] = new JLabel(new ImageIcon("resources/image"));
jLabelPanel.add(jLabelArr[i]);
final int p = i;
jLabelArr[i].addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("Label" + p + "was clicked");
}
});
}
add(jLabelPanel);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
pack();
setSize(400,600);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new JavaLabels().setVisible(true);
}
}
-> if(e.getSource() == jLabelArr[i]) is not needed in this case
1
public class JavaLabels extends JFrame {
private JLabel[] jLabelArr;
private JPanel jLabelPanel = new JPanel();
public JavaLabels() {
setLayout(new FlowLayout());
jLabelArr = new JLabel[10];
for (int i = 0; i < 10; i++) {
jLabelArr[i] = new JLabel(new ImageIcon("resources/image"));
jLabelPanel.add(jLabelArr[i]);
jLabelArr[i].addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
onMouseClicked(e);
}
});
}
add(jLabelPanel);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
pack();
setSize(400, 600);
setLocationRelativeTo(null);
setVisible(true);
}
private void onMouseClicked(MouseEvent e) {
for (int i = 0; i < 10; i++)
if (e.getSource() == jLabelArr[i]) {
System.out.println("Label" + i + "was clicked");
}
}
public static void main(String[] args) {
new JavaLabels();
}
}
2
Implement MouseListener to JavaLabels class and jLabelArr[i].addMouseListener(this);
I'm working on a school project where we have to create a virtual smartphone, to run on a computer.
My problem is that I need to create a keyboard on the screen (like on an smartphone), which you can then use by clicking with your mouse. I could just create every single JButton, but that will take a really long time. So I was hopping that someone knew some sort of algorithm that creates all the buttons and places them correctly on the screen.
Thank you in advance :)
You could construct the buttons through the use of for loops. One loop for every keyboard row is a plausible approach.
String row1 = "1234567890";
String row2 = "qwertyuiop";
// and so forth
String[] rows = { row1, row2, .. };
for (int i = 0; i < rows.length; i++) {
char[] keys = rows[i].toCharArray();
for (int j = 0; i < keys.length; j++) {
JButton button = new JButton(Character.toString(keys[j]));
// add button
}
}
// add special buttons like space bar
This could be done more elegantly through a more OOP approach, but this basic loop system will work.
This simple example might help you:
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class MainFrame extends JFrame
{
private JTextField txt;
private PopUpKeyboard keyboard;
public MainFrame()
{
super("pop-up keyboard");
setDefaultCloseOperation(EXIT_ON_CLOSE);
txt = new JTextField(20);
keyboard = new PopUpKeyboard(txt);
txt.addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent e)
{
Point p = txt.getLocationOnScreen();
p.y += 30;
keyboard.setLocation(p);
keyboard.setVisible(true);
}
});
setLayout(new FlowLayout());
add(txt);
pack();
setLocationByPlatform(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new MainFrame().setVisible(true);
}
});
}
private class PopUpKeyboard extends JDialog implements ActionListener
{
private JTextField txt;
public PopUpKeyboard(JTextField txt)
{
this.txt = txt;
setLayout(new GridLayout(3, 3));
for(int i = 1; i <= 9; i++) createButton(Integer.toString(i));
pack();
}
private void createButton(String label)
{
JButton btn = new JButton(label);
btn.addActionListener(this);
btn.setFocusPainted(false);
btn.setPreferredSize(new Dimension(100, 100));
Font font = btn.getFont();
float size = font.getSize() + 15.0f;
btn.setFont(font.deriveFont(size));
add(btn);
}
#Override
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
txt.setText(txt.getText() + actionCommand);
}
}
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String alphabet = "abcdefghijklmnopqrstuvwxyz";
JFrame myFrame = new JFrame();
JPanel myPanel = new JPanel();
for (int i = 0; i < alphabet.length(); i++) {
myPanel.add(new JButton(alphabet.substring(i, i + 1)));
}
myFrame.add(myPanel);
myFrame.pack();
myFrame.setVisible(true);
}
This is a fast example of how to do it :).