# HG changeset patch # User prr # Date 1529428320 25200 # Node ID 681b118332d731747e0a225d6d86b21314f350cf # Parent 9d7f647a2b6d98da2b463249f8d542d726f10a40# Parent 81affcb6832c0f990749ef81544aecd04153e1fa Merge diff -r 9d7f647a2b6d -r 681b118332d7 test/jdk/sanity/client/SwingSet/src/GridBagLayoutDemoTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sanity/client/SwingSet/src/GridBagLayoutDemoTest.java Tue Jun 19 10:12:00 2018 -0700 @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2018, 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 org.jtregext.GuiTestListener; +import com.sun.swingset3.demos.gridbaglayout.GridBagLayoutDemo; +import static com.sun.swingset3.demos.gridbaglayout.GridBagLayoutDemo.*; +import static com.sun.swingset3.demos.gridbaglayout.Calculator.*; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Point; +import javax.swing.JButton; +import javax.swing.UIManager; +import org.testng.annotations.Test; +import org.netbeans.jemmy.ClassReference; +import org.netbeans.jemmy.operators.JFrameOperator; +import org.netbeans.jemmy.operators.JButtonOperator; +import org.netbeans.jemmy.operators.JTextFieldOperator; +import org.testng.annotations.Listeners; +import static org.jemmy2ext.JemmyExt.EXACT_STRING_COMPARATOR; +import static org.jemmy2ext.JemmyExt.getUIValue; +/* + * @test + * @key headful + * @summary Verifies SwingSet3 GridBagLayoutDemo by checking the relative + * location of all the components before and after resizing the frame, + * interacting with all the controls and checking this interaction on the + * text field display. + * + * @library /sanity/client/lib/jemmy/src + * @library /sanity/client/lib/Extensions/src + * @library /sanity/client/lib/SwingSet3/src + * @modules java.desktop + * java.logging + * @build com.sun.swingset3.demos.gridbaglayout.GridBagLayoutDemo + * @run testng GridBagLayoutDemoTest + */ + +@Listeners(GuiTestListener.class) +public class GridBagLayoutDemoTest { + + private JTextFieldOperator tfScreen; + private JButtonOperator buttonZero; + private JButtonOperator buttonOne; + private JButtonOperator buttonTwo; + private JButtonOperator buttonThree; + private JButtonOperator buttonFour; + private JButtonOperator buttonFive; + private JButtonOperator buttonSix; + private JButtonOperator buttonSeven; + private JButtonOperator buttonEight; + private JButtonOperator buttonNine; + private JButtonOperator buttonPlus; + private JButtonOperator buttonMinus; + private JButtonOperator buttonMultiply; + private JButtonOperator buttonDivide; + private JButtonOperator buttonComma; + private JButtonOperator buttonSqrt; + private JButtonOperator buttonReciprocal; + private JButtonOperator buttonToggleSign; + private JButtonOperator buttonEquals; + private JButtonOperator backspaceButton; + private JButtonOperator resetButton; + private JFrameOperator mainFrame; + + @Test(dataProvider = "availableLookAndFeels", dataProviderClass = TestHelpers.class) + public void test(String lookAndFeel) throws Exception { + initializeUIComponents(lookAndFeel); + // Check that the relative location of buttons is as expected. + checkRelativeLocations(); + // Interact with buttons and check the result on the display. + checkInteractionOnDisplay(); + // Change the location and check that the relative location of buttons is same as before. + checkChangeLocation(); + // Change the size and check that the relative location of buttons is same as before. + checkChangeSize(); + } + + private double x(Component component) { + return component.getLocation().getX(); + } + + private double y(Component component) { + return component.getLocation().getY(); + } + + private void checkRight(JButtonOperator currentButton, JButtonOperator rightButton) { + // Check that x coordinate of right button is greater than that of right + // end of current button + currentButton.waitStateOnQueue(button -> x(button) + button.getWidth() < x(rightButton.getSource())); + // Check that the y coordinate of the button is same as the button to + // the right + currentButton.waitStateOnQueue(button -> y(button) == y(rightButton.getSource())); + // Check that the height of the button is same as the button to the + // right + currentButton.waitStateOnQueue(button -> button.getHeight() == rightButton.getHeight()); + } + + private void checkBelow(JButtonOperator currentButton, JButtonOperator buttonBelow) { + // Check that y coordinate of button below is greater than that of + // bottom end of current button + currentButton.waitStateOnQueue(button -> y(button) + button.getHeight() < y(buttonBelow.getSource())); + // Check that the x coordinate of the button is same as the button below + currentButton.waitStateOnQueue(button -> x(button) == x(buttonBelow.getSource())); + // Check that the width of the button is same as the button below + currentButton.waitStateOnQueue(button -> button.getWidth() == buttonBelow.getWidth()); + } + + private void checkRelativeLocations() { + // Check relative location of button 7 + checkRight(buttonSeven, buttonEight); + checkBelow(buttonSeven, buttonFour); + + // Check relative location of button 8 + checkRight(buttonEight, buttonNine); + checkBelow(buttonEight, buttonFive); + + // Check relative location of button 9 + checkRight(buttonNine, buttonDivide); + checkBelow(buttonNine, buttonSix); + + // Check relative location of Division button + checkRight(buttonDivide, buttonReciprocal); + checkBelow(buttonDivide, buttonMultiply); + + // Check relative location of Reciprocal and Sqrt buttons + checkBelow(buttonReciprocal, buttonSqrt); + + // Check relative location of button 4 + checkRight(buttonFour, buttonFive); + checkBelow(buttonFour, buttonOne); + + // Check relative location of button 5 + checkRight(buttonFive, buttonSix); + checkBelow(buttonFive, buttonTwo); + + // Check relative location of button 6 + checkRight(buttonSix, buttonMultiply); + checkBelow(buttonSix, buttonThree); + + // Check relative location of Multiply button + checkRight(buttonMultiply, buttonSqrt); + checkBelow(buttonMultiply, buttonMinus); + + // Check relative location of button 1 + checkRight(buttonOne, buttonTwo); + checkBelow(buttonOne, buttonZero); + + // Check relative location of button 2 + checkRight(buttonTwo, buttonThree); + checkBelow(buttonTwo, buttonToggleSign); + + // Check relative location of button 3 + checkRight(buttonThree, buttonMinus); + checkBelow(buttonThree, buttonComma); + + // Check relative location of Minus button + checkBelow(buttonMinus, buttonPlus); + + // Check relative location of button 0 + checkRight(buttonZero, buttonToggleSign); + + // Check relative location of Sign Toggle Button + checkRight(buttonToggleSign, buttonComma); + + // Check relative location of Comma button + checkRight(buttonComma, buttonPlus); + + // Check relative location of plus and Equals buttons + checkRight(buttonPlus, buttonEquals); + + // Check relative location of JPanel containing Backspace and Reset + // buttons + Point parentLocation = getUIValue(backspaceButton, (JButton button) -> button.getParent().getLocation()); + // Check that the y coordinate of bottom of the screen is + // less than that of parent of backspace button + tfScreen.waitStateOnQueue(screen -> y(screen) + screen.getHeight() < parentLocation.getY()); + // Check that the y coordinate of the button 7 is greater + // than that of parent of backspace + buttonSeven.waitStateOnQueue(button -> parentLocation.getY() < y(button)); + // Check that the y coordinate of reciprocal button is greater + // than that of parent of backspace + buttonReciprocal.waitStateOnQueue(button -> parentLocation.getY() < y(button)); + // Check that x coordinate of screen is same as that of parent of + // backspace + tfScreen.waitStateOnQueue(screen -> x(screen) == parentLocation.getX()); + // Check that x coordinate of button 7 is same as that of parent of + // backspace + buttonSeven.waitStateOnQueue(button -> x(button) == parentLocation.getX()); + + // Check relative location of Backspace button + // Check that the x coordinate of right of backspace button + // is less than that of reset button + backspaceButton.waitStateOnQueue(button -> x(button) + button.getWidth() < x(resetButton.getSource())); + // Check that the height of backspace button is same as that of reset + // button + backspaceButton.waitStateOnQueue(button -> button.getHeight() == resetButton.getHeight()); + // Check that the y coordinate bottom of backspace button is less that + // that of button 7 + backspaceButton.waitStateOnQueue( + button -> parentLocation.getY() + button.getParent().getHeight() < y(buttonSeven.getSource())); + + // Check that the x coordinate of reset button is greater than that + // of right of backspace button + resetButton.waitStateOnQueue(button -> x(backspaceButton.getSource()) + backspaceButton.getWidth() < x(button)); + + // Check that the height of reset button is same as that of backspace + // button + resetButton.waitStateOnQueue(button -> backspaceButton.getHeight() == button.getHeight()); + + // Check that the y coordinate of bottom of reset button is less + // than that of divide button. + resetButton.waitStateOnQueue( + button -> parentLocation.getY() + button.getParent().getHeight() < y(buttonDivide.getSource())); + + // Check that the y coordinate of top of screen is lower + // than that of parent of backspace button + tfScreen.waitStateOnQueue(screen -> y(screen) + screen.getHeight() < parentLocation.getY()); + } + + private void checkInteractionOnDisplay() { + // Check buttons: 1,2,+,=,C + buttonOne.push(); + tfScreen.waitText("1"); + buttonPlus.push(); + tfScreen.waitText("1"); + buttonTwo.push(); + tfScreen.waitText("2"); + buttonEquals.push(); + tfScreen.waitText("3"); + resetButton.push(); + tfScreen.waitText("0"); + + // Check buttons: 3,4,- + buttonFour.push(); + tfScreen.waitText("4"); + buttonMinus.push(); + tfScreen.waitText("4"); + buttonThree.push(); + tfScreen.waitText("3"); + buttonEquals.push(); + tfScreen.waitText("1"); + reset(); + + // Check buttons: 5,6,* + buttonFive.push(); + tfScreen.waitText("5"); + buttonMultiply.push(); + tfScreen.waitText("5"); + buttonSix.push(); + tfScreen.waitText("6"); + buttonEquals.push(); + tfScreen.waitText("30"); + reset(); + + // Check buttons: 8,9,/ + buttonNine.push(); + buttonNine.push(); + tfScreen.waitText("99"); + buttonDivide.push(); + tfScreen.waitText("99"); + buttonEight.push(); + tfScreen.waitText("8"); + buttonEquals.push(); + tfScreen.waitText("12.375"); + reset(); + + // Check buttons: 7,0,[+/-],Backspace + buttonSeven.push(); + tfScreen.waitText("7"); + buttonZero.push(); + tfScreen.waitText("70"); + buttonToggleSign.push(); + tfScreen.waitText("-70"); + buttonToggleSign.push(); + tfScreen.waitText("70"); + backspaceButton.push(); + tfScreen.waitText("7"); + reset(); + + // Check Sqrt Button + buttonFour.push(); + buttonNine.push(); + tfScreen.waitText("49"); + buttonSqrt.push(); + tfScreen.waitText("7"); + reset(); + + // Check Reciprocal Button + buttonFour.push(); + tfScreen.waitText("4"); + buttonReciprocal.push(); + tfScreen.waitText("0.25"); + reset(); + + // Check Comma button + buttonFour.push(); + buttonComma.push(); + tfScreen.waitText("4,"); + } + + private void reset() { + resetButton.push(); + tfScreen.waitText("0"); + } + + private void initializeUIComponents(String lookAndFeel) throws Exception { + UIManager.setLookAndFeel(lookAndFeel); + new ClassReference(GridBagLayoutDemo.class.getCanonicalName()).startApplication(); + mainFrame = new JFrameOperator(GRID_BAG_LAYOUT_DEMO_TITLE); + mainFrame.setComparator(EXACT_STRING_COMPARATOR); + buttonZero = new JButtonOperator(mainFrame, ZERO_BUTTON_TITLE); + buttonOne = new JButtonOperator(mainFrame, ONE_BUTTON_TITLE); + buttonTwo = new JButtonOperator(mainFrame, TWO_BUTTON_TITLE); + buttonThree = new JButtonOperator(mainFrame, THREE_BUTTON_TITLE); + buttonFour = new JButtonOperator(mainFrame, FOUR_BUTTON_TITLE); + buttonFive = new JButtonOperator(mainFrame, FIVE_BUTTON_TITLE); + buttonSix = new JButtonOperator(mainFrame, SIX_BUTTON_TITLE); + buttonSeven = new JButtonOperator(mainFrame, SEVEN_BUTTON_TITLE); + buttonEight = new JButtonOperator(mainFrame, EIGHT_BUTTON_TITLE); + buttonNine = new JButtonOperator(mainFrame, NINE_BUTTON_TITLE); + buttonPlus = new JButtonOperator(mainFrame, PLUS_BUTTON_TITLE); + buttonMinus = new JButtonOperator(mainFrame, MINUS_BUTTON_TITLE); + buttonMultiply = new JButtonOperator(mainFrame, MULTIPLY_BUTTON_TITLE); + buttonDivide = new JButtonOperator(mainFrame, DIVIDE_BUTTON_TITLE); + buttonComma = new JButtonOperator(mainFrame, ","); + buttonSqrt = new JButtonOperator(mainFrame, SQRT_BUTTON_TITLE); + buttonReciprocal = new JButtonOperator(mainFrame, INVERSE_BUTTON_TITLE); + buttonToggleSign = new JButtonOperator(mainFrame, SWAPSIGN_BUTTON_TITLE); + buttonEquals = new JButtonOperator(mainFrame, EQUALS_BUTTON_TITLE); + resetButton = new JButtonOperator(mainFrame, C_BUTTON_TITLE); + backspaceButton = new JButtonOperator(mainFrame, BACKSPACE_BUTTON_TITLE); + tfScreen = new JTextFieldOperator(mainFrame, 0); + } + + private void checkChangeLocation() { + Point startingPoint = new Point(100, 100); + mainFrame.setLocation(startingPoint); + mainFrame.waitComponentLocation(startingPoint); + checkRelativeLocations(); + } + + private void checkChangeSize() { + Dimension newSize = new Dimension((int) mainFrame.getToolkit().getScreenSize().getWidth() / 2, + (int) mainFrame.getToolkit().getScreenSize().getHeight() / 2); + mainFrame.setSize(newSize); + mainFrame.waitComponentSize(newSize); + checkRelativeLocations(); + } +} diff -r 9d7f647a2b6d -r 681b118332d7 test/jdk/sanity/client/SwingSet/src/TestHelpers.java --- a/test/jdk/sanity/client/SwingSet/src/TestHelpers.java Tue Jun 19 09:22:38 2018 -0700 +++ b/test/jdk/sanity/client/SwingSet/src/TestHelpers.java Tue Jun 19 10:12:00 2018 -0700 @@ -1,17 +1,40 @@ - import java.awt.Dimension; import java.awt.Point; - +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.channels.FileChannel; +import java.nio.file.Path; +import javax.swing.UIManager; import org.netbeans.jemmy.operators.ComponentOperator; +import org.testng.annotations.DataProvider; public class TestHelpers { + /** + * A DataProvider having the class name of all the available look and feels + * + * @return a 2d Object array containing the class name of all the available + * look and feels + */ + @DataProvider(name = "availableLookAndFeels") + public static Object[][] provideAvailableLookAndFeels() { + UIManager.LookAndFeelInfo LookAndFeelInfos[] + = UIManager.getInstalledLookAndFeels(); + Object[][] lookAndFeels = new Object[LookAndFeelInfos.length][1]; + for (int i = 0; i < LookAndFeelInfos.length; i++) { + lookAndFeels[i][0] = LookAndFeelInfos[i].getClassName(); + } + return lookAndFeels; + } + public static void checkChangeLocation(ComponentOperator component, Point finalLocation) { Point initialLocation = component.getLocation(); component.setLocation(finalLocation); component.waitComponentLocation(finalLocation); component.setLocation(initialLocation); + component.waitComponentLocation(initialLocation); } public static void checkChangeSize(ComponentOperator component, @@ -20,5 +43,7 @@ component.setSize(dimensionFinal); component.waitComponentSize(dimensionFinal); component.setSize(dimensionInitial); + component.waitComponentSize(dimensionInitial); } + } diff -r 9d7f647a2b6d -r 681b118332d7 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/gridbaglayout/Calculator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/gridbaglayout/Calculator.java Tue Jun 19 10:12:00 2018 -0700 @@ -0,0 +1,469 @@ +/* + * Copyright (c) 2007, 2018, 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 com.sun.swingset3.demos.gridbaglayout; + +import java.awt.*; +import java.awt.event.*; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import javax.swing.*; + +/** + * Calculator + * + * @author Pavel Porvatov + */ +public class Calculator extends JComponent { + + private static final String ZERO = "0"; + + private static final char DECIMAL_SEPARATOR = ','; + + private final JTextField tfScreen = new JTextField(); + + private enum State { + + INPUT_X, + INPUT_X_FINISHED, + INPUT_Y, + INPUT_Y_FINISHED + } + + private enum Operator { + + ADDITION, + SUBTRACTION, + MULTIPLICATION, + DIVISION, + SQRT, + INVERSE, + EQUALS + } + + private final Map keyMapping = new HashMap(); + + private String operand_x; + + private Operator operator; + + private State state; + + public static final String ZERO_BUTTON_TITLE = "0"; + public static final String ONE_BUTTON_TITLE = "1"; + public static final String TWO_BUTTON_TITLE = "2"; + public static final String THREE_BUTTON_TITLE = "3"; + public static final String FOUR_BUTTON_TITLE = "4"; + public static final String FIVE_BUTTON_TITLE = "5"; + public static final String SIX_BUTTON_TITLE = "6"; + public static final String SEVEN_BUTTON_TITLE = "7"; + public static final String EIGHT_BUTTON_TITLE = "8"; + public static final String NINE_BUTTON_TITLE = "9"; + public static final String PLUS_BUTTON_TITLE = "+"; + public static final String MINUS_BUTTON_TITLE = "-"; + public static final String DIVIDE_BUTTON_TITLE = "/"; + public static final String MULTIPLY_BUTTON_TITLE = "*"; + public static final String BACKSPACE_BUTTON_TITLE = "Backspace"; + public static final String C_BUTTON_TITLE = "C"; + public static final String EQUALS_BUTTON_TITLE = "="; + public static final String SWAPSIGN_BUTTON_TITLE = "+/-"; + public static final String INVERSE_BUTTON_TITLE = "1/x"; + public static final String SQRT_BUTTON_TITLE = "sqrt"; + public static final String COMMA_BUTTON_TITLE = ","; + + private static DecimalFormatSymbols decimalFormatSymbols; + private static DecimalFormat decimalFormat; + + public Calculator() { + keyMapping.put('/', Operator.DIVISION); + keyMapping.put('*', Operator.MULTIPLICATION); + keyMapping.put('+', Operator.ADDITION); + keyMapping.put('-', Operator.SUBTRACTION); + keyMapping.put('\n', Operator.EQUALS); + + decimalFormatSymbols = new DecimalFormatSymbols(Locale.US); + decimalFormatSymbols.setDecimalSeparator('.'); + decimalFormat = new DecimalFormat("##0.###", decimalFormatSymbols); + + initUI(); + + addKeyListener(new KeyAdapter() { + public void keyTyped(KeyEvent e) { + char c = e.getKeyChar(); + + if (Character.isDigit(c)) { + doProcessChar(c); + } else if (c == '.' || c == ',') { + doProcessChar(DECIMAL_SEPARATOR); + } else { + Operator operator = keyMapping.get(c); + + if (operator != null) { + doProcessOperator(operator); + } + } + } + + public void keyPressed(KeyEvent e) { + switch (e.getKeyCode()) { + case KeyEvent.VK_BACK_SPACE: + doProcessBackspace(); + + break; + + case KeyEvent.VK_DELETE: + doReset(); + } + } + }); + + doReset(); + } + + private void initUI() { + tfScreen.setHorizontalAlignment(JTextField.RIGHT); + + JButton btnBackspace = new JButton(BACKSPACE_BUTTON_TITLE); + + btnBackspace.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doProcessBackspace(); + } + }); + + JButton btnReset = new JButton(C_BUTTON_TITLE); + + btnReset.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doReset(); + } + }); + + JPanel pnGridPanel = new JPanel(new GridLayout(1, 2, 8, 8)); + + pnGridPanel.add(btnBackspace); + pnGridPanel.add(btnReset); + + setLayout(new GridBagLayout()); + + JButton btnSwapSign = new SquareButton(SWAPSIGN_BUTTON_TITLE); + + btnSwapSign.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doSwapSign(); + } + }); + + addComp(tfScreen, 0, 0, 5, 1); + addComp(pnGridPanel, 0, 1, 5, 1); + + addComp(new CharButton(SEVEN_BUTTON_TITLE.charAt(0)), 0, 2, 1, 1); + addComp(new CharButton(EIGHT_BUTTON_TITLE.charAt(0)), 1, 2, 1, 1); + addComp(new CharButton(NINE_BUTTON_TITLE.charAt(0)), 2, 2, 1, 1); + addComp(new OperatorButton(Operator.DIVISION, DIVIDE_BUTTON_TITLE), 3, 2, 1, 1); + addComp(new OperatorButton(Operator.INVERSE, INVERSE_BUTTON_TITLE), 4, 2, 1, 1); + + addComp(new CharButton(FOUR_BUTTON_TITLE.charAt(0)), 0, 3, 1, 1); + addComp(new CharButton(FIVE_BUTTON_TITLE.charAt(0)), 1, 3, 1, 1); + addComp(new CharButton(SIX_BUTTON_TITLE.charAt(0)), 2, 3, 1, 1); + addComp(new OperatorButton(Operator.MULTIPLICATION, MULTIPLY_BUTTON_TITLE), 3, 3, 1, 1); + addComp(new OperatorButton(Operator.SQRT, SQRT_BUTTON_TITLE), 4, 3, 1, 1); + + addComp(new CharButton(ONE_BUTTON_TITLE.charAt(0)), 0, 4, 1, 1); + addComp(new CharButton(TWO_BUTTON_TITLE.charAt(0)), 1, 4, 1, 1); + addComp(new CharButton(THREE_BUTTON_TITLE.charAt(0)), 2, 4, 1, 1); + addComp(new OperatorButton(Operator.SUBTRACTION, MINUS_BUTTON_TITLE), 3, 4, 1, 1); + + addComp(new CharButton(ZERO_BUTTON_TITLE.charAt(0)), 0, 5, 1, 1); + addComp(btnSwapSign, 1, 5, 1, 1); + addComp(new CharButton(COMMA_BUTTON_TITLE.charAt(0)), 2, 5, 1, 1); + addComp(new OperatorButton(Operator.ADDITION, PLUS_BUTTON_TITLE), 3, 5, 1, 1); + addComp(new OperatorButton(Operator.EQUALS, EQUALS_BUTTON_TITLE), 4, 5, 1, 1); + + // Set focusable false + resetFocusable(this); + + setFocusable(true); + } + + private static void resetFocusable(Component component) { + component.setFocusable(false); + + if (component instanceof Container) { + for (Component c : ((Container) component).getComponents()) { + resetFocusable(c); + } + } + } + + private void doReset() { + synchronized (this) { + operand_x = null; + operator = null; + state = State.INPUT_X; + } + tfScreen.setText(ZERO); + } + + private void doProcessChar(char c) { + String text = tfScreen.getText(); + + String newValue; + + synchronized (this) { + if (state == State.INPUT_X || state == State.INPUT_Y) { + newValue = attachChar(text, c); + + if (stringToValue(newValue) == null) { + return; + } + } else { + newValue = attachChar("0", c); + + if (stringToValue(newValue) == null) { + return; + } + + if (operator == null) { + operand_x = null; + state = State.INPUT_X; + } else { + operand_x = text; + state = State.INPUT_Y; + } + } + } + tfScreen.setText(newValue); + } + + private static String attachChar(String s, char c) { + if (Character.isDigit(c)) { + if (s.equals(ZERO)) { + return Character.toString(c); + } + + if (s.equals("-" + ZERO)) { + return "-" + Character.toString(c); + } + + return s + Character.toString(c); + } else { + return s + Character.toString(c); + } + } + + private void doSwapSign() { + String text = tfScreen.getText(); + + tfScreen.setText(text.startsWith("-") ? text.substring(1) : "-" + text); + } + + private void doProcessBackspace() { + String text = tfScreen.getText(); + + if (text.length() > 0) { + text = text.substring(0, text.length() - 1); + } + + if (text.length() == 0 || text.equals("-")) { + text = ZERO; + } + + if (stringToValue(text) != null) { + tfScreen.setText(text); + } + } + + private void doProcessOperator(Operator operator) { + double y = stringToValue(tfScreen.getText()); + + // Process unary operators + boolean isUnary; + + switch (operator) { + case SQRT: + tfScreen.setText(valueToString(Math.sqrt(y))); + + isUnary = true; + + break; + + case INVERSE: + tfScreen.setText(valueToString(1 / y)); + + isUnary = true; + + break; + + default: + isUnary = false; + } + + synchronized (this) { + if (isUnary) { + if (state == State.INPUT_X) { + state = State.INPUT_X_FINISHED; + } + + if (state == State.INPUT_Y) { + state = State.INPUT_Y_FINISHED; + } + + return; + } + + // Process binary operators + if (state == State.INPUT_Y || state == State.INPUT_Y_FINISHED) { + double x = stringToValue(operand_x); + double result; + + switch (this.operator) { + case ADDITION: + result = x + y; + + break; + + case SUBTRACTION: + result = x - y; + + break; + + case MULTIPLICATION: + result = x * y; + + break; + + case DIVISION: + result = x / y; + + break; + + default: + throw new IllegalStateException("Unsupported operation " + operator); + } + + tfScreen.setText(valueToString(result)); + } + + this.operator = operator == Operator.EQUALS ? null : operator; + operand_x = null; + + state = State.INPUT_X_FINISHED; + } + } + + private static Double stringToValue(String value) { + try { + return new Double(value.replace(DECIMAL_SEPARATOR, '.')); + } catch (NumberFormatException e) { + // Continue convertion + } + + if (value.endsWith(String.valueOf(DECIMAL_SEPARATOR))) { + try { + // Try convert uncompleted value + return new Double(value.substring(0, value.length() - 1)); + } catch (NumberFormatException e) { + // Continue convertion + } + } + + return null; + } + + private static String valueToString(Double value) { + if (value == null) { + return ZERO; + } else { + String result = decimalFormat.format(value); + + if (result.endsWith(".0")) { + result = result.substring(0, result.length() - 2); + } + + if (result.equals("-0")) { + result = ZERO; + } + + return result; + } + } + + private void addComp(Component comp, int gridx, int gridy, + int gridwidth, int gridheight) { + add(comp, new GridBagConstraints(gridx, gridy, gridwidth, gridheight, + 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, + new Insets(4, 4, 4, 4), 0, 0)); + } + + private static class SquareButton extends JButton { + + private SquareButton(String text) { + super(text); + + setMargin(new Insets(2, 0, 2, 0)); + } + + public Dimension getMinimumSize() { + Dimension result = super.getMinimumSize(); + + if (result.width < result.height) { + result.width = result.height; + } + + return result; + } + + public Dimension getPreferredSize() { + return getMinimumSize(); + } + } + + private class CharButton extends SquareButton { + + private CharButton(final char c) { + super(String.valueOf(c)); + + addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doProcessChar(c); + } + }); + } + } + + private class OperatorButton extends SquareButton { + + private OperatorButton(final Operator operator, String text) { + super(text); + + addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + doProcessOperator(operator); + } + }); + } + } +} diff -r 9d7f647a2b6d -r 681b118332d7 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/gridbaglayout/GridBagLayoutDemo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/gridbaglayout/GridBagLayoutDemo.java Tue Jun 19 10:12:00 2018 -0700 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2007, 2018, 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 com.sun.swingset3.demos.gridbaglayout; + +import java.awt.*; +import javax.swing.*; + +import com.sun.swingset3.demos.JGridPanel; +import com.sun.swingset3.demos.ResourceManager; +import com.sun.swingset3.DemoProperties; + +/** + * GridBagLayout Demo + * + * @author Pavel Porvatov + */ +@DemoProperties( + value = "GridBagLayout Demo", + category = "Containers", + description = "Demonstrates GridBagLayout, a layout which allows to arrange components in containers.", + sourceFiles = { + "com/sun/swingset3/demos/gridbaglayout/GridBagLayoutDemo.java", + "com/sun/swingset3/demos/gridbaglayout/Calculator.java", + "com/sun/swingset3/demos/JGridPanel.java", + "com/sun/swingset3/demos/ResourceManager.java", + "com/sun/swingset3/demos/gridbaglayout/resources/GridBagLayoutDemo.properties", + "com/sun/swingset3/demos/gridbaglayout/resources/images/GridBagLayoutDemo.gif" + } +) +public class GridBagLayoutDemo extends JPanel { + + private final ResourceManager resourceManager = new ResourceManager(this.getClass()); + + private final JLabel lbCaption = new JLabel("" + + resourceManager.getString("GridBagLayoutDemo.caption.text") + ""); + + private final Calculator calculator = new Calculator(); + + public static final String GRID_BAG_LAYOUT_DEMO_TITLE = GridBagLayoutDemo.class + .getAnnotation(DemoProperties.class).value(); + + /** + * main method allows us to run as a standalone demo. + */ + public static void main(String[] args) { + JFrame frame = new JFrame(GRID_BAG_LAYOUT_DEMO_TITLE); + + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.getContentPane().add(new GridBagLayoutDemo()); + frame.setPreferredSize(new Dimension(800, 600)); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + public GridBagLayoutDemo() { + setLayout(new BorderLayout()); + + initUI(); + } + + private void initUI() { + JGridPanel pnContent = new JGridPanel(1, 0, 2); + + pnContent.setBorderEqual(10); + + pnContent.cell(lbCaption, JGridPanel.Layout.FILL). + cell(). + cell(calculator, JGridPanel.Layout.CENTER, JGridPanel.Layout.FIRST). + cell(); + + add(pnContent); + } +} diff -r 9d7f647a2b6d -r 681b118332d7 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/gridbaglayout/resources/GridBagLayoutDemo.properties --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/gridbaglayout/resources/GridBagLayoutDemo.properties Tue Jun 19 10:12:00 2018 -0700 @@ -0,0 +1,4 @@ +### GridBagLayout Demo ### + +GridBagLayoutDemo.caption.text = This calculator uses the GridBagLayout layout manager to arrange components. \ + GridBagLayout is very useful when you need to place components in a grid of rows and columns. diff -r 9d7f647a2b6d -r 681b118332d7 test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/gridbaglayout/resources/images/GridBagLayoutDemo.gif Binary file test/jdk/sanity/client/lib/SwingSet3/src/com/sun/swingset3/demos/gridbaglayout/resources/images/GridBagLayoutDemo.gif has changed