I'd appreciate any advice to how I can get the following to work.
Originally all my actions were stuffed into the GUI. Then the GUI became quite large as the project progressed. So I've been moving all these actions into their own classes. In doing this some aspects loose their visibility. I have hopefully captured all the visibility issues, this I am sure of.
Now the issue.
Implementing the setAction() call on a JButton allows the action to work and it works well if it is only a MouseListener or MouseMotionListener. However, the KeyListener code is not reached. You'll note the //Debug Lines.
Below Code #1 - Code in the GUI class
/**
* This method initializes toolRotateButton
*
* @return javax.swing.JButton
*/
private JToggleButton getToolRotateButton() {
if (toolRotateButton == null) {
toolRotateButton = new JToggleButton();
toolRotateButton.setPreferredSize(dimension30x30);
toolRotateButton.setHideActionText(true);
toolRotateButton.setAction(new RotateAction(this));
toolRotateButton.setToolTipText("Rotate Bearings or Selected Items");
}
return toolRotateButton;
}
Below Code #2 - Code in the RotateAction Class
package litetie.view.actions;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.Collections;
import javafx.geometry.Point3D;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import litetie.LiteTieTRIAL;
import litetie.controller.Transform;
import litetie.listeners.UndoableRotateBearing;
import litetie.model.Coordinate;
import litetie.model.NegativeNumberException;
import litetie.model.UnitConvert;
import litetie.view.Zoom;
@SuppressWarnings("serial")
public class RotateAction extends AbstractAction {
/**
* The host provides all of the state of the interface
*/
private final ActionHost host;
/**
* Constructs the move action, attaching it to the
* given host GUI.
*
* @param host The hosting GUI
*/
public RotateAction(ActionHost host) {
super("Rotate Selected Items", new ImageIcon(RotateAction.class.getResource("/icons_LiteTie_v2/rotate.png")));
this.host = host;
}
@Override
public void actionPerformed(ActionEvent e) {
host.setCurrentMouseMover(null); //set as nothing so that the new mouse listener can be applied later in the code
host.setStrokeColourLabelText("Stroke");
host.setStrokeColourWellBackground(host.getCurrentColour());
host.setCurrentMouseClicker(firstClicker);
host.setCurrentKeyEvent(currentKeyEvent);
}
/**
* The easting of the first click
*/
private double xClick;
/**
* The northing of the first click
*/
private double yClick;
/**
* The elevation of the first click
*/
private double zClick;
/**
* The offset between the click and the centre of the selection in easting
*/
private double xOffset;
/**
* The offset between the click and the centre of the selection in northing
*/
private double yOffset;
/**
* The offset between the click and the centre of the selection in elevation
*/
private double zOffset;
/**
* Boolean flag that is set by the currentKeyEvent for when the "C" key is pressed down.
*/
private boolean isVKCDown;
/**
* Boolean flag that is set by the currentKeyEvent for when the "P" key is pressed down.
*/
private boolean isVKPDown;
/**
* Boolean flag that is set by the currentKeyEvent for when the "SHIFT" key is pressed down.
*/
private boolean isVKShiftDown;
/**
* "currentKeyEvent" KeyListener to listen to when the various keys are pressed and then set the boolean flag
* allowing the code in the mouse motion listener to run.
*/
public KeyListener currentKeyEvent = new java.awt.event.KeyAdapter(){
@Override
public void keyPressed(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_C){
LiteTieTRIAL.setConsoleOutput("Aim bearings at mouse location");
System.out.println("Listening to key..."+e.getKeyChar()); //Debug currently this code is not reached.
System.out.println("VKCDown");//Debug currently this code is not reached.
isVKCDown = true;
}
if (e.getKeyCode() == KeyEvent.VK_P){
LiteTieTRIAL.setConsoleOutput("Rotate orientation of pattern");
System.out.println("Listening to key..."+e.getKeyChar()); //Debug currently this code is not reached.
System.out.println("VKPDown");//Debug currently this code is not reached.
isVKPDown = true;
}
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
LiteTieTRIAL.setConsoleOutput("Rotation in increments of Five Degrees");
System.out.println("Listening to key..."+e.getKeyChar()); //Debug currently this code is not reached.
System.out.println("VKCShiftDown");//Debug currently this code is not reached.
isVKShiftDown = true;
}
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
host.setSelection(null);
}
}
@Override
public void keyReleased(KeyEvent e){
if (e.getKeyCode() == KeyEvent.VK_C){
isVKCDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_P){
isVKPDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_SHIFT){
isVKShiftDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
host.setSelection(null);
}
}
};
/**
* "firstClicker" MouseListener to listen to when the mouse is clicked for the first time
*/
private MouseListener firstClicker = new MouseAdapter() {
//Mouse Event method
public void mouseReleased(MouseEvent e) {
//Get the Mouse Location and store it.
Rectangle2D canvas = host.getCanvasSize();
yClick = canvas.getY() + canvas.getHeight() - UnitConvert.pixelsToMeters(e.getY()) / Zoom.getScalingFactor(); //mouse's X location in the user co ords
xClick = canvas.getX() + UnitConvert.pixelsToMeters(e.getX()) / Zoom.getScalingFactor(); //mouse's Y location in the user co ords
zClick = 0;
Rectangle2D bounds = new Rectangle2D.Double();
host.getWorld().addAllCoordinates();
Object selection = host.getSelection();
if (selection == null) { // nothing selected yet
selection = host.selectFirstObjectNear(xClick, yClick, zClick);
if (selection == null) {
// nothing near the click location, wait for the next click
return;
}
}
if (!(selection instanceof Collection<?>)) {
// Put any single object into a collection so we only have one set of code
host.setSelection(Collections.singleton(selection));
}
// Reaching this point means one or more items are selected
// and are stored in a collection
for (Coordinate c: host.getWorld().getCoordList().values()) {
boolean isSelected = ((Collection<?>)selection).contains(c);
//STEP THROUGH CHECK
if (isSelected) {
if (bounds.isEmpty()) {
bounds = c.getBounds();
} else {
bounds = bounds.createUnion(c.getBounds());
}
}
}
host.setCentreBounds(bounds.getCenterX(), bounds.getCenterY(), 0);
host.setDelta(0, 0, 0);
yOffset = bounds.getCenterY() - yClick;
xOffset = bounds.getCenterX() - xClick;
host.setCurrentMouseClicker(nextClicker);
host.setCurrentMouseMover(mover);
}
};
/**
* "nextClicker" MouseListener to listen to when the mouse is clicked for the second time
*/
private MouseListener nextClicker = new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
Rectangle2D canvas = host.getCanvasSize();
double yMouseClick = canvas.getY() + canvas.getHeight() - UnitConvert.pixelsToMeters(e.getY()) / Zoom.getScalingFactor();
double xMouseClick = canvas.getX() + UnitConvert.pixelsToMeters(e.getX()) / Zoom.getScalingFactor();
try {
if (!isVKShiftDown && !isVKPDown && !isVKCDown) {
Transform.rotateBearingsOfCollection((Collection<?>) host.getSelection(), xMouseClick, yMouseClick);
host.updateCanvas();
} // ROTATE THE BEARING OF THE HOLE
else if (isVKShiftDown && !isVKPDown && !isVKCDown) {
Transform.rotateBearingsOfCollectionByFive((Collection<?>) host.getSelection(), xMouseClick, yMouseClick);
host.updateCanvas();
} // ROTATE THE BEARING OF THE HOLE BY 5 DEGREE INCREMENTS
if (isVKPDown && !isVKShiftDown && !isVKCDown){
Transform.rotateCoordinateCollection((Collection<?>) host.getSelection(), xMouseClick, yMouseClick);
host.updateCanvas();
}
else if (isVKPDown && isVKShiftDown && !isVKCDown){
// Transform.rotatePointByFive((Collection<?>) host.getSelection(), xMouseClick, xMouseClick);
// host.updateCanvas();
}
} catch (NumberFormatException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (NegativeNumberException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
host.updateCanvas();
//UNDO RECORD
host.addUndo(new UndoableRotateBearing(host.getWorld(), host.getSelection(), new Point3D(xClick + xOffset, yClick + yOffset, 0), new Point3D(xMouseClick, yMouseClick, 0)));
System.out.println("Add Coordinate Move - UndoableMoveObject()");
host.setSelection(null);
host.updateCanvas();
host.updateTrees();
host.setCurrentMouseClicker(firstClicker);
host.setCurrentMouseMover(host.getDefaultMouseMover());
host.setCentreBounds(0, 0, 0);
host.setDelta(0, 0, 0);
}
};
/**
* "mover" MouseMotionListener to listen to when the mouse is moved around the screen
*/
private MouseMotionListener mover = new MouseMotionAdapter() {
public void mouseMoved(MouseEvent e){
Rectangle2D canvas = host.getCanvasSize();
double yMouseClick = canvas.getY() + canvas.getHeight() - UnitConvert.pixelsToMeters(e.getY()) / Zoom.getScalingFactor();
double xMouseClick = canvas.getX() + UnitConvert.pixelsToMeters(e.getX()) / Zoom.getScalingFactor();
try {
if (!isVKShiftDown && !isVKPDown && !isVKCDown) {
Transform.rotateBearingsOfCollection((Collection<?>) host.getSelection(), xMouseClick, yMouseClick);
host.updateCanvas();
} // ROTATE THE BEARING OF THE HOLE
if (isVKShiftDown && !isVKPDown && !isVKCDown) {
Transform.rotateBearingsOfCollectionByFive((Collection<?>) host.getSelection(), xMouseClick, yMouseClick);
host.updateCanvas();
} // ROTATE THE BEARING OF THE HOLE BY 5 DEGREE INCREMENTS
if (isVKPDown && !isVKShiftDown && !isVKCDown){
Transform.rotateCoordinateCollection((Collection<?>) host.getSelection(), xMouseClick, yMouseClick);
host.updateCanvas();
}
if (isVKPDown && isVKShiftDown && !isVKCDown){
}
} catch (NumberFormatException e1) {
System.out.println("rotated - Error");
} catch (NegativeNumberException e1) {
System.out.println("rotated - Error");
}
host.updateCanvas();
}
};
}
Of note: I have other actions working where I have left the KeyListener in the GUI and not brought it into the Action.
So why would the MouseListeners be functioning and the KeyListeners not functioning?
Granted that perhaps keybindings may be the more appropriate method it is not the method I've employed in this portion of the application.
Thank you for your response however a friend suggested this today... which has fixed the KeyListener. Such a simple two lines.
private JToggleButton getToolRotateButton() {
if (toolRotateButton == null) {
RotateAction action = new RotateAction(this); //Code Added to fix
toolRotateButton = new JToggleButton();
toolRotateButton.setPreferredSize(dimension30x30);
toolRotateButton.setHideActionText(true);
toolRotateButton.setAction(action);
toolRotateButton.setToolTipText("Rotate Bearings or Selected Items");
toolRotateButton.addKeyListener(action.currentKeyEvent); //Code Added to fix
}
return toolRotateButton;
}
For those who are interested.