8043126: move awt automated functional tests from AWT_Events/Lw and AWT_Events/AWT to OpenJDK repository

Reviewed-by: pchelko
This commit is contained in:
Alexander Stepanov 2014-07-08 16:01:18 +04:00
parent 7144d3a4fd
commit 89e241569b
8 changed files with 2891 additions and 0 deletions

View File

@ -0,0 +1,271 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8043126
* @summary Check whether
* 1. correct extended modifiers are returned
* by KeyEvent.getModifiersEx()
* 2. InputEvent.getModifiersExText() returns
* correct extended modifier keys description
*
* @library ../../../../../lib/testlibrary/ ../../helpers/lwcomponents/
* @build LWComponent
* @build LWButton
* @build LWList
* @build ExtendedRobot
* @run main/timeout=600 ExtendedModifiersTest
*/
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import static jdk.testlibrary.Asserts.*;
import test.java.awt.event.helpers.lwcomponents.LWButton;
import test.java.awt.event.helpers.lwcomponents.LWList;
public class ExtendedModifiersTest implements KeyListener {
Frame frame;
Button button;
LWButton buttonLW;
TextField textField;
TextArea textArea;
List list;
LWList listLW;
private final ExtendedRobot robot;
private final static int robotDelay = 1000;
private final static int waitDelay = 5000;
private final static int keyDelay = 500;
private final Object lock;
private boolean keyPressedFlag = false;
private int modifiersEx = 0;
private String exText = "";
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
return;
}
modifiersEx = e.getModifiersEx();
exText = InputEvent.getModifiersExText(modifiersEx);
keyPressedFlag = true;
synchronized (lock) { lock.notifyAll(); }
}
@Override
public void keyReleased(KeyEvent e) {}
public void createGUI() {
frame = new Frame();
frame.setTitle("ExtendedModifiersTest");
frame.setLayout(new GridLayout(1, 6));
button = new Button();
button.addKeyListener(this);
frame.add(button);
buttonLW = new LWButton();
buttonLW.addKeyListener(this);
frame.add(buttonLW);
textField = new TextField(5);
textField.addKeyListener(this);
frame.add(textField);
textArea = new TextArea(5, 5);
textArea.addKeyListener(this);
frame.add(textArea);
list = new List();
for (int i = 1; i <= 5; ++i) { list.add("item " + i); }
list.addKeyListener(this);
frame.add(list);
listLW = new LWList();
for (int i = 1; i <= 5; ++i) { listLW.add("item " + i); }
listLW.addKeyListener(this);
frame.add(listLW);
frame.setBackground(Color.gray);
frame.setSize(500, 100);
frame.setVisible(true);
frame.toFront();
}
public ExtendedModifiersTest() throws Exception {
lock = new Object();
robot = new ExtendedRobot();
EventQueue.invokeAndWait( this::createGUI );
}
private void runScenario(int keys[], int refMask) {
if (keys.length < 1) { return; }
for (int k = 0; k < keys.length; ++k) {
keyPressedFlag = false;
robot.keyPress(keys[k]);
robot.delay(keyDelay);
if (!keyPressedFlag) {
synchronized (lock) {
try {
lock.wait(waitDelay);
} catch (InterruptedException ex) {}
}
}
if (!keyPressedFlag) {
robot.keyRelease(keys[k]);
robot.delay(keyDelay);
assertTrue(false, "key press event was not received");
}
}
int modEx = modifiersEx & refMask;
for (int k = keys.length - 1; k >=0; --k) {
robot.keyRelease(keys[k]);
robot.delay(keyDelay);
}
assertEQ(modifiersEx, modEx, "invalid extended modifiers");
for (int k = 0; k < keys.length; ++k) {
String keyText = KeyEvent.getKeyText(keys[k]).toLowerCase();
assertTrue(exText.toLowerCase().contains(keyText), "invalid extended modifier keys description");
}
System.out.println(exText + " : passed");
robot.type(KeyEvent.VK_ESCAPE);
robot.delay(robotDelay);
}
private void doTest() throws Exception {
ArrayList<Component> components = new ArrayList();
components.add(button);
components.add(buttonLW);
components.add(textField);
components.add(textArea);
components.add(list);
components.add(listLW);
String OS = System.getProperty("os.name").toLowerCase();
System.out.println(OS);
for (Component c: components) {
String className = c.getClass().getName();
System.out.println("component class : " + className);
Point origin = c.getLocationOnScreen();
int xc = origin.x + c.getWidth() / 2;
int yc = origin.y + c.getHeight() / 2;
Point center = new Point(xc, yc);
robot.delay(robotDelay);
robot.glide(origin, center);
robot.click();
robot.delay(robotDelay);
// 1. shift + control
runScenario(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL},
InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK);
// 2. alt + shift + control
runScenario(new int[]{KeyEvent.VK_ALT, KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL},
InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK);
// 3. shift
runScenario(new int[]{KeyEvent.VK_SHIFT},
InputEvent.SHIFT_DOWN_MASK);
// 4. alt + control
runScenario(new int[]{KeyEvent.VK_ALT, KeyEvent.VK_CONTROL},
InputEvent.ALT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK);
// 5. shift + alt
runScenario(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_ALT},
InputEvent.SHIFT_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
if (OS.contains("os x") || OS.contains("sunos")) {
// 6. meta
runScenario(new int[]{KeyEvent.VK_META}, InputEvent.META_DOWN_MASK);
// 7. shift + ctrl + alt + meta
runScenario(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL, KeyEvent.VK_ALT, KeyEvent.VK_META},
InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK | InputEvent.META_DOWN_MASK);
// 8. meta + shift + ctrl
runScenario(new int[]{KeyEvent.VK_META, KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL},
InputEvent.META_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK);
// 9. meta + shift + alt
runScenario(new int[]{KeyEvent.VK_META, KeyEvent.VK_SHIFT, KeyEvent.VK_ALT},
InputEvent.META_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
// 10. meta + ctrl + alt
runScenario(new int[]{KeyEvent.VK_META, KeyEvent.VK_CONTROL, KeyEvent.VK_ALT},
InputEvent.META_DOWN_MASK | InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
}
}
robot.waitForIdle();
frame.dispose();
}
public static void main(String[] args) throws Exception {
ExtendedModifiersTest test = new ExtendedModifiersTest();
test.doTest();
}
}

View File

@ -0,0 +1,219 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8043126
* @summary Check whether KeyEvent.getModifiers() returns correct modifiers
* when Ctrl, Alt or Shift keys are pressed.
*
* @library ../../../../../lib/testlibrary/ ../../helpers/lwcomponents/
* @build LWComponent
* @build LWButton
* @build LWList
* @build ExtendedRobot
* @run main/timeout=600 KeyMaskTest
*/
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import static jdk.testlibrary.Asserts.*;
import test.java.awt.event.helpers.lwcomponents.LWButton;
import test.java.awt.event.helpers.lwcomponents.LWList;
public class KeyMaskTest extends KeyAdapter {
Frame frame;
Button button;
LWButton buttonLW;
TextField textField;
TextArea textArea;
List list;
LWList listLW;
int buttonPressedNumber;
int buttonReleasedNumber;
ExtendedRobot robot;
private final static int robotDelay = 1500;
private final static int waitDelay = 3500;
final Object lock;
private boolean keyPressReceived = false;
private int keyCode = -1;
KeyMaskTest() throws Exception {
lock = new Object();
robot = new ExtendedRobot();
EventQueue.invokeAndWait( this::createGUI );
}
public void createGUI() {
frame = new Frame();
frame.setTitle("KeyMaskTest");
frame.setLayout(new GridLayout(1, 6));
button = new Button();
button.addKeyListener(this);
frame.add(button);
buttonLW = new LWButton();
buttonLW.addKeyListener(this);
frame.add(buttonLW);
textField = new TextField(5);
textField.addKeyListener(this);
frame.add(textField);
textArea = new TextArea(5, 5);
textArea.addKeyListener(this);
frame.add(textArea);
list = new List();
for (int i = 1; i <= 5; ++i) { list.add("item " + i); }
list.addKeyListener(this);
frame.add(list);
listLW = new LWList();
for (int i = 1; i <= 5; ++i) { listLW.add("item " + i); }
listLW.addKeyListener(this);
frame.add(listLW);
frame.setBackground(Color.gray);
frame.setSize(500, 100);
frame.setVisible(true);
frame.toFront();
}
@Override
public void keyPressed(KeyEvent e) {
keyPressReceived = true;
int code = e.getKeyCode();
assertEQ(code, keyCode, "wrong key code");
int mask = 0;
if (code == KeyEvent.VK_SHIFT) {
mask = InputEvent.SHIFT_MASK;
} else if (code == KeyEvent.VK_CONTROL) {
mask = InputEvent.CTRL_MASK;
} else if (code == KeyEvent.VK_ALT) {
mask = InputEvent.ALT_MASK;
} else if (code == KeyEvent.VK_META) {
mask = InputEvent.META_MASK;
}
int mod = e.getModifiers() & mask;
assertEQ(mod, mask, "invalid key mask");
synchronized (lock) { lock.notifyAll(); }
}
void doTest() throws Exception {
ArrayList<Component> components = new ArrayList();
components.add(button);
components.add(buttonLW);
components.add(textField);
components.add(textArea);
components.add(list);
components.add(listLW);
int keys[];
String OS = System.getProperty("os.name").toLowerCase();
System.out.println(OS);
if (OS.contains("os x") || OS.contains("sunos")) {
keys = new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL, KeyEvent.VK_ALT, KeyEvent.VK_META};
} else {
keys = new int[] {KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL, KeyEvent.VK_ALT};
}
for (Component c: components) {
System.out.print(c.getClass().getName() + ": ");
Point origin = c.getLocationOnScreen();
int xc = origin.x + c.getWidth() / 2;
int yc = origin.y + c.getHeight() / 2;
Point center = new Point(xc, yc);
robot.delay(robotDelay);
robot.glide(origin, center);
robot.click();
robot.delay(robotDelay);
for (int k = 0; k < keys.length; ++k) {
keyPressReceived = false;
keyCode = keys[k];
robot.type(keyCode);
robot.delay(robotDelay);
if (!keyPressReceived) {
synchronized (lock) {
try {
lock.wait(waitDelay);
} catch (InterruptedException e) {}
}
}
assertTrue(keyPressReceived, "key press event was not received");
}
System.out.println("passed");
}
robot.waitForIdle();
frame.dispose();
}
public static void main(String[] args) throws Exception {
KeyMaskTest test = new KeyMaskTest();
test.doTest();
}
}

View File

@ -0,0 +1,302 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import static jdk.testlibrary.Asserts.*;
import test.java.awt.event.helpers.lwcomponents.LWButton;
import test.java.awt.event.helpers.lwcomponents.LWList;
/*
* @test
* @bug 8043126
* @summary Check whether MouseEvent.getModifiers(), MouseEvent.getModifiersEx()
* and KeyEvent.getModifiers() return correct modifiers when pressing
* keys Ctrl, Alt, Shift, Meta and mouse buttons sequentially
*
* @library ../../../../../lib/testlibrary/ ../../helpers/lwcomponents/
* @build LWComponent
* @build LWButton
* @build LWList
* @build ExtendedRobot
* @run main/timeout=600 MouseButtonsAndKeyMasksTest
*/
public class MouseButtonsAndKeyMasksTest implements MouseListener, KeyListener {
Frame frame;
Button button;
LWButton buttonLW;
TextField textField;
TextArea textArea;
List list;
LWList listLW;
ExtendedRobot robot;
private final static int robotDelay = 1500;
private final static int keyDelay = 500;
private final static int waitDelay = 5000;
int modMouse = 0, modMouseEx = 0, modKey = 0, modAction = 0;
boolean mousePressFired = false;
boolean keyPressFired = false;
final Object lock;
MouseButtonsAndKeyMasksTest() throws Exception {
lock = new Object();
robot = new ExtendedRobot();
EventQueue.invokeAndWait( this::createGUI );
}
public void createGUI() {
frame = new Frame();
frame.setTitle("MouseButtonsAndKeysTest");
frame.setLayout(new GridLayout(1, 6));
button = new Button();
button.addKeyListener(this);
button.addMouseListener(this);
frame.add(button);
buttonLW = new LWButton();
buttonLW.addKeyListener(this);
buttonLW.addMouseListener(this);
frame.add(buttonLW);
textField = new TextField(5);
textField.addKeyListener(this);
textField.addMouseListener(this);
frame.add(textField);
textArea = new TextArea(5, 5);
textArea.addKeyListener(this);
textArea.addMouseListener(this);
frame.add(textArea);
list = new List();
for (int i = 1; i <= 5; ++i) { list.add("item " + i); }
list.addKeyListener(this);
list.addMouseListener(this);
frame.add(list);
listLW = new LWList();
for (int i = 1; i <= 5; ++i) { listLW.add("item " + i); }
listLW.addKeyListener(this);
listLW.addMouseListener(this);
frame.add(listLW);
frame.setBackground(Color.gray);
frame.setSize(500, 80);
frame.setVisible(true);
frame.toFront();
}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {
modMouse = e.getModifiers();
modMouseEx = e.getModifiersEx();
mousePressFired = true;
synchronized (lock) { lock.notifyAll(); }
}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { return; }
keyPressFired = true;
modKey = e.getModifiers();
synchronized (lock) { lock.notifyAll(); }
}
@Override
public void keyReleased(KeyEvent e) {}
void doTest() throws Exception {
int buttons[] = new int[]{
InputEvent.BUTTON1_MASK, InputEvent.BUTTON2_MASK, InputEvent.BUTTON3_MASK};
int buttonsEx[] = new int[]{
InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK};
String OS = System.getProperty("os.name").toLowerCase();
System.out.println(OS);
int keyMods[], keyModsEx[], keys[];
if (OS.contains("linux")) {
keyMods = new int[]{InputEvent.SHIFT_MASK, InputEvent.CTRL_MASK};
keyModsEx = new int[]{InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK};
keys = new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL};
} else if (OS.contains("os x")) {
keyMods = new int[]{
InputEvent.SHIFT_MASK, InputEvent.CTRL_MASK, InputEvent.ALT_MASK, InputEvent.META_MASK};
keyModsEx = new int[]{
InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK, InputEvent.ALT_DOWN_MASK, InputEvent.META_DOWN_MASK};
keys = new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL, KeyEvent.VK_ALT, KeyEvent.VK_META};
} else if (OS.contains("sunos")) {
keyMods = new int[]{InputEvent.SHIFT_MASK, InputEvent.META_MASK};
keyModsEx = new int[]{InputEvent.SHIFT_DOWN_MASK, InputEvent.META_DOWN_MASK};
keys = new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_META};
} else {
keyMods = new int[]{
InputEvent.SHIFT_MASK, InputEvent.CTRL_MASK, InputEvent.ALT_MASK};
keyModsEx = new int[]{
InputEvent.SHIFT_DOWN_MASK, InputEvent.CTRL_DOWN_MASK, InputEvent.ALT_DOWN_MASK};
keys = new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_CONTROL, KeyEvent.VK_ALT};
}
ArrayList<Component> components = new ArrayList();
components.add(button);
components.add(buttonLW);
components.add(textField);
components.add(textArea);
components.add(list);
components.add(listLW);
for (Component c: components) {
System.out.println(c.getClass().getName() + ":");
Point origin = c.getLocationOnScreen();
int xc = origin.x + c.getWidth() / 2;
int yc = origin.y + c.getHeight() / 2;
Point center = new Point(xc, yc);
robot.delay(robotDelay);
robot.glide(origin, center);
robot.click();
robot.delay(robotDelay);
for (int b = 0; b < buttons.length; ++b) {
int btn = buttons[b];
for (int k = 0; k < keys.length; ++k) {
int key = keys[k];
System.out.print(KeyEvent.getKeyText(key) + " + button " + (b + 1));
robot.delay(robotDelay);
robot.keyPress(key);
robot.delay(keyDelay);
if (!keyPressFired) {
synchronized (lock) {
try {
lock.wait(waitDelay);
} catch (InterruptedException ex) {}
}
}
if (!keyPressFired) {
robot.keyRelease(key);
assertTrue(false, "key press event was not received");
}
robot.mousePress(btn);
robot.delay(robotDelay);
if (!mousePressFired) {
synchronized (lock) {
try {
lock.wait(waitDelay);
} catch (InterruptedException ex) {}
}
}
assertTrue(mousePressFired, "mouse press event was not received");
robot.mouseRelease(btn);
robot.delay(robotDelay);
// do checks
assertEQ(modMouse & btn, btn, "invalid mouse button mask");
assertEQ(modKey & keyMods[k], keyMods[k], "invalid key mask");
assertEQ(buttonsEx[b] | keyModsEx[k], modMouseEx, "invalid extended modifiers");
mousePressFired = false;
keyPressFired = false;
robot.keyRelease(key);
robot.delay(keyDelay);
robot.type(KeyEvent.VK_ESCAPE);
robot.delay(robotDelay);
System.out.println(" - passed");
}
}
}
robot.waitForIdle();
frame.dispose();
}
public static void main(String[] args) throws Exception {
MouseButtonsAndKeyMasksTest test = new MouseButtonsAndKeyMasksTest();
test.doTest();
}
}

View File

@ -0,0 +1,254 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import test.java.awt.event.helpers.lwcomponents.LWButton;
import test.java.awt.event.helpers.lwcomponents.LWList;
import java.util.ArrayList;
import static jdk.testlibrary.Asserts.*;
/*
* @test
* @bug 8043126
* @summary Check whether getButton() returns correct mouse button
* number when the mouse buttons are pressed and getModifiers()
* returns correct modifiers
*
* @library ../../../../../lib/testlibrary/ ../../helpers/lwcomponents/
* @build LWComponent
* @build LWButton
* @build LWList
* @build ExtendedRobot
* @run main/timeout=600 MouseButtonsTest
*/
public class MouseButtonsTest implements MouseListener {
private Frame frame;
private Button button;
private LWButton buttonLW;
private TextField textField;
private TextArea textArea;
private List list;
private LWList listLW;
private int buttonPressedNumber = 0;
private int buttonReleasedNumber = 0;
private int modifiers = 0;
private final ExtendedRobot robot;
private final static int robotDelay = 1000;
private final static int waitDelay = 3500;
private boolean released = false;
private boolean pressed = false;
private final Object lock;
MouseButtonsTest() throws Exception {
lock = new Object();
robot = new ExtendedRobot();
EventQueue.invokeAndWait( this::createGUI );
}
public void createGUI() {
frame = new Frame();
frame.setTitle("MouseButtonsTest");
frame.setLayout(new GridLayout(1, 6));
button = new Button();
button.addMouseListener(this);
frame.add(button);
buttonLW = new LWButton();
buttonLW.addMouseListener(this);
frame.add(buttonLW);
textField = new TextField(5);
textField.addMouseListener(this);
frame.add(textField);
textArea = new TextArea(5, 5);
textArea.addMouseListener(this);
frame.add(textArea);
list = new List();
for (int i = 1; i <= 5; ++i) { list.add("item " + i); }
list.addMouseListener(this);
frame.add(list);
listLW = new LWList();
for (int i = 1; i <= 5; ++i) { listLW.add("item " + i); }
listLW.addMouseListener(this);
frame.add(listLW);
frame.setBackground(Color.gray);
frame.setSize(500, 100);
frame.setVisible(true);
frame.toFront();
}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {
assertFalse(e.getButton() == MouseEvent.NOBUTTON, "invalid button");
buttonPressedNumber = e.getButton();
modifiers = e.getModifiers();
pressed = true;
synchronized (lock) {
try {
lock.notifyAll();
} catch (Exception ex) {}
}
}
@Override
public void mouseReleased(MouseEvent e) {
assertFalse(e.getButton() == MouseEvent.NOBUTTON, "invalid button");
buttonReleasedNumber = e.getButton();
modifiers = e.getModifiers();
released = true;
synchronized (lock) {
try {
lock.notifyAll();
} catch (Exception ex) {}
}
}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
void doTest() throws Exception {
int masks[] = new int[]{
InputEvent.BUTTON1_MASK, InputEvent.BUTTON2_MASK, InputEvent.BUTTON3_MASK};
int buttons[] = new int[]{
MouseEvent.BUTTON1, MouseEvent.BUTTON2, MouseEvent.BUTTON3};
ArrayList<Component> components = new ArrayList();
components.add(button);
components.add(buttonLW);
components.add(textField);
components.add(textArea);
components.add(list);
components.add(listLW);
for (Component c: components) {
System.out.println(c.getClass().getName() + ":");
Point origin = c.getLocationOnScreen();
int xc = origin.x + c.getWidth() / 2;
int yc = origin.y + c.getHeight() / 2;
Point center = new Point(xc, yc);
robot.delay(robotDelay);
robot.glide(origin, center);
robot.click();
robot.delay(robotDelay);
for (int i = 0; i < masks.length; ++i) {
pressed = false;
released = false;
int mask = masks[i];
robot.mousePress(mask);
robot.delay(robotDelay);
if (!pressed) {
synchronized (lock) {
try {
lock.wait(waitDelay);
} catch (InterruptedException ex) {}
}
}
assertTrue(pressed, "mouse press event was not received");
assertEQ((modifiers & mask), mask, "invalid mask modifiers");
robot.mouseRelease(mask);
robot.delay(robotDelay);
if (!released) {
synchronized (lock) {
try {
lock.wait(waitDelay);
} catch (InterruptedException ex) {}
}
}
assertTrue(released, "mouse release event was not received");
assertEQ((modifiers & mask), mask, "invalid mask modifiers");
assertEquals(buttonPressedNumber, buttons[i]);
assertEquals(buttonReleasedNumber, buttons[i]);
robot.type(KeyEvent.VK_ESCAPE);
robot.delay(robotDelay);
System.out.println("button " + buttons[i] + " - passed");
}
}
robot.waitForIdle();
frame.dispose();
}
public static void main(String[] args) throws Exception {
MouseButtonsTest test = new MouseButtonsTest();
test.doTest();
}
}

View File

@ -0,0 +1,237 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import test.java.awt.event.helpers.lwcomponents.LWButton;
import test.java.awt.event.helpers.lwcomponents.LWList;
import static jdk.testlibrary.Asserts.*;
/*
* @test
* @bug 8043126
* @summary Check whether correct modifiers set when multiple mouse buttons were pressed;
* check number of received events.
*
* @library ../../../../../lib/testlibrary/ ../../helpers/lwcomponents/
* @build LWComponent
* @build LWButton
* @build LWList
* @build ExtendedRobot
* @run main/timeout=600 MultipleMouseButtonsTest
*/
public class MultipleMouseButtonsTest implements MouseListener {
private final static int robotDelay = 1000;
private final ExtendedRobot robot;
private final Object lock = new Object();
private Frame frame;
private Button button;
private LWButton buttonLW;
private TextField textField;
private TextArea textArea;
private List list;
private LWList listLW;
private int eventCount;
private int testCount;
private boolean pressed = false;
private int modifiers = 0;
private int modifiersEx = 0;
private boolean countEvents = false;
public void createGUI() {
frame = new Frame("MultipleMouseButtonTest");
frame.setLayout(new GridLayout(1, 6));
button = new Button();
button.addMouseListener(this);
frame.add(button);
buttonLW = new LWButton();
buttonLW.addMouseListener(this);
frame.add(buttonLW);
textField = new TextField(5);
textField.addMouseListener(this);
frame.add(textField);
textArea = new TextArea(5, 5);
textArea.addMouseListener(this);
frame.add(textArea);
list = new List();
for (int i = 1; i <= 5; ++i) { list.add("item " + i); }
list.addMouseListener(this);
frame.add(list);
listLW = new LWList();
for (int i = 1; i <= 5; ++i) { listLW.add("item " + i); }
listLW.addMouseListener(this);
frame.add(listLW);
frame.setBackground(Color.gray);
frame.setSize(500, 100);
frame.setVisible(true);
frame.toFront();
}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited (MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {
if (!countEvents) { return; }
++eventCount;
pressed = true;
modifiers = e.getModifiers();
modifiersEx = e.getModifiersEx();
synchronized (lock) { lock.notifyAll(); }
}
@Override
public void mouseReleased(MouseEvent e) {
if (countEvents) {
++eventCount;
}
}
MultipleMouseButtonsTest() throws Exception {
this.robot = new ExtendedRobot();
EventQueue.invokeAndWait( this::createGUI );
}
void doTest() throws Exception {
int masks[] = new int[]{InputEvent.BUTTON1_MASK, InputEvent.BUTTON2_MASK, InputEvent.BUTTON3_MASK};
int masksEx[] = new int[]{InputEvent.BUTTON1_DOWN_MASK, InputEvent.BUTTON2_DOWN_MASK, InputEvent.BUTTON3_DOWN_MASK};
robot.waitForIdle();
ArrayList<Component> components = new ArrayList();
components.add(button);
components.add(buttonLW);
components.add(textField);
components.add(textArea);
components.add(list);
components.add(listLW);
for (Component c: components) {
System.out.println(c.getClass().getName() + ": ");
Point origin = c.getLocationOnScreen();
int xc = origin.x + c.getWidth() / 2;
int yc = origin.y + c.getHeight() / 2;
Point center = new Point(xc, yc);
robot.delay(robotDelay);
robot.mouseMove(origin);
robot.delay(robotDelay);
robot.glide(origin, center);
robot.delay(robotDelay);
robot.click();
robot.delay(robotDelay);
testCount = 0;
eventCount = 0;
for (int i = 0; i < masks.length; ++i) {
for (int k = 0; k < masks.length; ++k) {
if (k == i) { continue; }
countEvents = false;
robot.mousePress(masks[i]);
robot.delay(robotDelay);
countEvents = true;
pressed = false;
robot.mousePress(masks[k]);
robot.delay(robotDelay);
++testCount;
if (!pressed) {
synchronized (lock) {
try {
lock.wait(3 * robotDelay);
} catch (InterruptedException ex) {}
}
}
assertTrue(pressed, "mouse press event was not received");
assertEQ(modifiers & masks[k], masks[k], "invalid modifiers");
assertEQ(modifiersEx & masksEx[i], masksEx[i], "invalid extended modifiers");
robot.mouseRelease(masks[k]);
robot.delay(robotDelay);
++testCount;
countEvents = false;
robot.mouseRelease(masks[i]);
robot.delay(robotDelay);
robot.type(KeyEvent.VK_ESCAPE);
robot.delay(robotDelay);
} //k
} //i
assertEquals(testCount, eventCount, "different amount of sent and received events");
System.out.println("passed");
} //component
robot.waitForIdle();
frame.dispose();
}
public static void main(String[] args) throws Exception {
MultipleMouseButtonsTest test = new MultipleMouseButtonsTest();
test.doTest();
}
}

View File

@ -0,0 +1,418 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.java.awt.event.helpers.lwcomponents;
import java.awt.*;
import java.awt.event.*;
/**
* Lightweight <i>Button</i> component with some nice features. This
* component provides the capabilities of Buttons, namely that you it
* displays a label string and, when clicked, causes the
* ActionListener method to be called.<p>
*
* The look of the button is a little unusual. There are three
* rectangles drawn at the border that indicate various states
* of the button. These are (listed from outside in)<p>
* <ol>
* <li><b>Focus</b>: Indicates that the LWButton has the focus.
* <li><b>Mouse Over</b>: Indicates that the mouse is over the component.
* <li><b>Mouse Pressed</b>: Indicates that the mouse has been pressed.
* </ol>
*
* In addition, when the button has been activated (mouse clicked or
* via keyboard activation) the button flashes briefly.
*/
public class LWButton extends LWComponent {
/*
* The button's Label.
* If Label is not specified it will default to "".
* @serial
* @see getLabel()
* @see setLabel()
*/
private String label;
private boolean isInClick = false;
private static final String base = "LWButton";
private static int nameCounter = 0;
private transient ActionListener actionListener;
/*
* The action to be performaed once a button has been
* pressed.
* actionCommand can be null.
* @serial
* @see getActionCommand()
* @see setActionCommand()
*/
String actionCommand;
Color colMousePressed;
public LWButton() { this(""); }
public LWButton(String label) {
this(label, Color.red, Color.green, Color.white);
}
/**
* Initialize the LWButton, fully specifying all parameters.
* @param label The string to display.
* @param fgnd The color to draw the label in.
* @param bkgnd The color of the button itself.
* @param mousePressed The Color of the MousePressed rectangle.
*/
public LWButton(String label, Color fgnd, Color bkgnd, Color mousePressed) {
super();
this.label = label;
setBackground(fgnd);
setForeground(bkgnd);
colMousePressed = mousePressed;
setName(makeComponentName());
enableEvents( AWTEvent.MOUSE_EVENT_MASK
| AWTEvent.KEY_EVENT_MASK
| AWTEvent.ACTION_EVENT_MASK);
setEnabled(true);
}
/**
* Make the component flash briefly.
*/
public void flash() {
isInClick = true;
repaint();
class unClicker implements Runnable {
@Override
public void run() {
try { Thread.sleep(100); } catch (InterruptedException ee) {}
isInClick = false;
repaint();
}
}
try {
unClicker uc = new unClicker();
new Thread(uc).start();
} catch (Exception e) {
// In case we're in an applet and the security has not been
// turned off (in which case we can't start a new thread)
// we can catch that and set the flag back to how it should be.
isInClick = false;
repaint();
}
}
/**
* Set the MousePressed color (the color shown in the MousePressed rectangle
* when the mouse is over the component).
* @param c The color of the MousePressed rectangle.
*/
public void setMousePressedColor(Color c) { colMousePressed = c; }
/**
* Get the MousePressed color.
* @return The color of the MousePressed rectangle.
*/
public Color getMousePressedColor() { return colMousePressed; }
/**
* Used to dispatch out the ActionEvent for a corresponding InputEvent.
* @param e The InputEvent that is causing the ActionEvent dispatch.
*/
private void sendActionEvent(InputEvent e) {
int modifiers = e.getModifiers();
int aModifiers = 0;
if ((modifiers & MouseEvent.SHIFT_MASK) != 0) {
aModifiers |= ActionEvent.SHIFT_MASK;
}
if ((modifiers & MouseEvent.CTRL_MASK) != 0) {
aModifiers |= ActionEvent.CTRL_MASK;
}
if ((modifiers & MouseEvent.META_MASK) != 0) {
aModifiers |= ActionEvent.META_MASK;
}
if ((modifiers & MouseEvent.ALT_MASK) != 0) {
aModifiers |= ActionEvent.ALT_MASK;
}
ActionEvent ae = new ActionEvent(this,
ActionEvent.ACTION_PERFORMED,
actionCommand,
aModifiers);
// XXX: What's the right way to send out the ActionEvent?
// My assumption was to put it into the system event queue
// and the it will be dispatched back into <i>processEvent</i>
// for us. However this doesn't happen...?
if (actionListener != null) {
actionListener.actionPerformed(ae);
}
//Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae);
}
/**
* Set whether the component is enabled ({@code true}) or not.
* @param enabled If {@code true}, the component is to be enabled.
*/
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
if (enabled) {
enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
} else {
disableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
repaint(1);
}
/**
* Indicates that LWButton component can receive focus.
* @return {@code true} if the LWButton component can receive focus
*/
@Override
public boolean isFocusTraversable() { return true; }
/**
* Construct a name for this component. Called by getName() when the
* name is null.
*/
String makeComponentName() {
synchronized (getClass()) {
return base + nameCounter++;
}
}
/**
* Handle painting the enabled version of the component.
*
* ASSUMES: g.color may be changed
*/
@Override
public void paint(Graphics g) {
super.paint(g);
restrictGraphicsToClientArea(g);
Dimension dim = getClientSize();
int s = Math.min(dim.width - 1, dim.height - 1);
if (isInClick) {
g.setColor(Color.white);
} else {
g.setColor(getBackground());
}
// In jdk 1.2 (pre-release) there was a bug using clearRect
// to paint the background of a lightweight.
//g.clearRect(loc.x, loc.y, dim.width, dim.height);
g.fillRect(0, 0, dim.width, dim.height);
if (mouseB1Pressed) {
g.setColor(colMousePressed);
//LWComponent.traceMsg("paint mousePressed " + this.toString());
g.drawRect(1, 1, dim.width - 3, dim.height - 3);
}
Font f = getFont();
if (f != null) {
FontMetrics fm = getFontMetrics(f);
g.setColor(getForeground());
g.drawString(label,
s/2 - fm.stringWidth(label)/2,
s/2 + fm.getMaxDescent());
}
unrestrictGraphicsFromClientArea(g);
}
@Override
public Dimension getPreferredSize() {
Font f = getFont();
if (f != null) {
FontMetrics fm = getFontMetrics(f);
int max = Math.max(fm.stringWidth(label) + 40, fm.getHeight() + 40);
return new Dimension(max, max);
} else {
return new Dimension(100, 100);
}
}
@Override
public Dimension getMinimumSize() {
return getPreferredSize();
}
/**
* Get the text displayed in the LWButton.
* @return the text displayed in the LWButton
*/
public String getText() { return label; }
/**
* Set the text displayed in the LWButton.
* @param s The text to be displayed.
*/
public void setText(String s) {
Font f = getFont();
int oWidth = 0;
int oHeight = 0;
int nWidth = 0;
int nHeight = 0;
int invalidated = 0;
FontMetrics fm = null;
if (f != null) {
fm = getFontMetrics(f);
oWidth = fm.stringWidth(label);
oHeight = fm.getHeight();
}
this.label = s;
if (f != null) {
nWidth = fm.stringWidth(label);
nHeight = fm.getHeight();
if ((nWidth > oWidth) || (nHeight > oHeight)) {
invalidate();
invalidated = 1;
}
}
if (invalidated == 0) {
repaint();
}
}
/**
* Set the command name for the action event fired
* by this button. By default this action command is
* set to match the label of the button.
* @param command A string used to set the button's
* action command.
* If the string is <code>null</code> then the action command
* is set to match the label of the button.
* @see java.awt.event.ActionEvent
* @since JDK1.1
*/
public void setActionCommand(String command) {
actionCommand = command;
}
/**
* Returns the command name of the action event fired by this button.
* If the command name is {@code null} (default) then this method
* returns the label of the button.
*
* @return the command name of the action event fired by this button
* or the label of the button (in case of {@code null})
*/
public String getActionCommand() {
return (actionCommand == null? label : actionCommand);
}
/**
* Add the specified action listener to receive action events from
* this button. Action events occur when a user presses or releases
* the mouse over this button.
* @param l the action listener.
* @see java.awt.event.ActionListener
* @see #removeActionListener
* @since JDK1.1
*/
public synchronized void addActionListener(ActionListener l) {
actionListener = AWTEventMulticaster.add(actionListener, l);
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
}
/**
* Remove the specified action listener so that it no longer
* receives action events from this button. Action events occur
* when a user presses or releases the mouse over this button.
* @param l the action listener.
* @see java.awt.event.ActionListener
* @see #addActionListener
* @since JDK1.1
*/
public synchronized void removeActionListener(ActionListener l) {
actionListener = AWTEventMulticaster.remove(actionListener, l);
}
@Override
protected void processKeyEvent(KeyEvent e) {
super.processKeyEvent(e);
if (!isEnabled()) { return; }
switch(e.getID()) {
case KeyEvent.KEY_TYPED:
switch (e.getKeyCode()) {
case KeyEvent.VK_ENTER:
case KeyEvent.VK_SPACE:
flash();
sendActionEvent(e);
break;
}
break;
}
}
@Override
protected void processMouseEvent(MouseEvent e) {
super.processMouseEvent(e);
if (!isEnabled()) { return; }
switch(e.getID()) {
case MouseEvent.MOUSE_PRESSED:
requestFocus();
repaint();
break;
case MouseEvent.MOUSE_RELEASED:
repaint();
break;
case MouseEvent.MOUSE_CLICKED:
if ((e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0) {
flash();
sendActionEvent(e);
}
break;
}
}
/**
* Returns the parameter string representing the state of this
* button. This string is useful for debugging.
* @return the parameter string of this button.
*/
@Override
protected String paramString() {
return super.paramString() + ", label = " + label;
}
}

View File

@ -0,0 +1,464 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.java.awt.event.helpers.lwcomponents;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
/**
* This is experimental - The idea is to subclass all the LW components
* from LWComponent to provide for some common capabilities. The main
* capability to be provided is the status rectangles as done for LWButton.
* In particular the Focus and MouseOver rectangles are generically
* useful, while other rectangles might be useful to other components.<p>
*
* To implement that, here is the idea ... borrowed from Win32 ... Each
* of the LW components has both a client and non-client region. We
* call paintNC to paint the non-client region (Focus and MouseOver
* rectangles), and the subclass might be permitted to implement paintNC
* but for now they aren't.<p>
*
* Then the paint{Enabled,Disabled} methods are called as appropriate.
* Note that paintDisabled is implemented in LWComponent to call paintEnabled
* then stipple over the top of it.<p>
*
* So it is paintEnabled that the component should implement. This method
* needs to know the dimensions of the client area (getClientRegion?) and
* the Graphics needs to have it's clip region set appropriately.<p>
*
* <b>KVETCHING</b>: <i>Kvetch</i> is a Yiddish word which means, basically,
* to complain very precisely. The LWComponent family tracks various pieces
* of information over time that are used to check closely for correct behavior
* in some circumstances. The method <i>kvetch</i> is where this code lives
* and is intended to check a broad range of conditions.<p>
*
* To turn off specific kvetch's, one simply specifies a System property
* as in this table:<p>
*
* <table border="1">
* <tr><th>Property name</th><th>Value</th><th>Discussion</th></tr>
* <tr>
* <th>javasoft.awtsqe.lw.IGNORE_FOCUS_KVETCH</th>
* <th>true or false</th>
* <td>Specify whether the <i>hasFocus</i> kvetch is checked.</td>
* </tr>
* </table><p>
*
* <b>XXX To implement</b> - specifying colors. NCBackground,
* FocusRectColor, MouseOverColor are the threee colors. paintNC
* fills the NC region with NCBackground, and then pains the two
* colors as appropriate. There needs to be methods to get/specify
* these colors.<p>
*
* <b>XXX To implement</b> - Specifying the component name and toString().
* The subclass should only give the base class name, and a method
* in LWComponent should construct a name from that. For toString()
* there needs to be a small amount of infrastructure built.<p>
*/
public abstract class LWComponent extends Component {
protected static Color ncBackgroundColor;
protected static Color focusColor;
protected static Color focusWrongColor;
protected static Color mouseOverColor;
static {
ncBackgroundColor = Color.white;
focusColor = Color.black;
focusWrongColor = Color.magenta;
mouseOverColor = Color.blue;
}
/**
* Flag indicating whether our records indicate that the component
* should have focus.
*/
protected boolean _shouldHaveFocus = false;
protected boolean _shouldBeShowing = false;
protected boolean mouseB1Pressed = false;
protected boolean mouseB2Pressed = false;
protected boolean mouseB3Pressed = false;
protected boolean mouseInside = false;
protected static boolean tracingOn = false;
protected static PrintStream traceOutput = null;
// Uncommenting these lines turns on tracing for the package.
// static {
// tracingOn = true;
// traceOutput = System.err;
// }
public LWComponent() {
enableEvents(AWTEvent.MOUSE_EVENT_MASK
/*| AWTEvent.MOUSE_MOTION_EVENT_MASK*/
| AWTEvent.FOCUS_EVENT_MASK
| AWTEvent.COMPONENT_EVENT_MASK);
}
/**
* Print out an error message.
* @param msg the message
*/
public static void errorMsg(String msg) {
System.err.println("ERROR: " + msg);
}
/**
* Print out a tracing message
* @param msg the message
*/
public static void traceMsg(String msg) {
if (LWComponent.tracingOn) {
LWComponent.traceOutput.println(msg);
}
}
/////////////////////////////////////////////
/////// FLAGS FOR IGNORING KVETCH's /////////
/////////////////////////////////////////////
static boolean bIgnFocus = false;
static {
// Initialize the kvetch ignoring flags here.
String ignFocus = System.getProperty("javasoft.awtsqe.lw.IGNORE_FOCUS_KVETCH",
"false");
bIgnFocus = ignFocus.trim().toLowerCase().equals("true");
}
/**
* Check the <i>shoulds</i> and return a string indicating which
* do not match the components actual state.
*
* @return the string indicating which do not match the components actual state
*/
public String kvetch() {
String ret = this.toString();
boolean errors = false;
if (!bIgnFocus) {
if (hasFocus()) {
if (!shouldHaveFocus()) {
ret += "\nERROR: hasFocus indicates we have Focus, when we shouldn't.";
errors = true;
}
} else {
if (shouldHaveFocus()) {
ret += "\nERROR: (see bug#4233658) hasFocus does not indicate we have Focus, when we should.";
errors = true;
}
}
}
if (errors) {
return ret;
} else {
return null;
}
}
/**
* Check the <i>shoulds</i> and return a string indicating which
* do not match the components actual state. Prints the output
* to the given PrintStream.
* @param out The PrintStream to print to.
*/
public void kvetch(PrintStream out) {
if (out != null) {
String s = kvetch();
if (s != null) {
LWComponent.errorMsg(s);
}
}
}
/**
* Turn on tracing for the LWComponent family.
* @param out the output stream
*/
public static void startTracing(PrintStream out) {
tracingOn = true;
traceOutput = out;
}
/**
* Turn off tracing for the LWComponent family.
*/
public static void stopTracing() { tracingOn = false; traceOutput = null; }
/**
* Indicate whether it is believed the component should have focus.
* @return {@code true} if the component should have focus
*/
public boolean shouldHaveFocus() { return _shouldHaveFocus; }
/**
* Indicate whether it is believed the component should be showing.
* @return {@code true} if the component should be showing
*/
public boolean shouldBeShowing() { return _shouldBeShowing; }
@Override
protected void processFocusEvent(FocusEvent e) {
super.processFocusEvent(e);
LWComponent.traceMsg("processFocusEvent " + e.toString());
switch (e.getID()) {
case FocusEvent.FOCUS_GAINED:
_shouldHaveFocus = true;
repaint();
break;
case FocusEvent.FOCUS_LOST:
_shouldHaveFocus = false;
repaint();
break;
}
}
@Override
protected void processComponentEvent(ComponentEvent e) {
super.processComponentEvent(e);
LWComponent.traceMsg("processComponentEvent " + e.toString());
switch (e.getID()) {
case ComponentEvent.COMPONENT_MOVED: break;
case ComponentEvent.COMPONENT_RESIZED: break;
case ComponentEvent.COMPONENT_SHOWN: _shouldBeShowing = true; break;
case ComponentEvent.COMPONENT_HIDDEN: _shouldBeShowing = false; break;
}
}
@Override
protected void processMouseEvent(MouseEvent e) {
int mod = e.getModifiers();
super.processMouseEvent(e);
LWComponent.traceMsg("processMouseEvent " + e.toString());
switch (e.getID()) {
case MouseEvent.MOUSE_PRESSED:
if ((mod & MouseEvent.BUTTON1_MASK) != 0) {
if (mouseB1Pressed) {
errorMsg("ERROR: MOUSE_PRESSED for B1 when already pressed, on "
+ this.toString());
}
mouseB1Pressed = true;
break;
}
if ((mod & MouseEvent.BUTTON2_MASK) != 0) {
if (mouseB2Pressed) {
errorMsg("ERROR: MOUSE_PRESSED for B2 when already pressed, on "
+ this.toString());
}
mouseB2Pressed = true;
break;
}
if ((mod & MouseEvent.BUTTON3_MASK) != 0) {
if (mouseB3Pressed) {
errorMsg("ERROR: MOUSE_PRESSED for B3 when already pressed, on "
+ this.toString());
}
mouseB3Pressed = true;
break;
}
repaint();
break;
case MouseEvent.MOUSE_RELEASED:
if ((mod & MouseEvent.BUTTON1_MASK) != 0) {
if (!mouseB1Pressed) {
errorMsg("ERROR: MOUSE_RELEASED for B1 when not pressed, on "
+ this.toString());
}
mouseB1Pressed = false;
break;
}
if ((mod & MouseEvent.BUTTON2_MASK) != 0) {
if (!mouseB2Pressed) {
errorMsg("ERROR: MOUSE_RELEASED for B2 when not pressed, on "
+ this.toString());
}
mouseB2Pressed = false;
break;
}
if ((mod & MouseEvent.BUTTON3_MASK) != 0) {
if (!mouseB3Pressed) {
errorMsg("ERROR: MOUSE_RELEASED for B3 when not pressed, on "
+ this.toString());
}
mouseB3Pressed = false;
break;
}
repaint();
break;
case MouseEvent.MOUSE_CLICKED:
break;
case MouseEvent.MOUSE_ENTERED:
if (mouseInside) {
errorMsg("ERROR: MOUSE_ENTERED when mouse already inside component, on "
+ this.toString());
}
mouseInside = true;
repaint();
break;
case MouseEvent.MOUSE_EXITED:
if (!mouseInside) {
errorMsg("ERROR: MOUSE_EXITED when mouse not inside component, on "
+ this.toString());
}
mouseInside = false;
repaint();
break;
case MouseEvent.MOUSE_MOVED:
break;
case MouseEvent.MOUSE_DRAGGED:
break;
}
}
public Point getClientLocation() {
return new Point(5, 5);
}
public Dimension getClientSize() {
Dimension dim = getSize();
dim.width -= 10;
dim.height -= 10;
return dim;
}
public Rectangle getClientBounds() {
Dimension dim = getClientSize();
return new Rectangle(5, 5, dim.width, dim.height);
}
public int getClientX() { return 5; }
public int getClientY() { return 5; }
/**
* Set the color used for painting the non-client area of the component.
* The default for this is Color.white.
*
* @param c The new color to use.
*/
public void setNonClientColor(Color c) {
LWComponent.ncBackgroundColor = c;
}
/**
* Handle painting for the component.
*/
@Override
public void paint(Graphics g) {
Dimension dim = getSize();
kvetch(System.err);
Color saveColor = g.getColor();
super.paint(g);
// ------------------- Paint the background -----------------
// In jdk 1.2 (pre-release) there was a bug using clearRect
// to paint the background of a lightweight.
//g.clearRect(0, 0, dim.width, dim.height);
g.setColor(getBackground());
g.fillRect(0, 0, dim.width, dim.height);
// ------------------- Paint the non-client area ------------
g.setColor(ncBackgroundColor);
// x y width height
g.fillRect(0, 0, dim.width, 5);
g.fillRect(0, 5, 5, dim.height - 10);
g.fillRect(dim.width - 5, 5, 5, dim.height - 10);
g.fillRect(0, dim.height - 5, dim.width, 5);
if (shouldHaveFocus() || hasFocus()) {
g.setColor(shouldHaveFocus() && hasFocus()
? focusColor
: focusWrongColor);
g.drawRect(1, 1, dim.width - 3, dim.height - 3);
}
if (mouseInside) {
g.setColor(mouseOverColor);
g.drawRect(3, 3, dim.width - 7, dim.height - 7);
}
// ------------------- Paint disabledness, if true -----------
if (!isEnabled()) {
g.setColor(getBackground());
Dimension size = getSize();
int borderThickness = 0;
int startX = borderThickness;
int startY = borderThickness;
int endX = startX + size.width - 2 * borderThickness - 2;
int endY = startY + size.height - 2 * borderThickness - 2;
int x, y;
for (y = startY; y <= endY; y += 1) {
for (x = startX + (y % 2); x <= endX; x += 2) {
g.fillRect(x, y, 1, 1);
} // x
} // y
}
g.setColor(saveColor);
}
/**
* Restricts the Graphics to be within the "client area" of the
* component. Recall that the LWComponent series of components has
* a "non-client area" of 5 pixels wide in which it draws two
* status rectangles showing mouse-over and has-focus status. <p>
*
* Child classes of LWComponent are to call {@code restrictGraphicsToClientArea}
* at the beginning of their {@code paint} method, and then call
* {@code unrestrictGraphicsFromClientArea} afterwards.<p>
*
* In order to make those paint methods as convenient as possible, these
* two methods make it appear as if the Graphics available to the
* component is slightly smaller than it really is, by the amount
* used in the non-client area (5 pixel wide border).<p>
*
* @param g The Graphics to restrict.
*/
public void restrictGraphicsToClientArea(Graphics g) {
Dimension dim = getSize();
g.translate(5, 5);
g.setClip(0, 0, dim.width - 10, dim.height - 10);
}
/**
* Undo the restriction done in restrictGraphicsToClientArea.
*
* @param g The Graphics to unrestrict.
*/
public void unrestrictGraphicsFromClientArea(Graphics g) {
g.translate(-5, -5);
Dimension dim = getSize();
g.setClip(0, 0, dim.width, dim.height);
}
}

View File

@ -0,0 +1,726 @@
/*
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.java.awt.event.helpers.lwcomponents;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import java.util.Enumeration;
/**
* Remarks : Source for LightWeight component - List.
*
* Scroll bar support is not available for this component, so if the
* items exceeds visibility those items will be truncated. Also, here
* double buffering is not used so there will be little bit flickering
* while it repaints. Item listener support is not enabled in this
* component. Listeners handled were Mouse, Key and Focus.
*
* @author R.Govindarajan (govind@siptech.co.in), G.N.V.Sekhar (sekharv@siptech.co.in)
*/
public class LWList extends LWComponent implements ItemSelectable {
// Constants used for component size
private final int MIN_WIDTH = 100;
private final int MIN_HEIGHT = 100;
private final int PREF_WIDTH = 100;
private final int PREF_HEIGHT = 100;
// Constants used for setting color for component
private final Color BACK_COLOR = Color.white;
private final Color FRONT_COLOR = Color.black;
private final Color BORDER_COLOR = Color.darkGray;
private final Color FOCUS_COLOR = Color.blue;
private final Color FOCUS_FORECOLOR = Color.white;
private final Color FOCUS_ENABLED_COLOR = Color.red;
private final int BORDER_WIDTH = 2;
private Vector stringList; // List of items
private Vector selList; // List of selected items
private int rows; // Visible rows
private int focusIndex, prevfocusIndex;
private Dimension minSize;
private Dimension prefSize;
private boolean pressed, eventOccurred, focusEnabled;
private boolean multipleMode;
// Listeners handled for this component
private ActionListener actionListener;
private KeyListener keyListener;
private FocusListener focusListener;
private ItemListener itemListener;
private static int nameCounter = 0;
/**
* Creates a new list.
*/
public LWList() {
this(0);
}
/**
* Creates a new list with the specified number of rows;
* multiple selection mode is disabled.
*
* @param i the number of rows
*/
public LWList(int i) {
this(i, false);
}
/**
* Creates a new list with the specified number of rows and multiple selection mode.
*
* @param rows the number of rows
* @param flag determines whether the list allows multiple selections
*/
public LWList(int rows, boolean flag) {
multipleMode = flag;
this.rows = rows;
minSize = new Dimension(MIN_WIDTH, MIN_HEIGHT);
prefSize = new Dimension(PREF_WIDTH, PREF_HEIGHT);
stringList = new Vector();
selList = new Vector();
selList.addElement(0);
focusIndex = -1;
prevfocusIndex = focusIndex;
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
enableEvents(AWTEvent.KEY_EVENT_MASK);
enableEvents(AWTEvent.FOCUS_EVENT_MASK);
enableEvents(AWTEvent.ITEM_EVENT_MASK);
setName(makeComponentName()); // set the name to the component
}
String makeComponentName() {
String s = "LWList" + nameCounter++;
return s;
}
/**
* Set whether the component is enabled or not.
* @param enabled if {@code true}, the component is to be enabled
*/
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
if (enabled) {
enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
} else {
disableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
repaint(1);
}
/**
* Set the selection mode.
*
* @param flag determines whether the list allows multiple selections
*/
public void setSelectionMode(boolean flag) {
multipleMode = flag;
}
/**
* Check if the list allows multiple selections.
*
* @return {@code true} if the list allows multiple selections
*/
public boolean isMultipleMode() {
return multipleMode;
}
/**
* Add the specified item.
*
* @param listItem the item
*/
public void add(String listItem) {
stringList.addElement(listItem);
invalidate();
repaint();
}
/**
* Get minimum dimension for the list.
*
* @return the minimum dimensions for displaying
*/
@Override
public Dimension getMinimumSize() {
return minSize;
}
/**
* Get the preferred size of the list.
*
* @return the preferred dimensions for displaying
*/
@Override
public Dimension getPreferredSize() {
return prefSize;
}
/**
* Get the background color for the component.
*
* @return the background color for the component
*/
@Override
public Color getBackground() {
return BACK_COLOR;
}
/**
* Get the foreground color for the component.
*
* @return the foreground color for the component
*/
@Override
public Color getForeground() {
return FRONT_COLOR;
}
/**
* Get the border color for the component.
*
* @return the border color for the component
*/
public Color getBorder() {
return BORDER_COLOR;
}
/**
* Get background color for the selected item.
*
* @return the color for the selected item
*/
public Color getFocusColor() {
return FOCUS_COLOR;
}
/**
* Get foreground color for the selected item.
*
* @return the foreground color for the selected item
*/
public Color getFocusForeColor() {
return FOCUS_FORECOLOR;
}
/**
* Get a "focus enabled" color - a small rectangle around the item
* should be drawn when the component got the focus.
*
* @return the "focus enabled" color
*/
public Color getFocusEnabledColor() {
return FOCUS_ENABLED_COLOR;
}
/**
* Get border width.
*
* @return the border width
*/
public int getBorderWidth() {
return BORDER_WIDTH;
}
/**
* Get the list item count.
*
* @return the count of items
*/
public int getItemCount() {
return stringList.size();
}
/**
* Get the specified item from the list.
*
* @param index the index
* @return the item string
*/
public String getItem(int index) {
return (String)stringList.elementAt(index);
}
/**
* Get array of items from the list.
*
* @return the array of item strings
*/
public String[] getItems() {
String str[] = new String[getItemCount()];
int count = 0;
for (Enumeration e = stringList.elements(); e.hasMoreElements(); ) {
str[count++] = (String)e.nextElement();
}
return str;
}
/**
* Check whether the component can be a focus owner (explicitly enabled here).
*
* @return {@code true} if the component is focusable
*/
@Override
public boolean isFocusTraversable() {
return true;
}
/**
* Check whether mouse click point lies within the list of items.
*
* @param pt the click point
* @return {@code true} if the click point lies within the list of items
*/
@Override
public boolean contains(Point pt) {
Rectangle rect = new Rectangle();
Dimension d = getSize();
rect.x = getBorderWidth();
rect.y = getBorderWidth();
rect.width = d.width - (getBorderWidth() * 2);
rect.height = d.height - (getBorderWidth() * 2);
return rect.contains(pt);
}
/**
* Given a click point the item that has to be selected is found from the list
* and focusIndex variable is set accordingly.
*
* @param pt the click point
*/
private void findSelectedIndex(Point pt) {
Font f = getFont();
FontMetrics fm = getFontMetrics(f);
focusIndex = pt.y / fm.getHeight() - 1;
if (multipleMode) {
Integer fi = focusIndex;
if (selList.contains(fi)) {
int i = selList.indexOf(fi);
selList.removeElementAt(i);
} else {
selList.addElement(fi);
}
}
}
/**
* Set index of the selected item.
*
* @param index the index
*/
public void setSelectedIndex(int index) {
prevfocusIndex = focusIndex;
focusIndex = index;
}
/**
* Get the selected item index.
*
* @return the selected item index.
*/
public int getSelectedIndex() {
return focusIndex;
}
/**
* Get an array of the selected Objects.
*
* @return array of the Objects
*/
@Override
public Object[] getSelectedObjects() {
int ai[] = getSelectedIndexes();
Object aobj[] = new Object[selList.size()];
for (int i = 0; i < selList.size(); i++) {
aobj[i] = stringList.elementAt(ai[i]);
}
return aobj;
}
/**
* Get an array of the selected item indices.
*
* @return the array of the indices
*/
public int[] getSelectedIndexes() {
int ai[] = new int[selList.size()];
for (int i = 0; i < selList.size(); i++) {
ai[i] = ((Integer)selList.elementAt(i));
}
return ai;
}
/**
* Add the specified item listener to receive item events from the list.
*
* @param itemlistener the item listener
*/
@Override
public synchronized void addItemListener(ItemListener itemlistener) {
itemListener = AWTEventMulticaster.add(itemListener, itemlistener);
enableEvents(AWTEvent.ITEM_EVENT_MASK);
}
/**
* Remove the specified item listener so
* that it no longer receives item events from this list.
*
* @param itemlistener the item listener
*/
@Override
public synchronized void removeItemListener(ItemListener itemlistener) {
itemListener = AWTEventMulticaster.remove(itemListener, itemlistener);
}
/**
* Add the specified action listener to receive action events from this list.
*
* @param listener the action listener
*/
public synchronized void addActionListener(ActionListener listener) {
actionListener = AWTEventMulticaster.add(actionListener, listener);
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
}
/**
* Remove the specified action listener so
* that it no longer receives action events from this list.
*
* @param listener the action listener
*/
public synchronized void removeActionListener(ActionListener listener) {
actionListener = AWTEventMulticaster.remove(actionListener, listener);
}
/**
* Add the specified key listener to receive key events from this component.
*
* @param listener the key listener
*/
@Override
public synchronized void addKeyListener(KeyListener listener) {
keyListener = AWTEventMulticaster.add(keyListener, listener);
enableEvents(AWTEvent.KEY_EVENT_MASK);
}
/**
* Remove the specified key listener so
* that it no longer receives key events from this component.
*
* @param listener the key listener
*/
@Override
public synchronized void removeKeyListener(KeyListener listener) {
keyListener = AWTEventMulticaster.remove(keyListener, listener);
}
/**
* Add the specified focus listener to receive focus events
* from this component when it gains input focus.
*
* @param listener the focus listener
*/
@Override
public synchronized void addFocusListener(FocusListener listener) {
focusListener = AWTEventMulticaster.add(focusListener, listener);
enableEvents(AWTEvent.FOCUS_EVENT_MASK);
}
/**
* Remove the specified focus listener so
* that it no longer receives focus events from this component.
*
* @param listener the focus listener
*/
@Override
public synchronized void removeFocusListener(FocusListener listener) {
focusListener = AWTEventMulticaster.remove(focusListener, listener);
}
@Override
protected void processEvent(AWTEvent awtevent) {
if (awtevent instanceof FocusEvent) {
processFocusEvent((FocusEvent)awtevent);
} else if (awtevent instanceof ItemEvent) {
processItemEvent((ItemEvent)awtevent);
} else if (awtevent instanceof KeyEvent) {
processKeyEvent((KeyEvent)awtevent);
} else if (awtevent instanceof MouseEvent) {
switch (awtevent.getID()) {
case MouseEvent.MOUSE_CLICKED:
case MouseEvent.MOUSE_PRESSED:
case MouseEvent.MOUSE_RELEASED:
case MouseEvent.MOUSE_ENTERED:
case MouseEvent.MOUSE_EXITED:
processMouseEvent((MouseEvent)awtevent);
break;
case MouseEvent.MOUSE_MOVED:
case MouseEvent.MOUSE_DRAGGED:
super.processEvent((MouseEvent)awtevent);
break;
}
} else {
if (awtevent instanceof ComponentEvent)
super.processComponentEvent((ComponentEvent)awtevent);
else
super.processEvent(awtevent);
}
}
protected void processItemEvent(ItemEvent itemevent) {
if (itemListener != null) {
itemListener.itemStateChanged(itemevent);
}
}
@Override
protected void processFocusEvent(FocusEvent e) {
switch (e.getID()) {
case FocusEvent.FOCUS_GAINED:
if (focusListener != null) { focusListener.focusGained(e); }
if (getSelectedIndex() == -1) { setSelectedIndex(0); }
focusEnabled = true;
repaint();
break;
case FocusEvent.FOCUS_LOST:
if (focusListener != null) {
focusListener.focusLost(e);
}
focusEnabled = false;
repaint();
break;
}
super.processFocusEvent(e);
}
@Override
protected void processKeyEvent(KeyEvent e) {
rows = getItemCount();
switch (e.getID()) {
case KeyEvent.KEY_TYPED:
if (keyListener != null) {
keyListener.keyTyped(e);
}
break;
case KeyEvent.KEY_PRESSED:
if (keyListener != null) {
keyListener.keyPressed(e);
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
prevfocusIndex = focusIndex;
int index = getSelectedIndex() + 1;
if (index > rows) { break; }
setSelectedIndex(index);
processItemEvent(new ItemEvent(this, 0, index, 0));
eventOccurred = true;
repaint();
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
int index = getSelectedIndex()-1;
if (index >= 0) {
setSelectedIndex(index);
if (e.getID() != 400) {
processItemEvent(new ItemEvent(this, 0, index, 0));
}
eventOccurred = true;
repaint();
}
}
break;
case KeyEvent.KEY_RELEASED:
if (keyListener != null) {
keyListener.keyReleased(e);
}
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
eventOccurred = true;
// ActionEvent is fired here
if (actionListener != null) {
actionListener.actionPerformed( new ActionEvent(
this, ActionEvent.ACTION_PERFORMED, null));
}
repaint();
}
break;
} // switch
super.processKeyEvent(e);
}
@Override
protected void processMouseEvent(MouseEvent e) {
switch (e.getID()) {
case MouseEvent.MOUSE_PRESSED:
pressed = true;
if (contains(e.getPoint())) {
findSelectedIndex(e.getPoint());
processItemEvent(new ItemEvent(this, 0, focusIndex, 0));
eventOccurred = true;
}
repaint();
break;
case MouseEvent.MOUSE_RELEASED:
if (pressed) { requestFocus(); }
if (contains(e.getPoint())) {
findSelectedIndex(e.getPoint());
eventOccurred = true;
}
// ActionEvent is fired here
if (actionListener != null) {
actionListener.actionPerformed(new ActionEvent(
this, ActionEvent.ACTION_PERFORMED, null));
}
if (pressed) {
pressed = false;
repaint();
}
break;
}
super.processMouseEvent(e);
}
@Override
/**
* Paint the list.
*
* @param g the graphics context to be used for testing
*/
public void paint(Graphics g) {
super.paint(g);
restrictGraphicsToClientArea(g);
Point loc = getClientLocation();
Dimension dim = getClientSize();
Color prevColor = g.getColor();
// List border is drawn here
g.setColor(getBackground());
g.fillRect(0, 0, dim.width - 2, dim.height - 2);
g.setColor(getBorder());
g.drawRect(0, 0, dim.width - 2, dim.height - 2);
if (getItemCount() > 0) {
Font f = getFont();
if (f != null) {
String str[] = getItems();
FontMetrics fm = getFontMetrics(f);
int drawRow = loc.x + getBorderWidth() + fm.getAscent();
int drawCol = loc.y + getBorderWidth();
int rectRow = loc.y + getBorderWidth();
int i = 0;
// Draw items (if the items exceeds visibility those items will be truncated
// as scrollbar support is not enabled
for (;
i < str.length && drawRow < (dim.height - getBorderWidth());
i++) {
if (fm.stringWidth(str[i]) < (dim.width - (getBorderWidth() * 2))) {
drawItem(g, i, drawCol, drawRow, rectRow, fm);
drawRow += fm.getHeight();
rectRow += fm.getHeight();
} else {
LWComponent.errorMsg("string width exceeds list width");
LWComponent.errorMsg("Horizontal scrollbar support is not available");
}
} // for
if ( (drawRow > (dim.height - getBorderWidth())) && (str.length > i) ) {
//LWComponent.errorMsg("no of strings exceeds list height");
//LWComponent.errorMsg("Vertical scrollbar support is not available");
}
} else { LWComponent.errorMsg("Font not available.."); }
}
eventOccurred = false;
g.setColor(prevColor);
unrestrictGraphicsFromClientArea(g);
}
// Draw String items
private void drawItem(Graphics g, int listIndex, int drawCol,
int drawRow, int rectRow, FontMetrics fm) {
Point loc = getClientLocation();
Dimension dim = getClientSize();
String str = getItem(listIndex);
if (multipleMode) {
for (int i1 = 0; i1 < selList.size(); i1++) {
if (listIndex == ((Integer)selList.elementAt(i1))) {
g.setColor(getFocusColor());
g.fillRect(loc.x + getBorderWidth(),
rectRow,
dim.width - getBorderWidth() * 2,
fm.getHeight());
g.setColor(getFocusEnabledColor());
g.drawRect(loc.x + getBorderWidth(),
rectRow,
dim.width - getBorderWidth() * 2,
fm.getHeight());
}
} // for
} else {
if (listIndex == getSelectedIndex() && !multipleMode) {
g.setColor(getFocusColor());
g.fillRect(loc.x + getBorderWidth(),
rectRow,
dim.width - getBorderWidth() * 2,
fm.getHeight());
g.setColor(getFocusForeColor());
}
if ((listIndex == prevfocusIndex) && (prevfocusIndex != getSelectedIndex()) && !multipleMode) {
g.setColor(getBackground());
g.fillRect(loc.x + getBorderWidth(),
rectRow,
dim.width - getBorderWidth() * 2,
fm.getHeight());
prevfocusIndex = getSelectedIndex();
}
if (focusEnabled && listIndex == getSelectedIndex() && !multipleMode) {
g.setColor(getFocusEnabledColor());
g.drawRect(loc.x + getBorderWidth(),
rectRow,
dim.width - getBorderWidth() * 2,
fm.getHeight());
}
}
g.setColor(getForeground());
g.drawString(str,drawCol,drawRow);
}
}