I've created a JPanel[][] Array.
private JPanel[][] pnlFeld;
And filled it with panels
for (int i = 0; i < world.getSize(); i++) {
for (int j = 0; j < world.getSize(); j++) {
pnlFeld[i][j] = new JPanel();
pnlFeld[i][j].setBorder(new EtchedBorder());
pnlFeld[i][j].addMouseListener(ml);
pnlFeld[i][j].setBackground(off);
add(pnlFeld[i][j]);
}
}
Now I want to get the array coordinates ([][]) by clicking on them and I have no clue how to do that.
I've only added methods to change the color of the panel I clicked on, nothing related to my problem.
MouseListener ml = new MouseListener() {
#Override
public void mouseEntered(MouseEvent e) {
if (world.getMode().equals("Malen")) {
if (e.getSource() instanceof JPanel)
e.getComponent().setBackground(on);
// check();
}
else if (world.getMode().equals("Radieren")) {
if (e.getSource() instanceof JPanel)
e.getComponent().setBackground(off);
// check();
}
}
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
if (world.getMode().equals("Setzen")) {
if (e.getSource() instanceof JPanel) {
if (e.getComponent().getBackground() == off) {
e.getComponent().setBackground(on);
} else
e.getComponent().setBackground(off);
}
// check();
}
}
}
#Override
public void mouseClicked(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
};
Actually you can use getBounds() to get component location and size. If you mean the array indexes there could be multiple solutions.
Define a Map and place all your panels in the Map with String value e.g. i+":"+j (or define simple pojo class with 2 fields i and j.
Create unique listener for each JPanel to keep the i and j.
Place the panels in a containr with GridBagLayout then you can use gridBagLayoutInstance.getConstraints(theClickedPanel) and check row column of the constraint
Getting JPanel[][] coordinates by clicking on a JPanel
Use a JButton[][] with ActionListener for easier coding and a better user experience. The ActionEvent has a getSource() method that will identify the button that was activated.
This chess GUI uses buttons for the 64 places on the chessboard.
If you create your MouseListener in your loop, you can use i en j within the code of your listener. The drawback is that you'll have a bit more instances of your listener.
I could suggest that you set the name of each JPanel as i and j in the loop where you declare and initialise the panels. As illustrated
pnlFeld[i][j].setName(i + "" + j);
And in your mouseClicked event check if the event source is an instance of JPanel and parse the name to get the x and y coordinates like this:
Integer.parseInt(p.getName().subString(0,1))
Integer.parseInt(p.getName().subString(1));
Related
I want to build a bingo got the following source code, which should create a JFrame with 25 buttons placed in a 5x5 matrix. But none of my button gets drawn on the window in any kind.
I ve created a Jpanel on which the buttons are placed, the locations and such are not specific, finetuning will come later, first thing is to even get them drawn on the window.
Bingo Buttons is a class which extends JFrame and simply adds two methods, one to toggle its status from true to false and the other way around and also an method (isSet) to check if the buttons is currently true or false.
bingoField is an String Array which holds nothing but the data which the buttons should get.
I dont get why it does nothing, please help me out. Any kind of help is highly appreciated!
public class BingoFrame extends JFrame {
public static final int BINGOSIZE=25;
public static final int BUTTON_X=50;
public static final int BUTTON_Y=50;
public BingoFrame() {
setResizable(false);
String[] bingoField = null;
BingoButton[] buttons=new BingoButton[25];
try {
bingoField = Utils.getRandomBingoField("Test");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
this.setTitle("BS Bingo");
this.setResizable(false);
this.setLocation(50, 50);
this.setSize(600, 800);
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
JPanel buttonPanel = new JPanel();
buttonPanel.setBounds(0, 0, 594, 772);
getContentPane().add(buttonPanel);
buttonPanel.setLayout(null);
for(int i=0;i<BINGOSIZE;i++) {
buttons[i] = new BingoButton("Text");
}
//decorate buttons and add an action listener
for(int i=0;i<BINGOSIZE;i++) {
final BingoButton temp = buttons[i];
temp.setText(bingoField[i]);
temp.setBackground(Color.white);
temp.setForeground(Color.blue);
temp.setPreferredSize(new Dimension(BUTTON_X,BUTTON_Y));
temp.addActionListener(new ActionListener() {
boolean toggle = false;
#Override
public void actionPerformed(ActionEvent e) {
if (!temp.isSet()) {
temp.setBackground(Color.blue);
temp.setForeground(Color.white);
} else {
temp.setBackground(Color.white);
temp.setForeground(Color.blue);
}
temp.toggle();
}
});
buttons[i]=temp;
}
//set Location for the buttons
for(int i=0;i<5;i++) {
buttons[i].setLocation(100,(50*i)+10*(i+1));
}
for(int i=5;i<10;i++) {
buttons[i].setLocation(160,(50*i)+10*(i+1));
}
for(int i=10;i<15;i++) {
buttons[i].setLocation(220,(50*i)+10*(i+1));
}
for(int i=15;i<20;i++) {
buttons[i].setLocation(280,(50*i)+10*(i+1));
}
for(int i=20;i<25;i++) {
buttons[i].setLocation(340,(50*i)+10*(i+1));
}
//add buttons to the panel
for(int i=0;i<BINGOSIZE;i++) {
buttonPanel.add(buttons[i]);
}
this.setVisible(true);
I got the answer.
I ve changed the Layout of the Panel to Grid Layout. This alligns the buttons just where they should be in a 5x5 matrix and also with the wanted gap between. This makes also the code for the positioning completly obsolete.
By simply changing the Layout to GridLayout all of my Problems were gone.
I would like to know if the multiple selections function used in list, will be workable too in the object?
The example I found was working on the list as provided from the link.
https://stackoverflow.com/questions/25691623/jlist-listselectionlistener-multiple-interval-selection-that-waits-for-cntrl-or
The current project I'm working on is to draw different shapes which is an object. After done drawing, I shall be able to select more than 1 object by holding the SHIFT key.
How can I do that?
you can not re-use the List-Selection-Model in a simple way - i really recommend to use your own implemention instead.
To do so you must add a KeyListener and a MouseListener on your Panel in order to check for Shift pressed or not.
private boolean isShiftDown = false;
KeyAdapter ka = new KeyAdapter() {
#Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if(e.getKeyCode() == KeyEvent.VK_SHIFT){
isShiftDown=false;
}
}
#Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
if(e.getKeyCode() == KeyEvent.VK_SHIFT){
isShiftDown=true;
}
}
};
use your own selection 'model' which will be a simple list (java.util.List)
private List<Shape> selectionList = new ArrayList();
MouseAdapter ma = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
Shape shape = findShapeAt(e.getX(), e.getY() ); //i guessed you had a methode like that
if (shape != null){
//check is your shift key is down
if (isShiftDown){
//add or remove on click
if (selectionList.contains(shape) ){
selectionList.remove(shape);
}else{
selectionList.add(shape);
}
}else{
//if shift is NOT down, clear the list before adding
selectionList.clear();
selectionList.add(shape);
}
}
//show the selection in your gui();
updateSelection(); //that's your part - draw a nice border around all Shapes from the selectionList
}
};
don't forget to add both keyListener(KeyAdapter) and MouseListener(MouseAdapter) to your panel...
NOTE
i would really use the ctrl-key (KeyEvent.VK_CONTROL) instead of the shift-key to add/remove shapes by single-mouse-klick...
Currently I'm using a for-loop to populate the JPanel with numbers from 1-31
So basically, What I want to do is if let say i click on number 1, it will do show
System.out.println(1);
Here's the code:
public class MonthPanel extends JPanel implements MouseListener {
public MonthPanel() {
setLayout(new GridLayout(6,7));
// Add headers
// Use for-each loop.
for (String header : headers) {
add(new JLabel(header));
}
for (int i = 1; i < 31; i++) {
add(new JLabel(String.valueOf(i)));
}
addMouseListener(this);
}
public void mouseClicked(MouseEvent e) {
// What should i do in here to get a specific JLabel?
}
}
}
Here's the picture
Here's the solution
First you have to add mouselistener in label which should have mouse adapter in brackets its because you only want to use mouse click method.
Than add mouseClicked method in it .
and than add you code in mouseClicked method.
Example:
JLabel l = new JLabel("label");
l.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
// Your Code Here
}
});
add(l);
Instead of adding like that you can do something like
for (String header : headers) {
JLabel lbl = new JLabel(header);
lbl.addMouseListener(add ur listner);
add(lbl);
}
In the mouseClicked event you can get the JLabel and print its text as follows
public void mouseClicked(MouseEvent e) {
System.out.println(((JLabel) e.getSource()).getText());
}
In your code if you implement the MouseListener interface you must override all the abstract method in that. Otherwise it will not compile
I am trying to make this program for minecraft, and now im just getting started. I want that if you click a label, it will check what label is it and will do something.
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent me) {
System.out.println(me.getX()+", "+me.getY()+".");
Object source = me.getSource();
int intx = me.getX();
int inty = me.getY();
if(me.getX()>=1 && me.getY()>=1 && me.getX()<=70 && me.getY()<=45){
permissionsframe.setLocation(810,250);
System.out.println(p1p.length);
permissionsframe.pack();
permissionsframe.setSize(200, 200);
permissionsframe.setVisible(true);
JLabel playerperms = new JLabel("Player "+p1s+" has "+p1p.length+" permissions.");
playerperms.setBounds(1, 1, 150, 150);
permissionsframe.add(playerperms);
System.out.println("You chose "+player1.getText()+".");
}
else{
System.out.println("You did not click any label.");
}
}
});
This selection area is adapted to the name I have now - NonameSL. But if the name will be longer or shorter, the selection area will obviuosly be different...
Is there a way to get the excact label? I tried if(source.equals(player1))(Player 1 is the label) but I placed the label in 1, 1 and I have to click the excact point that I defined the label in, X=1, Y=1. How can I make a mouse listener listen to a label?
There is no need to check if the mouse coordinates are inside your JLabel.
You can bind a Listener to every JLabel an process the click/press event in your MyMouseListener.class
To do so:
You have to add the MouseListener to every JLabel:
MyMouseListener myMouseListener = new MyMouseListener();
label01.setName("name01");
label01.addMouseListener(myMouseListener);
label02.setName("name02");
label02.addMouseListener(myMouseListener);
To identify the JLabel you could do something like this:
class MyMouseListener extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
JLabel l = (JLabel) e.getSource();
if(l.getName().equals("name01"))
doSomething01();
else if(l.getName().equals("name02"))
doSomething02();
}
}
The correct way to do this is to use the .getComponent() method instead of the .getSource() since this is MouseEvent which is something different than ActionEvent.
Implement the Listener to your class:
public class Main implements MouseListener {
public static void main(String[] args) {
//setup JFrame and some label and then
label.addMouseListener(this);
}
#Override
public void mousePressed(MouseEvent e) {
if (e.getComponent().equals(label)) {
System.out.println("clicked");
}
}
//the other orderride methods..
JAVA USING NETBEANS
Hello stackoverflow, i have a problem i would like help with. In a nutshell, I have a mouselistener and a keylistener on a jpanel, everything works fine except when i press one of my jbuttons, then the keylistener goes AWOL. Can any1 explain the problem, is the panels focus now on the buttons instead of the keyboard, im at a lost.
Here is the code, if somethings are not reference, assume its are there the entire panel code was 500+ long so i cut quite a bit.
Thanks in advance for any help.
package tankgame;
public class TankPanel extends JPanel implements KeyListener,
MouseListener,MouseMotionListener
{
JButton back,shop, menu, health, speed, rapidfire, shootradius;
TankPanel()
{
setLayout( null );
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
setFocusable(true);
shop= new JButton("SHOP");
shop.addMouseListener(this);
shop.setBounds(400,0, 80,15);
add(shop);
}
public void keyPressed(KeyEvent k)
{
char c = k.getKeyChar();
if(c=='u')
{
u++;
System.out.println(u+" = u");
}
if(c=='i')
{
i++;
System.out.println(i+" = i");
}
if( c == 'd' )
{
if(Ptank.pic==PlayerTankE)
{
if(Ptank.move==true)
{
Pbarrel.x+=Ptank.speed;
Ptank.x+=Ptank.speed;
}
}
else
{
if(Ptank.pic==PlayerTankN || Ptank.pic==PlayerTankS)
{
Ptank.x = Ptank.x - 5;
Ptank.y=Ptank.y+5;
}
Ptank.setPic(PlayerTankE);
Ptank.width=35;
Ptank.height = 23;
}
}
setFocusable(true);
repaint();
}
public void keyReleased(KeyEvent k)
{
}
public void keyTyped(KeyEvent k)
{
}
public void mouseClicked(MouseEvent e)
{
//Invoked when the mouse button has been clicked (pressed and released)
}
public void mouseEntered(MouseEvent e)
{//Invoked when the mouse enters a component.
}
public void mouseExited(MouseEvent e)
{ //Invoked when the mouse exits a component.
}
public void mousePressed(MouseEvent e)
{//Invoked when a mouse button has been pressed on a component.
if(e.getSource()==back)
{
System.out.println(456);
System.out.println(back.getLocation().x + " "+back.getLocation().y);
}
else if(e.getSource() == menu)
{
changebuttons("menu");
System.out.println(456);
System.out.println(menu.getLocation().x + " "+menu.getLocation().y);
}
else if(e.getSource() == shop)
{
changebuttons("shop");
System.out.println(456);
System.out.println(shop.getLocation().x + " "+shop.getLocation().y);
}
else if(e.getButton() == MouseEvent.BUTTON1)
{
destpoint= new Point();
destpoint.setLocation(mousex, mousey);
origin = new Point();
}
for(int i = 0; i< Ptank.rapidfire; i++)
{
if (origin.distance(destpoint) <= 100 && origin.distance(destpoint) >= 50)
{
Bullet add = new Bullet(this,destpoint);
add.getOrigin(origin);
add.setPic(PlayerBullet);
add.width=4;
add.height=4;
bulletList.add(add);
}
}
}
}
public void mouseReleased(MouseEvent e)
{//Invoked when a mouse button has been released on a component.
}
public void mouseDragged(MouseEvent e)
{//Invoked when a mouse button is pressed on a component and then dragged.
}
public void mouseMoved(MouseEvent e)
{
//Invoked when the mouse cursor has been moved onto a component but no buttons
Cursor cursor = Cursor.getDefaultCursor();
//you have a List<Polygon>, so you can use this enhanced for loop
cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
setCursor(cursor);
mousex=e.getX();
mousey=e.getY();
}
public void changebuttons(String x)
{
if(x.equals("shop"))
{
menu.setBounds(720, 0, 80, 15);
health.setBounds(0, 0, 125, 15);
speed.setBounds(150, 0, 125, 15);
shootradius.setBounds(300, 0, 200, 15);
rapidfire.setBounds(500, 0, 150, 15);
shop.setBounds(1000, 0, 150, 15);
}
}
KeyEvents are only generated on a component that has focus. When you click on the button is now has focus to key events won't be generated on the panel. You need to add:
panel.requestFocusInWindow()
in your ActionListener to give focus back to the panel.
However the better solution is to use Key Bindings as you can add bindings to a KeyStroke even when the component doesn't have focus.
Don't use a KeyListener which requires the component be focused to work. Instead consider using Key Bindings. You can find out how to use these guys at the Swing tutorial: How To Use Key Bindings. If you need more specific help, you will want to post a much smaller bit of code than you show above, code that is self-contained and will actually compile and run for us, an SSCCE.