I am a newcomer to the language of Java and to Stack Overflow. I want to add shapes to a Panel to mimic a map. The problem is explained in the title - I don't know how to add the shapes into my panel. Please note that I am about halfway through completing this program which means that it doesn't have all of the function that I intend for it yet. I have two classes for this program - Map.java and MapShapes.java
My first class.
/** Program that maps a room in the house and sees how things will look from an overhead, 2d perspective. ;
* #author: James ;
*
* */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Map extends JPanel{
MapShapes[] shapeArray = new MapShapes[20];
int count = 0;
private JLabel askLength, askWidth, askX, askY;
private JTextField length, width, x, y;
private JButton addButton;
private DrawingPanel drawPanel = new DrawingPanel();
public static void main(String[] args){
JFrame frame = new JFrame("Map");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Map panel = new Map();
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}// end of main;
public Map(){
JPanel controlPanel = new JPanel();
addButton = new JButton("Add a shape");
askX = new JLabel("X coordinate: ");
askY = new JLabel("Y coordinate: ");
askLength = new JLabel("Length: ");
askWidth = new JLabel("Width: ");
x = new JTextField(3);
y = new JTextField(3);
length = new JTextField(3);
width = new JTextField(3);
length.addActionListener(new Listener());
width.addActionListener(new Listener());
x.addActionListener(new Listener());
y.addActionListener(new Listener());
controlPanel.add(askX);
controlPanel.add(x);
controlPanel.add(askY);
controlPanel.add(y);
controlPanel.add(askLength);
controlPanel.add(length);
controlPanel.add(askWidth);
controlPanel.add(width);
controlPanel.add(addButton);
controlPanel.setPreferredSize(new Dimension (100, 400));
add(controlPanel);
add(drawPanel);
}// end of constructor;
private class DrawingPanel extends JPanel{
/** This public DrawingPanel() constructor.* */
public DrawingPanel(){
setPreferredSize(new Dimension(400, 400));
setBackground(Color.pink);
} // End of DrawingPanel() method.
/** This public void paintComponent(Graphics g) method* */
public void paintComponent(Graphics g){
super.paintComponent(g);
for(int index = 0; index<count; index++)
shapeArray[index].display(g);
} // End of paintComponent(Graphics g) method.
}// End of private class;
/** This class allows actions to be added to the buttons and text fields;*/
private class Listener implements ActionListener{
public void actionPerformed(ActionEvent event){
int lengthVal, widthVal, yVal, xVal;
JButton button = (JButton) event.getSource () ;
String textX = x.getText();
String textY = y.getText();
String textLength = length.getText();
String textWidth = width.getText();
xVal = Integer.parseInt(textX);
yVal = Integer.parseInt(textY);
lengthVal = Integer.parseInt(textLength);
widthVal = Integer.parseInt(textWidth);
if(button.getText().equals("Add a shape")){
if(count<shapeArray.length){
shapeArray[count] = new MapShapes(lengthVal, widthVal, xVal, yVal);
count++;
} // end of nested if block;
} // End of if block;
repaint();
}// end of method;
}// end of private class;
}// end of class;
My second class.
/** This class makes the rectangles for the Map program. ;
* #author: James ;
*/
import java.util.*; // So that we can use the Random class.
import java.awt.*; // So that we can use the Color class and the Graphics class.
/** This class makes rectangles.*/
public class MapShapes{
private int x;
private int y;
private int length;
private int width;
private Color colour;
public MapShapes(int length, int width, int x, int y){
this.length = length;
this.width = width;
this.x = x;
this.y = y;
this.colour = new Color(randInt(0,254), randInt(0,254), randInt(0,254));
}
/** This randInt(int lowest, int highest) method:
* Returns a random value within particular limits to instantiate the colour data field.
* */
public int randInt( int lowest, int highest){
Random generator = new Random();
int randomNum = generator.nextInt(highest - lowest) + lowest;
return randomNum;
}
public void display(Graphics j){
j.setColor(colour);
j.fillRect(x, y, length, width);
}
}// end of class;
You need to add a ActionListener to your addButton, which when triggered, gathers the information required from your other fields and adds them shapeArray and calls repaint on the instance of your DrawingPanel which is visible on the screen.
See How to Write an Action Listeners and How to Use Buttons, Check Boxes, and Radio Buttons for more details
Related
I don't know what I did, or what went wrong, but a change I made at some point in the last while has made my JPanel completely invisible. The JFrame it's nested in still changes in size to house it, and I can still toggle the content in the combobox.
In my desperation, I tried replacing the content of the SnakeSettingsPanel class with a single button, but the same thing happened - completely invisible, yet I can still interact with it. I figured it might be a computer error, so I tried restarting, but still nothing. When I tried adding a button to the frame outside of the JPanel, it worked just fine. What am I doing wrong?
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SnakeSettingsPanel extends JPanel {
public boolean quit = false;
public boolean play = false;
public int width = 20;
public int height = 15;
public Speed speed = Speed.SLOW;
public JTextField wField;
public JTextField hField;
public JComboBox<Speed> sField;
public static void main(String[] args) {
JFrame jf = new JFrame();
jf.setTitle("Snake");
SnakeSettingsPanel settings = new SnakeSettingsPanel();
jf.add(settings);
jf.pack();
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public SnakeSettingsPanel() {
setLayout(new GridBagLayout());
// #author Create our labels.
JLabel wLabel = new JLabel("Width:");
JLabel hLabel = new JLabel("Height:");
JLabel sLabel = new JLabel("Speed:");
GridBagConstraints p = new GridBagConstraints();
p.gridx = 0;
p.gridy = 0;
p.insets = new Insets(10, 10, 10, 10);
// #author Create the buttons, and add listeners
JButton y = new JButton("Play");
JButton n = new JButton("Quit");
y.addActionListener(new PlayListener());
n.addActionListener(new QuitListener());
// #author Create text fields for height/width
wField = new JTextField(15);
wField.setText("20");
hField = new JTextField(15);
hField.setText("15");
// #author Creates a combobox for selecting speed.
Speed[] speeds = {Speed.SLOW, Speed.MEDIUM, Speed.FAST};
sField = new JComboBox<Speed>(speeds);
// #author Stitch everything into the panel.
add(wLabel, p);
p.gridx = 1;
add(wField, p);
p.gridx = 0;
p.gridy = 1;
add(hLabel, p);
p.gridx = 1;
add(hField, p);
p.gridx = 0;
p.gridy = 2;
add(sLabel, p);
p.gridx = 1;
add(sField, p);
p.gridx = 0;
p.gridy = 3;
add(y, p);
p.gridx = 1;
add(n, p);
setVisible(true);
}
public boolean getPlay() {
return play;
}
public boolean getQuit() {
return quit;
}
// #author Returns all settings as a SnakeSettings object
public SnakeSettings getSettings() {
return new SnakeSettings(width, height, speed);
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public Speed getSpeed() {
return speed;
}
// #author Sends out the word to start a new game.
public class PlayListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
quit = false;
play = true;
width = Integer.parseInt(wField.getText());
height = Integer.parseInt(hField.getText());
speed = (Speed) sField.getSelectedItem();
}
}
// #author Sends out the word to shut down the program.
public class QuitListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
quit = true;
play = false;
}
}
}
Let this be a lesson on why you should avoid mixing Model (your application's data) with View (how it is displayed). Your SnakeSettingsPanel is currently both.
As Model, it contains 3 important fields: width, height, and speed.
As View, it is a full JPanel. JPanels have a lot of fields which you should avoid touching directly. Including width and height, usually accessed via getHeight and getWidth -- which you are overwriting with a version that always returns the same built-in values of 20 and 15 (until the user changes those values through a UI that they cannot see).
The fast fix is to rename your current getWidth() and getHeight() to avoid clashing with the built-in getWidth() and getHeight() methods of the parent JPanel class. Call them getMyWidth(), getMyHeight(), and suddenly everything works.
The better fix is to remove those fields and methods entirely, and store your own model attributes in a SnakeSettings attribute. Update it when the user clicks on play, and return it when it is requested via getSettings(). Less code for you, less chance of accidental name clashes with your parent JPanel class. This would look like:
// SnakeSettingsPanel, before
public int width = 20;
public int height = 15;
public Speed speed = Speed.SLOW;
public int getWidth() { // <-- clashes with superclass
return width;
}
public int getHeight() { // <-- clashes with superclass
return height;
}
public Speed getSpeed() {
return speed;
}
public SnakeSettings getSettings() {
return new SnakeSettings(width, height, speed);
}
// SnakeSettingsPanel, after
SnakeSettings settings = new SnakeSettings();
public SnakeSettings getSettings() {
return settings;
}
I'm currently working on a java project which consists of a frame , main panel, and 3 sub panels.On the north of the main panel i have my dataPanel, on the west i have my buttonPanel and on the center i have my drawPanel
My DrawPanel should display an initial of 5 circles and whenever create button is clicked it should draw X amount of circles specified by the user. However i want the circle center points to be all visible within DrawPanel only meaning no more than 1/2 of any circle is cut off the panel. I don't wish to set a length and width is there anyway to make it dynamic relative to the frame/panel size.
Here is my code
public class MainPanel extends JPanel{
private DataPanel data;
private JPanel buttonPanel;
private DrawPanel dPanel;
private JButton create;
private JButton sort;
private JButton coCenter;
private JButton reset;
public MainPanel()
{
setLayout(new BorderLayout());
data = new DataPanel();
add(data, BorderLayout.NORTH);
buttonPanelInitialize();
add(buttonPanel,BorderLayout.WEST);
int a,b,c;
a = data.getDataField();
b = data.getDataField1();
c = data.getDataField2();
dPanel = new DrawPanel(a,b,c);
add(dPanel, BorderLayout.CENTER);
}
private void buttonPanelInitialize()
{
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(4,1));
buttonCreate();
buttonSort();
buttonCoCenter();
buttonReset();
buttonPanel.add(create);
buttonPanel.add(sort);
buttonPanel.add(coCenter);
buttonPanel.add(reset);
}
private void buttonCreate()
{
create = new JButton("Create");
class cListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent event) {
//int amount = 0;
int amount = data.getDataField();
int smallestR = data.getDataField1();
int largestR = data.getDataField2();
dPanel.create(amount,smallestR,largestR);
}
}
ActionListener createListener = new cListener();
create.addActionListener(createListener);
}
and
public class DrawPanel extends JPanel{
private ArrayList<ColorCircle> circles;
private int numberOfCircles;
private int smallestRadiusSize;
private int biggestRadiusSize;
private int width;
private int height;
public DrawPanel()
{
circles = new ArrayList<ColorCircle>();
}
public DrawPanel(int number, int smallestRadius, int biggestRadius)
{
circles = new ArrayList<ColorCircle>();
create(number,smallestRadius,biggestRadius);
width = (int)Math.random()*getWidth();
height = (int)Math.random()*getHeight();
}
public void create(int number, int smallestRadius, int biggestRadius)
{
numberOfCircles = number;
smallestRadiusSize = smallestRadius;
biggestRadiusSize = biggestRadius;
for(int i = 0; i < numberOfCircles ; i++)
{
int radius = (int) ((int)smallestRadiusSize+Math.random()*((int)biggestRadiusSize-(int)smallestRadiusSize+1));
width = (int) ((int)100+Math.random()*701); //the problem is here
height = (int) ((int)100+Math.random()*501); //and here this part should be dynamic
circles.add(new ColorCircle(width,height,radius));
System.out.println(smallestRadiusSize);
System.out.println(biggestRadiusSize);
System.out.println(radius+"-----");
System.out.println(circles.size());
System.out.println(width+" THis is x");
System.out.println(height+" THIs is Y");
repaint();
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for(ColorCircle c : circles)
{
c.fill(g2);
}
}
is there anyway to make it dynamic relative to the frame/panel size
You add a AncestorListener to the panel and handle the ancestorAdded event. This event will be generated when the panel is added to a visible GUI.
So this means your create(...) method needs to be invoked from this method (not the constructor). Then when the code is executed you can use the getWidth() and getHeight() methods of the panel to get the actual size of the panel and do your processing.
I'm new to java and I'm seeking some help. The problem I have is that I cannot change a speed variable in a different class, from within the main class.
I have setter/getter methods, but the problem i am having is deciding which "object" to address to the setter/getter methods.
The slider is meant to change the speed of all of the turtles in the ArrayList. If i could have some help with this that would be great. Aside from the speed changing, the rest of the ChangeListener method works.
Main Class:
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.awt.event.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
class TurtleProgram
{
private JFrame frame;
private Canvas canvas;
private JPanel lowerPanel;
private JButton addTurtleButton;
private ArrayList<DynamicTurtle> turtles;
private JSlider turtleSpeed;
private int oldSliderState = 100;
public static void main(String[] args)
{
new TurtleProgram();
}
public TurtleProgram()
{
frame = new JFrame();
canvas = new Canvas();
lowerPanel = new JPanel();
lowerPanel.setLayout(new FlowLayout());
DynamicTurtle referenceTurtle = new DynamicTurtle(canvas , new CartesianCoordinate(400,300));
turtles = new ArrayList<DynamicTurtle>();
turtles.add(new RandomTurtleB(canvas, 400, 300));
addTurtleButton = new JButton("Add A Turtle?");
lowerPanel.add(addTurtleButton);
turtleSpeed = new JSlider(0, 100, 100);
lowerPanel.add(turtleSpeed);
frame.setTitle("Welcome to Button Simulator!");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(lowerPanel, BorderLayout.PAGE_END);
frame.add(canvas);
addTurtleButton.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent event)
{
turtles.add(new RandomTurtleB(canvas, 400, 300));
}
} );
turtleSpeed.addChangeListener( new ChangeListener()
{
public void stateChanged(ChangeEvent event)
{
int currentSliderState = turtleSpeed.getValue();
int currentSpeed = (turtles.get(i)).getSpeed(); //HERE I CANNOT USE THE TURTLES IN THE ARRAYLIST TO SET SPEED
if(currentSliderState < oldSliderState)
{
System.out.println("is less");
(turtles.get(i)).setSpeed(currentSpeed - 100); //DECREASES ALL TURTLES SPEED
}
else if(currentSliderState > oldSliderState)
{
System.out.println("is more");
(turtles.get(i)).setSpeed(currentSpeed + 100); //INCREASES ALL TURTLES SPEED
}
oldSliderState = (turtles.get(i)).getValue();
}
} );
gameLoop();
}
private void gameLoop()
{
int deltaTime = 20;
while(true)
{
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).unDrawTurtle();
(turtles.get(i)).wrapPosition((turtles.get(i)).getPositionX(), (turtles.get(i)).getPositionY());
}
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).update(1000);
}
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).drawTurtle();
}
Utils.pause(deltaTime/2);
}
}
}
The class containing the setter/getter methods:
class DynamicTurtle extends Turtle
{
private int speed = 100;
private int time;
private double xPos, yPos;
private CartesianCoordinate myLocation;
private int Angle = 0;
DynamicTurtle(Canvas canvas, CartesianCoordinate initLocation)
{
super(canvas, initLocation);
}
DynamicTurtle(Canvas canvas, double xPosition, double yPosition) //THE PROBLEM CONSTRUCTOR
{
super(canvas, new CartesianCoordinate(xPosition, yPosition));
}
public int getSpeed()
{
return this.speed;
}
public void setSpeed(int speed)
{
this.speed = speed;
}
public void update(int time)
{
this.move((speed*100/time));
canvas.removeMostRecentLine();
}
}
Thankyou for your help in advance, I have not removed code(I'm aware it's long) from the Main so you can see my logic in how i approached dealing with ArrayLists in the main. I am aware i cannot use this "get(i)". Cheers.
From inside the ChangeListener class, you can access that turtles variable with TurtleProgram.this.turtles. TurtleProgram.this gets you the enclosing instance of TurtleProgram in which the ChangeListener was constructed.
But, as Saviour Self suggested in his comment, if different turtles will never have the same speed, just make the speed variable, along with its get/set methods, static.
I am expanding Image editing application in Java. I want to make a class that would adjust contrast of the image. Main class calls apply method and passes image that has to be modified. I managed to create JFrame and algorithm for calculation, but I have problems with Action Listener because I don't know how to make my apply method wait for the users input and only then calculate and edit image. Here is the code for contrast class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
lic class ContrastFilter extends Filter implements ActionListener {
private JFrame contFr;
private JButton ok;
private JTextField textF;
private String s;
private int contV;
private int factor;
public ContrastFilter(String name){
super(name);
}
public void makeFrame(){
contFr = new JFrame("contrast window");
Container contentPane = contFr.getContentPane();
contentPane.setLayout(new FlowLayout());
JLabel label = new JLabel("Enter contrast");
contentPane.add(label, BorderLayout.PAGE_START);
textF = new JTextField(5);
contentPane.add(textF, BorderLayout.PAGE_START);
ok = new JButton("OK");
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == ok){
s = textF.getText();
contV = Integer.parseInt(s);
factor = Math.round((259*(contV+255))/(255*(259 - contV)));
}}
});
contentPane.add(ok, BorderLayout.PAGE_START);
contFr.pack();
contFr.setVisible(true);
}
public void apply(OFImage image) {
makeFrame();
int height = image.getHeight();
int width = image.getWidth();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
Color pix = image.getPixel(x, y);
image.setPixel(x, y, new Color(trunC(factor*(pix.getRed()-128)+128),
trunC(factor*(pix.getGreen()-128)+128),
trunC(factor*(pix.getBlue()-128)+128)));
} } }
public int trunC(int a){
if (a>255){
return 255;
}
return a;
}
}
If you want your apply() method to work after the button "OK" was clicked (user inputs something, then clicks OK), then you need to put an apply() invocation into you ActionListener's actionPerformed() method body.
I'm coding an application to print bricks in the grids, and I have set it up so that ideally, to change the colour, the menu selection changes an int which sets the colour in the bricks class.
I have two panels, one for the grid (where things are drawn) and one for the menu bar. If I manually change the number in the grid, it works, so I think it might be a problem with the menu, but I'm not sure. I'm wondering how I can get the int from the menu jpanel to the grid jpanel whenever it changes.
This is the menu code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Selector extends JPanel implements Common, ActionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
public Color colorValues[] = {Color.BLACK, Color.YELLOW, Color.RED, Color.ORANGE};
public String colors[] = {"Black", "Yellow", "Red", "Orange"};
public JMenuItem colorItems[];
public int display;
//constructor
public Selector(){
//set size and layout
setPreferredSize(new Dimension(SELECTOR_WIDTH, SELECTOR_HEIGHT));
setLayout(new BorderLayout());
//menu bar
JMenuBar bar = new JMenuBar();
Font f = new Font("Helvetica", Font.BOLD, 15);
//menus
JMenu colorMenu = new JMenu("Colour");
//create Color menu
String colors[] = {"Black", "Yellow", "Red", "Orange"};
colorItems = new JMenuItem[colors.length];
for (int i = 0; i<colors.length; i++){
colorItems [i] = new JMenuItem(colors[i]);
colorMenu.add(colorItems[i]);
colorItems[i].addActionListener(this);
}// end of for loop
//set all font the same
UIManager.put("Menu.font", f);
UIManager.put("MenuBar.font", f);
UIManager.put("MenuItem.font", f);
//add menus
bar.add(colorMenu);
//add menu bar
add(bar, BorderLayout.PAGE_START);
}//constructor end
public void actionPerformed(ActionEvent e){
if (e.getSource()==colorItems[0]){
display=0;
}
else if (e.getSource()==colorItems[1]){
display=1;
}
else if (e.getSource()==colorItems[2]){
display=2;
}
else if (e.getSource()==colorItems[3]){
display=3;
}
}
}//class end
This is the Map Grid code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MapGrid extends JPanel implements Common, MouseListener{
/**
*
*/
private static final long serialVersionUID = 1L;
//brick array
public Bricks [] brick = new Bricks[COLUMN*ROW];
//number array to save
public int [] cell = new int[COLUMN*ROW];
//coordinate variables
private int x=0;
private int y=0;
Selector s = new Selector();
//constructor
public MapGrid(){
//sets size, layout, and background colour
setPreferredSize(new Dimension(MAPGRID_WIDTH, MAPGRID_HEIGHT));
setLayout(new GridLayout(ROW, COLUMN));
addMouseListener(this);
//draws grid of bricks
for (int i = 0; i <COLUMN*ROW; i++){
cell[i] = 4;
if ((i%COLUMN==0)&&(i>COLUMN-1)){
x=0;
y+=22;
}
brick[i] = new Bricks(x,y);
x+=40;
}
}//constructor end
//draws bricks
public void paint(Graphics g){
super.paint(g);
for (int i = 0; i <COLUMN*ROW; i++){
brick[i].draw(g);
}
}//paint end
public void mousePressed(MouseEvent evt) {
//gets mouse and y coordinates
int x = evt.getX();
int y = evt.getY();
//gets column and row of mouse location
int c =x/BRICK_WIDTH;
int r =y/BRICK_HEIGHT;
//checks if mouse is within range
if ((c>=0&&c<=COLUMN)&&(r>=0&&r<=ROW)){
int index = (r)*COLUMN+c; //calculates brick number
//right click - delete brick
if (evt.isMetaDown()) {
brick[index].setChoice(4);
cell[index]=4;
}
//left click - draws brick
else{
brick[index].setChoice(s.display);
cell[index]=s.display;
}
}
repaint();
}//mousePressed end
//unused
public void mouseEntered(MouseEvent evt) {}
public void mouseExited(MouseEvent evt) {}
public void mouseClicked(MouseEvent evt) {}
public void mouseReleased(MouseEvent evt) {}
}//class end
this is the brick code:
import java.awt.*;
public class Bricks implements Common{
//variables
public int x=0;
public int y=0;
public int choice=3;
public boolean clear = true;
//size of bricks
private static final int width = BRICK_WIDTH;
private static final int height = BRICK_HEIGHT;
//constructor
public Bricks(int x, int y){
this.x=x;
this.y=y;
}//constructor end
//draw bricks
public void draw(Graphics g){
//set color or blank
switch(choice){
case 0: g.setColor(Color.BLACK);
break;
case 1: g.setColor(Color.YELLOW);
break;
case 2: g.setColor(Color.RED);
break;
case 3: g.setColor(Color.ORANGE);
break;
case 4: clear = true;
break;
}
//check if set blank
if (clear==true){
g.setColor(Color.BLACK);
g.drawRect(x,y,width,height);
}
else{
g.fillRect(x,y,width,height);
}
}//draw end
//set choice of color
public void setChoice (int c){
choice=c;
clear = false;
}//choice end
}//class end
Your problem is here:
public class MapGrid extends JPanel implements Common, MouseListener{
//...
Selector s = new Selector(); // ******* HERE **********
// ...
public void mousePressed(MouseEvent evt) {
// ....
else{
brick[index].setChoice(s.display);
cell[index]=s.display;
}
// ....
}
//...
}
You're creating a new Selector object above, but it is likely completely distinct from the Selector object that is displayed in your GUI. So changes to the state of the Selector held and displayed by the GUI will not be reflected in the Selector object that you're using above.
To solve this, make sure that the Selector variable refers to the one and same Selector that is displayed in the GUI.
e.g., change it to something like so:
public class MapGrid extends JPanel implements Common, MouseListener{
//...
Selector s = null;
public MapGrid(Selector s) {
this.s = s;
}
// .... etc....
and then when you create your MapGrid object, be sure to pass in a reference to the displayed true Selector instance.