I'm working on a task-planning AWT applet for my dev team, and I'm running into a problem.
I'm using a screen system, where the main class has a "current screen" variable that it uses to paint other screens. When the applet starts, it loads the "main screen" which has a "Chatroom" button. When you click the button, it should open the chatroom screen.
My problem is that it displays the main screen just fine, but when you click the button everything just goes blank and the chatroom does not show up at all. What am I doing wrong?
Each screen is a subclass of the Screen class, which is a subclass of Container.
Main Class:
public class TPApplet extends Applet
{
private static final long serialVersionUID = 7611084043153150559L;
private static final int WIDTH = 400;
private static final int HEIGHT = 350;
private static final String TITLE = "TaskPlanner v";
private static final double VERSION = 0.01;
private boolean setup = false;
public Screen currentScreen;
public void init()
{
setLayout(null);
setScreen(new MainScreen(this));
}
public void stop()
{
}
public void setScreen(Screen s)
{
if (currentScreen != null)
{
currentScreen.destroy();
remove(currentScreen);
}
currentScreen = s;
if (currentScreen != null)
{
currentScreen.init();
add(currentScreen);
}
}
public void paint(Graphics g)
{
if (!setup)
{
setSize(WIDTH, HEIGHT);
setName(TITLE + VERSION);
currentScreen.setLocation(0, 0);
currentScreen.setSize(WIDTH, HEIGHT);
setup = true;
}
if (currentScreen != null)
{
currentScreen.paint(g);
}
}
}
Main Menu class:
public class MainScreen extends Screen
{
private static final long serialVersionUID = -993648854350389881L;
private TPApplet applet;
private Button todoButton;
private Button chatButton;
private boolean setup = false;
public MainScreen(TPApplet tpApplet)
{
applet = tpApplet;
}
#Override
public void init()
{
setLayout(null);
todoButton = createButton("To-Do List");
chatButton = createButton("Chatroom");
}
#Override
public void destroy()
{
removeAll();
}
#Override
public void paint(Graphics g)
{
if (!setup)
{
todoButton.setLocation(25, 50);
todoButton.setSize(100, 40);
chatButton.setLocation(135, 50);
chatButton.setSize(100, 40);
setup = true;
}
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() instanceof Button)
{
Button button = (Button) e.getSource();
if (button.getLabel() == chatButton.getLabel())
{
applet.setScreen(new ChatScreen(applet));
}
}
}
}
Chatroom Class:
public class ChatScreen extends Screen
{
private static final long serialVersionUID = -8774060448361093669L;
private TPApplet applet;
private ScrollPane chatWindow;
private TextField textField;
private Button sendButton;
private boolean setup = false;
public ChatScreen(TPApplet tpApplet)
{
applet = tpApplet;
}
#Override
public void init()
{
setLayout(null);
sendButton = createButton("Send");
chatWindow = new ScrollPane();
textField = new TextField();
add(chatWindow);
add(textField);
}
#Override
public void destroy()
{
removeAll();
}
#Override
public void paint(Graphics g)
{
if (!setup)
{
chatWindow.setLocation(20, 20);
chatWindow.setSize(100, 100);
textField.setLocation(150, 150);
textField.setSize(60, 20);
sendButton.setLocation(220, 150);
sendButton.setSize(40, 20);
setup = true;
}
}
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() instanceof Button)
{
Button button = (Button) e.getSource();
if (button.getLabel() == sendButton.getLabel())
{
String text = textField.getText();
}
}
}
}
Thank you in advance for your help!
I suspect that seen as you've chosen to discard the use of layout managers, when you add a new screen, the screen is being added with a 0x0 size
public void setScreen(Screen s)
{
//...//
if (currentScreen != null)
{
currentScreen.init();
// Look ma, I have no size...
add(currentScreen);
}
}
One of the jobs of a layout manger is to decide how any new components should be laid out.
Try setting the applet's layout manager to something like BorderLayout.
The next problem is that the child screens suffer from the same problem, so even though the screen will be sized (based on the needs of the layout manager), the screens themselves also have no layout manager, so the components you add to them have no size and it will appear that the screen hasn't been updated.
I'd also recommend that you take a look at Andrew's example of CardLayout
You could also check out A Visual Guide to Layout Managers and Using Layout Managers for more details...
You will need to invalidate() the applet in your setScreen method.
The new screen component needs to be laid out again to compute the sizes of its children.
It's a shame this isn't done automatically when adding!
Also, consider doing this using a LayoutManager if possible. Would a CardLayout work for you?
Related
I want to develop a simple interactive game (like arcanoid). I already have implemented a menu and different views, and now I need to develop the actually game (draw flying ball, some movable platform) and I don't know how to do this. I need something like canvas where I can draw my graphic each frame.
I have tryed to implement this with Canvas and Timer. But it doesn't want update graphic itself, but only when user clicks on screen or similar. Also I saw com.google.gwt.canvas.client.Canvas, but I cannot understand how to use it in Vaadin application.
So my question is next: is it possible to draw some graphic each frame with high framerate in any way? If possible, how can I do this?
P.S. I use the Vaadin 7.3.3.
ADDED LATER:
Here is a link to my educational project with implementation below.
I'll be glad if it helps someone.
ORIGINAL ANSWER:
Well... I found the solution myself. First of all, I have created my own widget - "client side" component (according to this article).
Client side part:
public class GWTMyCanvasWidget extends Composite {
public static final String CLASSNAME = "mycomponent";
private static final int FRAMERATE = 30;
public GWTMyCanvasWidget() {
canvas = Canvas.createIfSupported();
initWidget(canvas);
setStyleName(CLASSNAME);
}
Connector:
#Connect(MyCanvas.class)
public class MyCanvasConnector extends AbstractComponentConnector {
#Override
public Widget getWidget() {
return (GWTMyCanvasWidget) super.getWidget();
}
#Override
protected Widget createWidget() {
return GWT.create(GWTMyCanvasWidget.class);
}
}
Server side part:
public class MyCanvas extends AbstractComponent {
#Override
public MyCanvasState getState() {
return (MyCanvasState) super.getState();
}
}
Then I just add MyCanvas component on my View:
private void createCanvas() {
MyCanvas canvas = new MyCanvas();
addComponent(canvas);
canvas.setSizeFull();
}
And now I can draw anything on Canvas (on client side in GWTMyCanvasWidget) with great performance =). Example:
public class GWTMyCanvasWidget extends Composite {
public static final String CLASSNAME = "mycomponent";
private static final int FRAMERATE = 30;
private Canvas canvas;
private Platform platform;
private int textX;
public GWTMyCanvasWidget() {
canvas = Canvas.createIfSupported();
canvas.addMouseMoveHandler(new MouseMoveHandler() {
#Override
public void onMouseMove(MouseMoveEvent event) {
if (platform != null) {
platform.setCenterX(event.getX());
}
}
});
initWidget(canvas);
Window.addResizeHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent resizeEvent) {
resizeCanvas(resizeEvent.getWidth(), resizeEvent.getHeight());
}
});
initGameTimer();
resizeCanvas(Window.getClientWidth(), Window.getClientHeight());
setStyleName(CLASSNAME);
platform = createPlatform();
}
private void resizeCanvas(int width, int height) {
canvas.setWidth(width + "px");
canvas.setCoordinateSpaceWidth(width);
canvas.setHeight(height + "px");
canvas.setCoordinateSpaceHeight(height);
}
private void initGameTimer() {
Timer timer = new Timer() {
#Override
public void run() {
drawCanvas();
}
};
timer.scheduleRepeating(1000 / FRAMERATE);
}
private void drawCanvas() {
canvas.getContext2d().clearRect(0, 0, canvas.getCoordinateSpaceWidth(), canvas.getCoordinateSpaceHeight());
drawPlatform();
}
private Platform createPlatform() {
Platform platform = new Platform();
platform.setY(Window.getClientHeight());
return platform;
}
private void drawPlatform() {
canvas.getContext2d().fillRect(platform.getCenterX() - platform.getWidth() / 2, platform.getY() - 100, platform.getWidth(), platform.getHeight());
}
}
I have a Java program with two textareas and a button. I want to allow the user to write one one textarea using a touch pen or mouse and when he/she clicks the button, the drawn content should be send to textarea no 2.
So the textarea where the user is writing on, I gave a mousemotion listener with paintComponent method in it.
When I run the application, I have realized that texarea method getText() and setText() can't set or get the drawn content.
Is there way I can achieve the above task? I have also tried JPanel but it doesn't have the setContent() method.
I appreciate any help.
This is my first textarea where user is writing on with touchpen.
public class Area1 extends JTextArea {
int pointcount = 0;
Point[] points = new Point[10000];
public Area1() {
addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent event) {
if (pointcount < points.length) {
points[pointcount] = event.getPoint();
++pointcount;
repaint();
}
}
});
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < pointcount; i++) {
g.fillOval(points[i].x, points[i].y, 4, 4);
}
}
}
this is my overall application with textarea2 and button
public class Handwriting extends JFrame {
private JTextArea area2;
private JButton b1;
Area1 area1;
public Handwriting() {
Box box = Box.createHorizontalBox();
area1 = new Area1();
area1.setRows(30);
area1.setColumns(30);
area2 = new JTextArea(30, 30);
b1 = new JButton("Copy");
b1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
if (event.getSource() == b1) {
area2.setText(area1.getText());
}
}
});
box.add(area1);
box.add(b1);
box.add(area2);
add(box);
}
public static void main(String[] args) {
Handwriting hand = new Handwriting();
hand.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
hand.setSize(500, 500);
hand.setVisible(true);
}
}
One possible solution would be to make one class as a Inner Class of the other , that way even private instance fields can be accessed
I followed steps from many articles but the undo system not behaving as expected. first, the undo button goes back correctly till the first edit but can't go beyond the first edit. also, when I click undo and then re-edit it circles back to the last edit. It's better if you execute the code and see yourself.
Another question, while I'm trying to figure out a solution I read that saving images in an Array is memory intensive, is that true even for this simple paint class, and what is the alternative? saving the image's graphic?
import java.awt.*;import java.awt.image.BufferedImage;import java.awt.event.*;import java.util.ArrayList;import javax.swing.*;import javax.swing.event.*;import javax.swing.undo.*;
public class Painter extends JFrame{
//attributes//
Painter.Canvas canvas;
JPanel controlPanel;
JButton undoButton;
JButton redoButton;
PainterHandler handler;
Container container;
//undo system elements//
UndoManager undoManager; // history list
UndoableEditSupport undoSupport; // event support
//constructor//
public Painter()
{
super("Painter-test");
controlPanel = new JPanel();
undoButton = new JButton("undo");
redoButton = new JButton("redo");
handler = new Painter.PainterHandler();
container = getContentPane();
canvas = new Painter.Canvas();
this.organizer();
}// end constructor
public void organizer()
{
controlPanel.setLayout(null);
controlPanel.setPreferredSize(new Dimension(120,350));
controlPanel.setBackground(null);
//add undo listeners to undo/redo buttons.
undoButton.addActionListener( new AbstractAction()
{
public void actionPerformed( ActionEvent evt )
{ undoManager.undo(); refreshCanvas(); refreshUndoRedo();}
});
redoButton.addActionListener(new AbstractAction()
{
public void actionPerformed(ActionEvent evt )
{ undoManager.redo(); refreshCanvas(); refreshUndoRedo(); }
});
// initilize the undo/redo system.
undoManager= new UndoManager();//history list
// event support, instance.
undoSupport = new UndoableEditSupport();
//add undoable edit listener to the support instance.
undoSupport.addUndoableEditListener(new UndoableEditListener()
{
public void undoableEditHappened (UndoableEditEvent event)
{
UndoableEdit edit = event.getEdit();
undoManager.addEdit( edit );
refreshUndoRedo();
}
});
refreshUndoRedo();
canvas.setPreferredSize(new Dimension(600,400));
//place buttons on panel.
undoButton.setBounds(10, 160, 80, 20);
redoButton.setBounds(10, 181, 80, 20);
//add components to panel.
controlPanel.add(undoButton);
controlPanel.add(redoButton);
//add panels to window.
container.add(canvas,BorderLayout.WEST);
container.add(controlPanel, BorderLayout.EAST);
}//end organizerTab3()
public void refreshCanvas() { canvas.repaint(); }
//refresh undo, redo buttons.
public void refreshUndoRedo()
{
// refresh undo
undoButton.setEnabled( undoManager.canUndo() );
// refresh redo
redoButton.setEnabled( undoManager.canRedo() );
}
//INNER CLASSES
ArrayList<BufferedImage> imagesArray = new ArrayList<BufferedImage>();
BufferedImage imageCopy;
Graphics graphics;
BufferedImage image;
int index;
private class Canvas extends JPanel
{
public Canvas()
{
//Panel properties
setSize(600,400);
setBackground(new Color(84,84,118));
image = new BufferedImage(getWidth(), getHeight(),BufferedImage.TYPE_INT_ARGB);
//add Listeners.
addMouseMotionListener(handler);
addMouseListener(handler);
}//end constructor
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
}//end inner class PaintPanel
private class PainterHandler extends MouseAdapter
{
#Override
public void mouseDragged(MouseEvent event)
{
if(event.getComponent().equals(canvas))
{
if (image != null)
{
// Paint into the image
graphics = image.getGraphics();
graphics.setColor(new Color(249,30,138));
graphics.fillOval(event.getX(), event.getY(), 20, 20);
imageCopy = new BufferedImage(canvas.getWidth(),canvas.getHeight(),BufferedImage.TYPE_INT_ARGB);
imageCopy.getGraphics().drawImage(image, 0, 0, null);
canvas.repaint();
}
}
}//end mouseDragged(MouseEvent event)
#Override
public void mouseReleased(MouseEvent event)
{
if(event.getComponent().equals(canvas))
{
//UNDO SYSTEM START//
//add image to the array.
imagesArray.add(imageCopy);
// get image's index.
index = imagesArray.indexOf(imageCopy);
//create AddEdit instance of type UndoableEdit.
UndoableEdit edit = new Painter.AddEdit(imagesArray, imageCopy,index);
// notify the listeners
undoSupport.postEdit( edit );
//UNDO SYSTEM END//
}
}
}//end MouseHandler class
private class AddEdit extends AbstractUndoableEdit
{
private ArrayList<BufferedImage> undoableImagesArray;
private BufferedImage undoableImage;
int undoableIndex;
public AddEdit(ArrayList<BufferedImage> v, BufferedImage img, int i)
{
undoableImagesArray = v;
undoableImage = img;
undoableIndex = i;
}
public void undo() throws CannotUndoException
{
undoableImagesArray.remove(undoableImage);
if(!undoableImagesArray.isEmpty())
image = (BufferedImage)undoableImagesArray.get(undoableImagesArray.size()-1);
canvas.repaint();
}
public void redo() throws CannotRedoException
{
undoableImagesArray.add(undoableImage);
image = (BufferedImage)undoableImagesArray.get(undoableImagesArray.size()-1);
canvas.repaint();
}
public boolean canUndo() { return true; }
public boolean canRedo() { return true; }
}//end class AddEdit
public static void main(String[] s)
{
Painter p = new Painter();
p.setSize(800, 500);
p.setVisible(true);
p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}//END CLASS Painter
You don't use undoableIndex. In fact you should not remove the image from array but instead move the pointer.
canUndo() should return true if the list is not empty and the pointer >0
canRedo() should return true if the pointer!= size() of the list
Is there a way I can disable mouse click ? In the panel there are different components and for some of the Button Click events, I want to disable the mouse click. I mean the click of the mouse doesn't have any effect on the components. I can disable using the setEnabled() function but I don't want to do that way.
Is there any way I can disable the mouse click ?
Situation :
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
//..disable the mouse click on each component present inside the panel
}
You can add an extended ActionListener to all the buttons like this:
public abstract class ExtendedActionListener implements ActionListener{
private static boolean disabled = false;
public static void setDisabled(boolean disabled){
ExtendedActionListener.disabled = disabled;
}
#Override
public final void actionPerformed(ActionEvent e){
if(disabled)
return;
doSomething;
}
}
And now just disable all the ActionListeners by calling the method setDisabled(false). The Button visual behavior doesn't change at all, but nothing happens, when you click on it.
If the visual click behaviour doesn't matter, then you can just remove the MouseListeners.
You can create a button group like this:
public class SingleSelectionButtonGroup {
private final List<JButton> buttons;
public static SingleSelectionButtonGroup group(List<JButton> buttons) {
return new SingleSelectionButtonGroup(buttons);
}
public static SingleSelectionButtonGroup group(JButton...buttons) {
return new SingleSelectionButtonGroup(Arrays.asList(buttons));
}
private SingleSelectionButtonGroup(List<JButton> buttons) {
this.buttons = new ArrayList<JButton>(buttons);
setupListener();
}
private void setupListener() {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
SingleSelectionButtonGroup.this.disableAllExcept((JButton) e.getSource());
}
};
for (JButton button : buttons) {
button.addActionListener(listener);
}
}
private void disableAllExcept(JButton clickedButton) {
for (JButton button : buttons) {
if (!clickedButton.equals(button)) {
button.setEnabled(false);
}
}
}
}
And then uses it with a collection of buttons that you want to group:
public class Application {
public void run() {
final JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(400, 300));
final JPanel pane = new JPanel();
List<JButton> buttons = new ArrayList<JButton>();
String[] texts = {"A", "B", "C"};
for (String text : texts) {
JButton button = new JButton(text);
buttons.add(button);
pane.add(button);
}
SingleSelectionButtonGroup.group(buttons);
frame.getContentPane().add(pane);
frame.setVisible(true);
}
public static void main(String[] args) {
new Application().run();
}
}
you should use one common class of your listener and have static method for turn listener turn on and off
public abstract class BaseMouseListener implements ActionListener{
private static boolean active = true;
public static void setActive(boolean active){
BaseMouseListener.active = active;
}
protected abstract void doPerformAction(ActionEvent e);
#Override
public final void actionPerformed(ActionEvent e){
if(active){
doPerformAction(e);
}
}
}
your listeners would have to implements doPerformedAction()
Add empty mouse listener. This will "disable" the click because it will not have any effect.
I'm working in Java to create an internal tool. The two consists of two JPanels which are anticipated to run on two separate screens. I want to be able to click a JButton which is part of JFrame A which will send a keyboard action to JFrame B.
Unfortunately I can't seem to do this because JFrame B doesn't have the focus and I can't use any of the request Focus methods because JFrame B is not a child of the Focus Window (JFrame A is).
So how can I either give JFrame B focus despite it not being a child of the Focus Window or send Keyboard Events to JFrame B that it will respond to without having focus?
is so hard to manage Focus between two JFrames, better would be create only one JFrame and other Top-level Containers would be JDialogs, create one/two JDialog(s) and reuse that by removing all JComponents
basicaly it would be :
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
someComponent.grabFocus();
someComponent.requestFocus();//or inWindow depends if Swing or Awt
}
});
but between two JFrames is things little bit complicated, just basic and uncompleted example (based on code from old.good.sun.forums.com)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PMDialog extends JDialog {
private static final long serialVersionUID = 1L;
private boolean modal = false;
private WindowAdapter parentWindowListener;
private Window owner;
private JFrame blockedFrame = new JFrame("Blocked Frame");
private JFrame noBlockedFrame = new JFrame("No Blocked Frame");
public PMDialog() {
noBlockedFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
noBlockedFrame.getContentPane().add(new JButton(new AbstractAction("Test button") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("Non blocked button pushed");
/*if (blockedFrame.isVisible()) {
noBlockedFrame.setVisible(false);
} else {
blockedFrame.setVisible(true);
}*/
noBlockedFrame.setVisible(true);
blockedFrame.setVisible(true);
}
}));
noBlockedFrame.setSize(200, 200);
noBlockedFrame.setVisible(true);
blockedFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
blockedFrame.getContentPane().add(new JButton(new AbstractAction("Test Button") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent evt) {
final PMDialog pmd = new PMDialog(blockedFrame, "Partial Modal Dialog", true);
pmd.setSize(200, 100);
pmd.setLocationRelativeTo(blockedFrame);
pmd.getContentPane().add(new JButton(new AbstractAction("Test button") {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("Blocked button pushed");
pmd.setVisible(false);
blockedFrame.setVisible(false);
noBlockedFrame.setVisible(true);
}
}));
pmd.setDefaultCloseOperation(PMDialog.DISPOSE_ON_CLOSE);
pmd.setVisible(true);
System.out.println("Returned from Dialog");
}
}));
blockedFrame.setSize(200, 200);
blockedFrame.setLocation(300, 0);
blockedFrame.setVisible(false);
}
public PMDialog(JDialog parent, String title, boolean isModal) {
super(parent, title, false);
initDialog(parent, title, isModal);
}
public PMDialog(JFrame parent, String title, boolean isModal) {
super(parent, title, false);
initDialog(parent, title, isModal);
}
private void initDialog(Window parent, String title, boolean isModal) {
owner = parent;
modal = isModal;
parentWindowListener = new WindowAdapter() {
#Override
public void windowActivated(WindowEvent e) {
if (isVisible()) {
System.out.println("Dialog.getFocusBack()");
getFocusBack();
}
}
};
}
private void getFocusBack() {
Toolkit.getDefaultToolkit().beep();
super.setVisible(false);
super.pack();
super.setLocationRelativeTo(owner);
super.setVisible(true);
super.toFront();
}
#Override
public void dispose() {
owner.setEnabled(true);
owner.setFocusableWindowState(true);
super.dispose();
}
#Override
#SuppressWarnings("deprecation")
public void hide() {
owner.setEnabled(true);
owner.setFocusableWindowState(true);
super.hide();
}
#Override
public void setVisible(boolean visible) {
boolean blockParent = (visible && modal);
owner.setEnabled(!blockParent);
owner.setFocusableWindowState(!blockParent);
super.setVisible(visible);
if (blockParent) {
System.out.println("Adding listener to parent ...");
owner.addWindowListener(parentWindowListener);
try {
if (SwingUtilities.isEventDispatchThread()) {
System.out.println("EventDispatchThread");
EventQueue theQueue = getToolkit().getSystemEventQueue();
while (isVisible()) {
AWTEvent event = theQueue.getNextEvent();
Object src = event.getSource();
if (event instanceof ActiveEvent) {
((ActiveEvent) event).dispatch();
} else if (src instanceof Component) {
((Component) src).dispatchEvent(event);
}
}
} else {
System.out.println("OUTSIDE EventDispatchThread");
synchronized (getTreeLock()) {
while (isVisible()) {
try {
getTreeLock().wait();
} catch (InterruptedException e) {
break;
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Error from EDT ... : " + ex);
}
} else {
System.out.println("Removing listener from parent ...");
owner.removeWindowListener(parentWindowListener);
owner.setEnabled(true);
owner.setFocusableWindowState(true);
}
}
#Override
public void setModal(boolean modal) {
this.modal = modal;
}
public static void main(String args[]) {
PMDialog pMDialog = new PMDialog();
}
}
EDIT: for How to adds Focus to the JDialog is there excelent Woodoo by camickr Dialog Focus but AncestorListener isn't my cup of Java and too much abstract for me
Is this a Swing GUI (you don't mention or add a tag to a gui library)? If so, consider using Key Bindings which can be more flexible about focus compared with KeyListeners.
Nothing says you can't have one Action send a message to another. In this example, Enter also needs to Clear, so it forwards the ActionEvent. Note also that each NumberButton binds two keystrokes to Click. In your case, you may have to to remove an existing binding and perhaps call toFront() on the other window. Note the caveats that lend support to #mKorbel's answer.