Skip to content

Commit

Permalink
Add utility method to find all descendant components of a particular …
Browse files Browse the repository at this point in the history
…type. This is useful for custom serach fialogs, e.g. FindInFilesDialog, in applications
  • Loading branch information
bobbylight committed Dec 31, 2022
1 parent 1a7762c commit 487d3d3
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 7 deletions.
2 changes: 0 additions & 2 deletions RSTAUI/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ archivesBaseName = 'rstaui'
dependencies {
api 'com.fifesoft:rsyntaxtextarea:3.3.1'
api 'com.fifesoft:autocomplete:3.3.1-SNAPSHOT'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1'
}

ext.isReleaseVersion = !project.version.endsWith('SNAPSHOT')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class DecorativeIconPanel extends JPanel {
* listening to with other combo boxes or text fields without a
* DecorativeIconPanel.
*/
private static final int DEFAULT_WIDTH = 8;
public static final int DEFAULT_WIDTH = 8;

private JLabel iconLabel;
private boolean showIcon;
Expand Down
34 changes: 30 additions & 4 deletions RSTAUI/src/main/java/org/fife/rsta/ui/UIUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.*;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
Expand Down Expand Up @@ -144,6 +142,34 @@ private static SpringLayout.Constraints getConstraintsForCell(
}


/**
* Returns all components that are ancestors of {@code comp} that are of the
* specified class (or a subclass of it).
*
* @param comp The parent component.
* @param clazz The class of children to look for.
* @param <T> The type of children to look for.
* @return The matching children. This will be an empty list if none are found.
*/
@SuppressWarnings("unchecked")
public static <T> List<T> getDescendantsOfType(Container comp, Class<T> clazz) {
List<T> result = new ArrayList<>();
Stack<Component> stack = new Stack<>();
stack.add(comp);
while (!stack.isEmpty()) {
Component current = stack.pop();
if (clazz.isAssignableFrom(current.getClass())) {
result.add((T)current);
}
if (current instanceof Container) {
Container container = (Container)current;
stack.addAll(Arrays.asList(container.getComponents()));
}
}
return result;
}


/**
* Returns the singleton <code>java.awt.Desktop</code> instance, or
* <code>null</code> if it is unsupported on this platform (or the JRE
Expand Down Expand Up @@ -209,7 +235,7 @@ public static Color getErrorTextForeground() {
defaultFG.getBlue()>=160) {
return new Color(255, 160, 160);
}
return Color.red;
return Color.RED;
}


Expand Down
82 changes: 82 additions & 0 deletions RSTAUI/src/test/java/org/fife/rsta/ui/UIUtilTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Licensed under a modified BSD license.
* See the included license file for details.
*/
package org.fife.rsta.ui;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import javax.swing.*;
import java.util.List;


/**
* Unit tests for the {@code UIUtil} class.
*
* @author Robert Futrell
* @version 1.0
*/
class UIUtilTest {

@Test
void testGetDescendantsOfType_topLevelMatch() {
JLabel label = new JLabel();
List<JLabel> result = UIUtil.getDescendantsOfType(label, JLabel.class);
Assertions.assertEquals(1, result.size());
Assertions.assertEquals(label, result.get(0));
}

@Test
void testGetDescendantsOfType_nestedMatch() {
JPanel panel = new JPanel();
JLabel label = new JLabel();
panel.add(label);
List<JLabel> result = UIUtil.getDescendantsOfType(panel, JLabel.class);
Assertions.assertEquals(1, result.size());
Assertions.assertEquals(label, result.get(0));
}

@Test
void testGetDescendantsOfType_nestedTwoDeepMatch() {
JPanel panel = new JPanel();
JPanel nestedPanel = new JPanel();
panel.add(nestedPanel);
JLabel label = new JLabel();
nestedPanel.add(label);
List<JLabel> result = UIUtil.getDescendantsOfType(panel, JLabel.class);
Assertions.assertEquals(1, result.size());
Assertions.assertEquals(label, result.get(0));
}

@Test
void testGetDescendantsOfType_subclass() {
JPanel panel = new JPanel();
SubclassedJLabel label = new SubclassedJLabel();
panel.add(label);
List<JLabel> result = UIUtil.getDescendantsOfType(panel, JLabel.class);
Assertions.assertEquals(1, result.size());
Assertions.assertEquals(label, result.get(0));
}

@Test
void testGetDescendantsOfType_multiple() {
JPanel panel = new JPanel();
JPanel nestedPanel = new JPanel();
panel.add(nestedPanel);
JLabel label = new JLabel();
nestedPanel.add(label);
SubclassedJLabel label2 = new SubclassedJLabel();
panel.add(label2);
List<JLabel> result = UIUtil.getDescendantsOfType(panel, JLabel.class);
Assertions.assertEquals(2, result.size());
Assertions.assertEquals(label2, result.get(0));
Assertions.assertEquals(label, result.get(1));
}

/**
* A dummy subclass used for unit testing purposes.
*/
private static class SubclassedJLabel extends JLabel {
}
}
9 changes: 9 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ subprojects {
apply plugin: 'checkstyle'
apply plugin: 'com.github.spotbugs'

test {
useJUnitPlatform()
}

checkstyle {
toolVersion = '9.3'
}
Expand Down Expand Up @@ -56,6 +60,11 @@ subprojects {
}
}

dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1'
}

compileJava {
sourceCompatibility javaVersion.toString()
targetCompatibility javaVersion.toString()
Expand Down

0 comments on commit 487d3d3

Please sign in to comment.