Browse Source

Refactor tests.

Add tests for custom title bars.
Fix issue where the JRootPane.hideTitlePane option had no effect on macOS.
pull/215/head
weisj 4 years ago committed by Jannis Weis
parent
commit
5b8a340e60
  1. 9
      .github/workflows/codeql-analysis.yml
  2. 7
      .github/workflows/documentation.yml
  3. 48
      .github/workflows/gradle.yml
  4. 14
      .github/workflows/libs.yml
  5. 4
      core/src/test/java/DemoLauncher.java
  6. 19
      core/src/test/java/test/AbstractImageTest.java
  7. 226
      core/src/test/java/test/CustomTitleBarTest.java
  8. 4
      core/src/test/java/test/FontTest.java
  9. 6
      core/src/test/java/test/NativeLibraryTest.java
  10. 57
      core/src/test/java/test/TestUtils.java
  11. 54
      core/src/test/java/test/TooltipTest.java
  12. 4
      macos/src/main/java/com/github/weisj/darklaf/platform/macos/ui/MacOSTitlePane.java

9
.github/workflows/codeql-analysis.yml

@ -84,8 +84,13 @@ jobs:
# ✏ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
- run: |
./gradlew build -PskipAutostyle
- name: Build
uses: eskatos/gradle-command-action@v1
with:
arguments: build -PskipAutostyle --info -x test
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

7
.github/workflows/documentation.yml

@ -46,7 +46,12 @@ jobs:
with:
java-version: 11
- name: Build documentation
run: ./gradlew :darklaf-core:makeDocumentation -PskipAutostyle -x test
uses: eskatos/gradle-command-action@v1
with:
arguments: :darklaf-core:makeDocumentation -PskipAutostyle -x test
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Upload documentation
uses: actions/upload-artifact@v1
with:

48
.github/workflows/gradle.yml

@ -38,17 +38,21 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 10
fetch-depth: 2
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Build
run: ./gradlew build -PskipAutostyle --info -x test
- name: Test
run: ./gradlew test -PskipAutostyle --info
- name: Upload Results
- name: Build & Test
uses: eskatos/gradle-command-action@v1
with:
arguments: build test -PskipAutostyle --info --no-daemon
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Upload Test Results
uses: actions/upload-artifact@v1
if: ${{ always() }}
with:
name: windows-test-results
path: build/test_results
@ -59,16 +63,20 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 10
fetch-depth: 2
- name: Set up JDK 8
uses: actions/setup-java@v1
with:
java-version: 8
- name: Build
run: ./gradlew build -PskipAutostyle --info -x test
- name: Test
run: ./gradlew test -PskipAutostyle --info
- name: Upload Results
- name: Build & Test
uses: eskatos/gradle-command-action@v1
with:
arguments: build test -PskipAutostyle --info --no-daemon
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Upload Test Results
if: ${{ always() }}
uses: actions/upload-artifact@v1
with:
name: linux-test-results
@ -80,17 +88,21 @@ jobs:
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 10
fetch-depth: 2
- name: Set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 11
- name: Build
run: ./gradlew build -PskipAutostyle --info -x test
- name: Test
run: ./gradlew test -PskipAutostyle --info
- name: Upload Results
- name: Build & Test
uses: eskatos/gradle-command-action@v1
with:
arguments: build test -PskipAutostyle --info --no-daemon
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Upload Test Results
uses: actions/upload-artifact@v1
if: ${{ always() }}
with:
name: macOS-test-results
path: build/test_results

14
.github/workflows/libs.yml

@ -51,7 +51,12 @@ jobs:
with:
java-version: 11
- name: Build
run: ./gradlew :darklaf-windows:build -PskipAutostyle -x test
uses: eskatos/gradle-command-action@v1
with:
arguments: :darklaf-windows:build -PskipAutostyle -x test
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Upload x86 artifact
uses: actions/upload-artifact@v1
with:
@ -75,7 +80,12 @@ jobs:
with:
java-version: 11
- name: Build
run: ./gradlew :darklaf-macos:build -PskipAutostyle -x test
uses: eskatos/gradle-command-action@v1
with:
arguments: :darklaf-macos:build -PskipAutostyle -x test
wrapper-cache-enabled: true
dependencies-cache-enabled: true
configuration-cache-enabled: true
- name: Upload artifact
uses: actions/upload-artifact@v1
with:

4
core/src/test/java/DemoLauncher.java

@ -28,9 +28,13 @@ import ui.ComponentDemo;
import ui.DemoPanel;
import util.ClassFinder;
import com.github.weisj.darklaf.util.ColorUtil;
public class DemoLauncher implements ComponentDemo {
public static void main(final String[] args) {
System.out.println(ColorUtil.getPerceivedBrightness(ColorUtil.fromHex("2D2D2D")));
if (true) return;
ComponentDemo.showDemo(new DemoLauncher());
}

19
core/src/test/java/test/AbstractImageTest.java

@ -30,8 +30,9 @@ import java.nio.file.Files;
import javax.imageio.ImageIO;
import com.github.weisj.darklaf.util.ImageUtil;
import com.github.weisj.darklaf.util.Scale;
public abstract class AbstractImageTest {
abstract class AbstractImageTest {
private static final int SCALING_FACTOR = 3;
protected static final String WORKING_DIR = "image_test";
private final String workingDir;
@ -69,4 +70,20 @@ public abstract class AbstractImageTest {
}
return null;
}
protected BufferedImage saveWindowScreenShot(final String name, final Window w) {
try {
File file = new File(name + ".png");
file.getParentFile().mkdirs();
Robot robot = new Robot();
Point p = w.getLocationOnScreen();
BufferedImage image = robot.createScreenCapture(
new Rectangle(p.x, p.y, Scale.scaleWidth(w.getWidth()), Scale.scaleHeight(w.getHeight())));
ImageIO.write(image, "png", file);
return image;
} catch (IOException | AWTException e) {
e.printStackTrace();
}
return null;
}
}

226
core/src/test/java/test/CustomTitleBarTest.java

@ -0,0 +1,226 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package test;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import javax.swing.*;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import com.github.weisj.darklaf.LafManager;
import com.github.weisj.darklaf.theme.DarculaTheme;
import com.github.weisj.darklaf.theme.IntelliJTheme;
import com.github.weisj.darklaf.ui.rootpane.DarkRootPaneUI;
import com.github.weisj.darklaf.util.ColorUtil;
import com.github.weisj.darklaf.util.SystemInfo;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class CustomTitleBarTest extends AbstractImageTest {
private static final Color TITLE_BAR_COLOR = Color.RED;
private static final Color CONTENT_COLOR = Color.BLUE;
private static final int TITLE_BAR_Y = 10;
private static final int TOLERANCE = SystemInfo.isMac ? 55 : 0;
public CustomTitleBarTest() {
super("titlebar");
}
@BeforeAll
static void setup() {
LafManager.registerInitTask((t, d) -> {
d.put("MacOS.TitlePane.background", TITLE_BAR_COLOR);
d.put("MacOS.TitlePane.inactiveBackground", TITLE_BAR_COLOR);
d.put("Windows.TitlePane.background", TITLE_BAR_COLOR);
d.put("Windows.TitlePane.inactiveBackground", TITLE_BAR_COLOR);
});
}
@BeforeEach
void beforeEach() {
LafManager.setDecorationsEnabled(true);
}
private AtomicReference<JFrame> createFrame(final Consumer<JFrame> frameModifier) {
AtomicReference<JFrame> frame = new AtomicReference<>();
final Object lock = new Object();
TestUtils.runOnSwingThreadNotThrowing(() -> {
JFrame f = new JFrame("");
frame.set(f);
JPanel content = new JPanel();
content.setBackground(CONTENT_COLOR);
content.setPreferredSize(new Dimension(200, 200));
f.setContentPane(content);
f.pack();
f.setLocationRelativeTo(null);
f.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(final WindowEvent e) {
f.removeWindowListener(this);
SwingUtilities.invokeLater(() -> {
synchronized (lock) {
lock.notify();
}
});
}
});
f.setVisible(true);
frameModifier.accept(f);
});
synchronized (lock) {
try {
lock.wait(100000);
// Wait some time because the window may still be transparent.
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
}
return frame;
}
private boolean checkScreenColor(final Color expected, final Color value) {
return Math.abs(expected.getRed() - value.getRed()) <= CustomTitleBarTest.TOLERANCE
&& Math.abs(expected.getGreen() - value.getGreen()) <= CustomTitleBarTest.TOLERANCE
&& Math.abs(expected.getBlue() - value.getBlue()) <= CustomTitleBarTest.TOLERANCE;
}
private void assertScreenColorEquals(final Color expected, final Color value,
final String message) {
if (!checkScreenColor(expected, value)) {
String failureMessage = "Expected " + expected + ", but got " + value + ". Allowed tolerance is "
+ CustomTitleBarTest.TOLERANCE + ". " + message;
Assertions.fail(failureMessage);
}
}
private void assertScreenColorNotEquals(final Color expected, final Color value,
final String message) {
if (checkScreenColor(expected, value)) {
String failureMessage = "Did not expect " + expected + ", but got " + value + ". Allowed tolerance is "
+ CustomTitleBarTest.TOLERANCE + ". " + message;
Assertions.fail(failureMessage);
}
}
private void checkImage(final String fileName, final Consumer<BufferedImage> check) {
checkImage(fileName, f -> {
}, check);
}
private void checkImage(final String fileName, final Consumer<JFrame> frameModifier,
final Consumer<BufferedImage> check) {
AtomicReference<JFrame> frame = createFrame(frameModifier);
TestUtils.runOnSwingThreadNotThrowing(() -> {
Rectangle rect = frame.get().getBounds();
rect.setLocation(0, 0);
check.accept(saveWindowScreenShot(getPath(fileName), frame.get()));
});
}
@Test
@EnabledOnOs({OS.MAC, OS.WINDOWS})
void checkTitleBarColored() {
SwingUtilities.invokeLater(() -> LafManager.install(new IntelliJTheme()));
UIManager.put("macos.coloredTitleBar", true);
checkImage("colored_title_" + SystemInfo.getOsName(),
img -> assertScreenColorEquals(TITLE_BAR_COLOR, new Color(img.getRGB(img.getWidth() / 2, TITLE_BAR_Y)),
"Title color not equal."));
}
@Test
@EnabledOnOs(OS.MAC)
void checkTitleBarNotColored() {
SwingUtilities.invokeLater(() -> LafManager.install(new IntelliJTheme()));
UIManager.put("macos.coloredTitleBar", false);
checkImage("non_colored_title_" + SystemInfo.getOsName(), img -> {
Color c = new Color(img.getRGB(img.getWidth() / 2, TITLE_BAR_Y));
assertScreenColorNotEquals(TITLE_BAR_COLOR, c, "Title is colored. Shouldn't be");
assertScreenColorNotEquals(CONTENT_COLOR, c, "No native titlebar is visible");
});
}
@Test
@EnabledOnOs(OS.MAC)
void checkForDarkNativeTitle() {
SwingUtilities.invokeLater(() -> LafManager.install(new DarculaTheme()));
UIManager.put("macos.coloredTitleBar", false);
checkImage("native_title_dark_mac", img -> {
assertScreenColorNotEquals(CONTENT_COLOR, new Color(img.getRGB(img.getWidth() / 2, TITLE_BAR_Y)),
"No native titlebar is visible");
Color bg = new Color(img.getRGB(img.getWidth() / 2, TITLE_BAR_Y));
double brightness = ColorUtil.getPerceivedBrightness(bg);
Assertions.assertTrue(brightness < 80,
"Titlebar is not dark. brightness = " + brightness + ". For color " + bg);
});
}
@Test
@EnabledOnOs(OS.MAC)
void checkForLightNativeTitle() {
SwingUtilities.invokeLater(() -> LafManager.install(new IntelliJTheme()));
UIManager.put("macos.coloredTitleBar", false);
checkImage("native_title_light_mac", img -> {
assertScreenColorNotEquals(CONTENT_COLOR, new Color(img.getRGB(img.getWidth() / 2, TITLE_BAR_Y)),
"No native titlebar is visible");
Color bg = new Color(img.getRGB(img.getWidth() / 2, TITLE_BAR_Y));
double brightness = ColorUtil.getPerceivedBrightness(bg);
Assertions.assertTrue(brightness > 200,
"Titlebar is not light. brightness = " + brightness + ". For color " + bg);
});
}
@Test
@EnabledOnOs({OS.MAC, OS.WINDOWS})
void checkTitleBarHidden() {
SwingUtilities.invokeLater(() -> LafManager.install(new IntelliJTheme()));
UIManager.put("macos.coloredTitleBar", true);
Assertions.assertTrue(LafManager.isDecorationsEnabled());
checkImage("title_bar_hidden_" + SystemInfo.getOsName(),
frame -> {
JRootPane rootPane = frame.getRootPane();
rootPane.putClientProperty(DarkRootPaneUI.HIDE_TITLEBAR, true);
},
img -> assertScreenColorEquals(CONTENT_COLOR, new Color(img.getRGB(img.getWidth() / 2, TITLE_BAR_Y)),
"Titlebar isn't hidden"));
}
@Test
@EnabledOnOs(OS.WINDOWS)
void checkDisableCustomDecoration() {
SwingUtilities.invokeLater(() -> LafManager.install(new IntelliJTheme()));
checkImage("native_title_bar_window",
f -> LafManager.setDecorationsEnabled(false),
img -> assertScreenColorNotEquals(TITLE_BAR_COLOR,
new Color(img.getRGB(img.getWidth() / 2, TITLE_BAR_Y)),
"No native titlebar installed"));
}
}

4
core/src/test/java/test/FontTest.java

@ -42,7 +42,7 @@ import com.github.weisj.darklaf.LafManager;
import com.github.weisj.darklaf.theme.IntelliJTheme;
import com.github.weisj.darklaf.util.SystemInfo;
public class FontTest extends AbstractImageTest {
class FontTest extends AbstractImageTest {
private static final Map<AttributedCharacterIterator.Attribute, Integer> kerning;
@ -56,7 +56,7 @@ public class FontTest extends AbstractImageTest {
@Test
@EnabledOnOs({OS.MAC, OS.WINDOWS, OS.LINUX})
public void testFontChoices() {
void testFontChoices() {
LafManager.install(new IntelliJTheme());
JTextArea textArea = new JTextArea();
textArea.setText(DemoResources.KERNING_TEST);

6
core/src/test/java/test/NativeLibraryTest.java

@ -29,11 +29,11 @@ import org.junit.jupiter.api.condition.OS;
import com.github.weisj.darklaf.platform.macos.MacOSLibrary;
import com.github.weisj.darklaf.platform.windows.WindowsLibrary;
public class NativeLibraryTest {
class NativeLibraryTest {
@Test
@EnabledOnOs(OS.MAC)
public void testMacOSLibraryLoading() {
void testMacOSLibraryLoading() {
MacOSLibrary library = new TestMacOsLibrary();
Assertions.assertNotNull(getClass().getResource(library.getLibraryPath()), "macOS library doesn't exist");
Assertions.assertDoesNotThrow(library::updateLibrary);
@ -42,7 +42,7 @@ public class NativeLibraryTest {
@Test
@EnabledOnOs(OS.WINDOWS)
public void testWindowsLibraryLoading() {
void testWindowsLibraryLoading() {
WindowsLibrary library = new TestWindowsLibrary();
Assertions.assertNotNull(getClass().getResource(library.getX64Path() + library.getLibraryName()),
"x64 library doesn't exist");

57
core/src/test/java/test/TestUtils.java

@ -0,0 +1,57 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package test;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.*;
import org.junit.jupiter.api.Assertions;
class TestUtils {
private TestUtils() {}
static void runOnSwingThreadNotThrowing(final Runnable action) {
AtomicReference<Exception> exceptionRef = new AtomicReference<>();
try {
SwingUtilities.invokeAndWait(() -> {
try {
action.run();
} catch (Exception e) {
exceptionRef.set(e);
}
});
} catch (InterruptedException e) {
e.printStackTrace();
Assertions.fail(e.getMessage(), e);
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace();
Throwable target = e.getTargetException();
Assertions.fail(target.getMessage(), target);
}
if (exceptionRef.get() != null) {
Assertions.fail(exceptionRef.get().getMessage(), exceptionRef.get());
}
}
}

54
core/src/test/java/test/TooltipTest.java

@ -23,7 +23,6 @@ package test;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.concurrent.atomic.AtomicReference;
import javax.swing.*;
@ -40,7 +39,7 @@ import com.github.weisj.darklaf.ui.tooltip.ToolTipConstants;
import com.github.weisj.darklaf.util.DarkUIUtil;
import com.github.weisj.darklaf.util.SystemInfo;
public class TooltipTest extends AbstractImageTest {
class TooltipTest extends AbstractImageTest {
public TooltipTest() {
super("tooltip");
@ -63,7 +62,7 @@ public class TooltipTest extends AbstractImageTest {
@Test
@EnabledOnOs({OS.MAC, OS.WINDOWS})
public void testTooltipTransparency() throws Exception {
void testTooltipTransparency() throws Exception {
JToolTip toolTip = createTooltip();
SwingUtilities.invokeAndWait(() -> {
@ -74,37 +73,28 @@ public class TooltipTest extends AbstractImageTest {
Window window = DarkUIUtil.getWindow(toolTip);
SwingUtilities.invokeAndWait(() -> window.setOpacity(1));
AtomicReference<Exception> exception = new AtomicReference<>();
SwingUtilities.invokeAndWait(() -> {
try {
Component c;
for (c = toolTip.getParent(); c != null; c = c.getParent()) {
Color bg = c.getBackground();
Assertions.assertNotNull(bg, "Background is null for " + c);
Assertions.assertEquals(0, bg.getAlpha(), "Background " + bg + " is opaque " + c);
if (c instanceof Window) break;
}
Assertions.assertEquals(c, window, "Did not traverse full hierarchy");
JRootPane rootPane = SwingUtilities.getRootPane(window);
Assertions.assertNotNull(rootPane, "RootPane is null");
Assertions.assertFalse(rootPane.isOpaque(), "RootPane is opaque");
Color backgroundColor = window.getBackground();
Assertions.assertNotNull(backgroundColor, "Background is null");
BufferedImage img = saveScreenShot(getPath("tooltip_" + SystemInfo.getOsName()), window);
Assertions.assertNotNull(img, "Tooltip Image is null");
int alpha = getAlpha(img.getRGB(img.getMinX(), img.getMinY() + img.getHeight() - 1));
Assertions.assertEquals(0, alpha, "Tooltip is opaque");
} catch (Exception e) {
exception.set(e);
TestUtils.runOnSwingThreadNotThrowing(() -> {
Component c;
for (c = toolTip.getParent(); c != null; c = c.getParent()) {
Color bg = c.getBackground();
Assertions.assertNotNull(bg, "Background is null for " + c);
Assertions.assertEquals(0, bg.getAlpha(), "Background " + bg + " is opaque " + c);
if (c instanceof Window) break;
}
});
Assertions.assertEquals(c, window, "Did not traverse full hierarchy");
Exception e = exception.get();
if (e != null) Assertions.fail(e.getMessage());
JRootPane rootPane = SwingUtilities.getRootPane(window);
Assertions.assertNotNull(rootPane, "RootPane is null");
Assertions.assertFalse(rootPane.isOpaque(), "RootPane is opaque");
Color backgroundColor = window.getBackground();
Assertions.assertNotNull(backgroundColor, "Background is null");
BufferedImage img = saveScreenShot(getPath("tooltip_" + SystemInfo.getOsName()), window);
Assertions.assertNotNull(img, "Tooltip Image is null");
int alpha = getAlpha(img.getRGB(img.getMinX(), img.getMinY() + img.getHeight() - 1));
Assertions.assertEquals(0, alpha, "Tooltip is opaque");
});
}
private int getAlpha(final int rgb) {

4
macos/src/main/java/com/github/weisj/darklaf/platform/macos/ui/MacOSTitlePane.java

@ -157,9 +157,9 @@ public class MacOSTitlePane extends CustomTitlePane {
window.addWindowListener(windowListener);
propertyChangeListener = new PropertyChangeHandler();
window.addPropertyChangeListener(propertyChangeListener);
rootPanePropertyChangeListener = createRootPanePropertyChangeListener();
rootPane.addPropertyChangeListener(rootPanePropertyChangeListener);
}
rootPanePropertyChangeListener = createRootPanePropertyChangeListener();
rootPane.addPropertyChangeListener(rootPanePropertyChangeListener);
}
private void uninstallListeners() {

Loading…
Cancel
Save