Skip to content

Commit c3804de

Browse files
authored
Add files via upload
1 parent ebfda66 commit c3804de

File tree

3 files changed

+517
-0
lines changed

3 files changed

+517
-0
lines changed

source/KeyboardAnimation.java

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
import java.awt.*;
2+
import java.awt.event.*;
3+
import java.net.*;
4+
import java.util.Map;
5+
import java.util.HashMap;
6+
import javax.swing.*;
7+
8+
public class KeyboardAnimation implements ActionListener
9+
{
10+
private final static String PRESSED = "pressed ";
11+
private final static String RELEASED = "released ";
12+
13+
private JComponent component;
14+
private Timer timer;
15+
private Map<String, Point> pressedKeys = new HashMap<String, Point>();
16+
17+
public KeyboardAnimation(JComponent component, int delay)
18+
{
19+
this.component = component;
20+
21+
timer = new Timer(delay, this);
22+
timer.setInitialDelay( 0 );
23+
}
24+
25+
/*
26+
* &param keyStroke - see KeyStroke.getKeyStroke(String) for the format of
27+
* of the String. Except the "pressed|released" keywords
28+
* are not to be included in the string.
29+
*/
30+
public void addAction(String keyStroke, int deltaX, int deltaY)
31+
{
32+
// Separate the key identifier from the modifiers of the KeyStroke
33+
34+
int offset = keyStroke.lastIndexOf(" ");
35+
String key = offset == -1 ? keyStroke : keyStroke.substring( offset + 1 );
36+
String modifiers = keyStroke.replace(key, "");
37+
38+
// Get the InputMap and ActionMap of the component
39+
40+
InputMap inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
41+
ActionMap actionMap = component.getActionMap();
42+
43+
// Create Action and add binding for the pressed key
44+
45+
Action pressedAction = new AnimationAction(key, new Point(deltaX, deltaY));
46+
String pressedKey = modifiers + PRESSED + key;
47+
KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke(pressedKey);
48+
inputMap.put(pressedKeyStroke, pressedKey);
49+
actionMap.put(pressedKey, pressedAction);
50+
51+
// Create Action and add binding for the released key
52+
53+
Action releasedAction = new AnimationAction(key, null);
54+
String releasedKey = modifiers + RELEASED + key;
55+
KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke(releasedKey);
56+
inputMap.put(releasedKeyStroke, releasedKey);
57+
actionMap.put(releasedKey, releasedAction);
58+
}
59+
60+
// Invoked whenever a key is pressed or released
61+
62+
private void handleKeyEvent(String key, Point moveDelta)
63+
{
64+
// Keep track of which keys are pressed
65+
66+
if (moveDelta == null)
67+
pressedKeys.remove( key );
68+
else
69+
pressedKeys.put(key, moveDelta);
70+
71+
// Start the Timer when the first key is pressed
72+
73+
if (pressedKeys.size() == 1)
74+
{
75+
timer.start();
76+
}
77+
78+
// Stop the Timer when all keys have been released
79+
80+
if (pressedKeys.size() == 0)
81+
{
82+
timer.stop();
83+
}
84+
}
85+
86+
// Invoked when the Timer fires
87+
88+
public void actionPerformed(ActionEvent e)
89+
{
90+
moveComponent();
91+
}
92+
93+
// Move the component to its new location
94+
95+
private void moveComponent()
96+
{
97+
int componentWidth = component.getSize().width;
98+
int componentHeight = component.getSize().height;
99+
100+
Dimension parentSize = component.getParent().getSize();
101+
int parentWidth = parentSize.width;
102+
int parentHeight = parentSize.height;
103+
104+
// Calculate new move
105+
106+
int deltaX = 0;
107+
int deltaY = 0;
108+
109+
for (Point delta : pressedKeys.values())
110+
{
111+
deltaX += delta.x;
112+
deltaY += delta.y;
113+
}
114+
115+
116+
// Determine next X position
117+
118+
int nextX = Math.max(component.getLocation().x + deltaX, 0);
119+
120+
if ( nextX + componentWidth > parentWidth)
121+
{
122+
nextX = parentWidth - componentWidth;
123+
}
124+
125+
// Determine next Y position
126+
127+
int nextY = Math.max(component.getLocation().y + deltaY, 0);
128+
129+
if ( nextY + componentHeight > parentHeight)
130+
{
131+
nextY = parentHeight - componentHeight;
132+
}
133+
134+
// Move the component
135+
136+
component.setLocation(nextX, nextY);
137+
}
138+
139+
// Action to keep track of the key and a Point to represent the movement
140+
// of the component. A null Point is specified when the key is released.
141+
142+
private class AnimationAction extends AbstractAction implements ActionListener
143+
{
144+
private Point moveDelta;
145+
146+
public AnimationAction(String key, Point moveDelta)
147+
{
148+
super(key);
149+
150+
this.moveDelta = moveDelta;
151+
}
152+
153+
public void actionPerformed(ActionEvent e)
154+
{
155+
handleKeyEvent((String)getValue(NAME), moveDelta);
156+
}
157+
}
158+
159+
public static void main(String[] args)
160+
{
161+
JPanel contentPane = new JPanel();
162+
contentPane.setLayout( null );
163+
164+
JLabel label = new JLabel( new ColorIcon(Color.BLUE, 40, 40) );
165+
label.setSize( label.getPreferredSize() );
166+
label.setLocation(500, 500);
167+
contentPane.add( label );
168+
169+
KeyboardAnimation animation = new KeyboardAnimation(label, 24);
170+
animation.addAction("LEFT", -3, 0);
171+
animation.addAction("RIGHT", 3, 0);
172+
animation.addAction("UP", 0, -3);
173+
animation.addAction("DOWN", 0, 3);
174+
175+
animation.addAction("control LEFT", -5, 0);
176+
animation.addAction("V", 5, 5);
177+
178+
JLabel label2 = new JLabel( new ColorIcon(Color.GREEN, 40, 40) );
179+
label2.setSize( label2.getPreferredSize() );
180+
label2.setLocation(100, 100);
181+
contentPane.add( label2 );
182+
183+
KeyboardAnimation animation2 = new KeyboardAnimation(label2, 24);
184+
animation2.addAction("A", -3, 0);
185+
animation2.addAction("D", 3, 0);
186+
animation2.addAction("W", 0, -3);
187+
animation2.addAction("S", 0, 3);
188+
189+
JFrame frame = new JFrame();
190+
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
191+
frame.getContentPane().add(contentPane);
192+
frame.setSize(600, 600);
193+
frame.setLocationRelativeTo( null );
194+
frame.setVisible(true);
195+
}
196+
197+
static class ColorIcon implements Icon
198+
{
199+
private Color color;
200+
private int width;
201+
private int height;
202+
203+
public ColorIcon(Color color, int width, int height)
204+
{
205+
this.color = color;
206+
this.width = width;
207+
this.height = height;
208+
}
209+
210+
public int getIconWidth()
211+
{
212+
return width;
213+
}
214+
215+
public int getIconHeight()
216+
{
217+
return height;
218+
}
219+
220+
public void paintIcon(Component c, Graphics g, int x, int y)
221+
{
222+
g.setColor(color);
223+
g.fillRect(x, y, width, height);
224+
}
225+
}
226+
}

source/MotionWithKeyBindings.java

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import java.awt.*;
2+
import java.awt.event.*;
3+
import java.net.*;
4+
import java.net.*;
5+
import javax.imageio.ImageIO;
6+
import javax.swing.*;
7+
8+
public class MotionWithKeyBindings
9+
{
10+
private JComponent component;
11+
12+
public MotionWithKeyBindings(JComponent component)
13+
{
14+
this.component = component;
15+
}
16+
17+
// Move the component to its new location. The component will stop
18+
// moving when it reaches the bounds of its container
19+
20+
public void move(int deltaX, int deltaY)
21+
{
22+
int componentWidth = component.getSize().width;
23+
int componentHeight = component.getSize().height;
24+
25+
Dimension parentSize = component.getParent().getSize();
26+
int parentWidth = parentSize.width;
27+
int parentHeight = parentSize.height;
28+
29+
// Determine next X position
30+
31+
int nextX = Math.max(component.getLocation().x + deltaX, 0);
32+
33+
if ( nextX + componentWidth > parentWidth)
34+
{
35+
nextX = parentWidth - componentWidth;
36+
}
37+
38+
// Determine next Y position
39+
40+
int nextY = Math.max(component.getLocation().y + deltaY, 0);
41+
42+
if ( nextY + componentHeight > parentHeight)
43+
{
44+
nextY = parentHeight - componentHeight;
45+
}
46+
47+
// Move the component
48+
49+
component.setLocation(nextX, nextY);
50+
}
51+
52+
public MotionAction addAction(String name, int deltaX, int deltaY)
53+
{
54+
MotionAction action = new MotionAction(name, deltaX, deltaY);
55+
56+
KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke(name);
57+
InputMap inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
58+
inputMap.put(pressedKeyStroke, name);
59+
component.getActionMap().put(name, action);
60+
61+
return action;
62+
}
63+
64+
private class MotionAction extends AbstractAction
65+
{
66+
private int deltaX;
67+
private int deltaY;
68+
69+
public MotionAction(String name, int deltaX, int deltaY)
70+
{
71+
super(name);
72+
putValue(Action.ACTION_COMMAND_KEY, name);
73+
74+
75+
this.deltaX = deltaX;
76+
this.deltaY = deltaY;
77+
}
78+
79+
public void actionPerformed(ActionEvent e)
80+
{
81+
move(deltaX, deltaY);
82+
}
83+
}
84+
85+
private static JButton addMotionSupport(JComponent component)
86+
{
87+
int delta = 3;
88+
MotionWithKeyBindings motion = new MotionWithKeyBindings(component);
89+
motion.addAction("LEFT", -delta, 0);
90+
motion.addAction("RIGHT", delta, 0);
91+
motion.addAction("UP", 0, -delta);
92+
motion.addAction("DOWN", 0, delta);
93+
94+
Action left = component.getActionMap().get("LEFT");
95+
return new JButton(left);
96+
}
97+
98+
public static void main(String[] args)
99+
{
100+
EventQueue.invokeLater(new Runnable()
101+
{
102+
public void run()
103+
{
104+
// Create a panel with a component to be moved
105+
106+
JPanel content = new JPanel();
107+
content.setLayout(null);
108+
109+
JLabel component = new JLabel( new ColorIcon(Color.BLUE, 40, 40) );
110+
component.setSize( component.getPreferredSize() );
111+
component.setLocation(100, 100);
112+
content.add(component);
113+
114+
JButton left = addMotionSupport( component );
115+
116+
JFrame.setDefaultLookAndFeelDecorated(true);
117+
JFrame frame = new JFrame("Motion With Key Bindings");
118+
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
119+
frame.add( content );
120+
frame.add(left, BorderLayout.PAGE_END);
121+
frame.setSize(600, 600);
122+
frame.setLocationByPlatform( true );
123+
frame.setVisible(true);
124+
125+
}
126+
});
127+
}
128+
129+
static class ColorIcon implements Icon
130+
{
131+
private Color color;
132+
private int width;
133+
private int height;
134+
135+
public ColorIcon(Color color, int width, int height)
136+
{
137+
this.color = color;
138+
this.width = width;
139+
this.height = height;
140+
}
141+
142+
public int getIconWidth()
143+
{
144+
return width;
145+
}
146+
147+
public int getIconHeight()
148+
{
149+
return height;
150+
}
151+
152+
public void paintIcon(Component c, Graphics g, int x, int y)
153+
{
154+
g.setColor(color);
155+
g.fillRect(x, y, width, height);
156+
}
157+
}
158+
}

0 commit comments

Comments
 (0)