mirror of https://github.com/apache/jmeter.git
Update FlatLaf & RSyntaxArea dependencies; removed Darcula LAF; correctly apply LAF on RSyntaxArea components.
This commit is contained in:
parent
d3c489885e
commit
2f128aa8e1
|
@ -45,7 +45,7 @@ dependencies {
|
||||||
api("com.fasterxml.jackson.core:jackson-annotations:2.16.1")
|
api("com.fasterxml.jackson.core:jackson-annotations:2.16.1")
|
||||||
api("com.fasterxml.jackson.core:jackson-core:2.16.1")
|
api("com.fasterxml.jackson.core:jackson-core:2.16.1")
|
||||||
api("com.fasterxml.jackson.core:jackson-databind:2.16.1")
|
api("com.fasterxml.jackson.core:jackson-databind:2.16.1")
|
||||||
api("com.fifesoft:rsyntaxtextarea:3.3.4")
|
api("com.fifesoft:rsyntaxtextarea:3.6.0")
|
||||||
api("com.formdev:svgSalamander:1.1.4")
|
api("com.formdev:svgSalamander:1.1.4")
|
||||||
api("com.github.ben-manes.caffeine:caffeine:2.9.3")
|
api("com.github.ben-manes.caffeine:caffeine:2.9.3")
|
||||||
api("com.github.weisj:darklaf-core:2.7.3")
|
api("com.github.weisj:darklaf-core:2.7.3")
|
||||||
|
@ -144,11 +144,16 @@ dependencies {
|
||||||
api("xml-apis:xml-apis:1.4.01")
|
api("xml-apis:xml-apis:1.4.01")
|
||||||
api("xmlpull:xmlpull:1.1.3.1")
|
api("xmlpull:xmlpull:1.1.3.1")
|
||||||
//FlatLaf: https://www.formdev.com/flatlaf/native-libraries/#gradle
|
//FlatLaf: https://www.formdev.com/flatlaf/native-libraries/#gradle
|
||||||
val flatlafVersion = "3.5.2"
|
val flatlafVersion = "3.6.1"
|
||||||
api("com.formdev:flatlaf:${flatlafVersion}" )
|
api("com.formdev:flatlaf:${flatlafVersion}" )
|
||||||
api("com.formdev:flatlaf:${flatlafVersion}:linux-x86_64@so")
|
api("com.formdev:flatlaf:${flatlafVersion}:linux-x86_64@so")
|
||||||
api("com.formdev:flatlaf:${flatlafVersion}:macos-x86_64@dylib")
|
api("com.formdev:flatlaf:${flatlafVersion}:macos-x86_64@dylib")
|
||||||
api("com.formdev:flatlaf:${flatlafVersion}:windows-x86_64@dll")
|
api("com.formdev:flatlaf:${flatlafVersion}:windows-x86_64@dll")
|
||||||
api("com.formdev:flatlaf-intellij-themes:${flatlafVersion}")
|
api("com.formdev:flatlaf-intellij-themes:${flatlafVersion}")
|
||||||
|
api("com.formdev:flatlaf-extras:${flatlafVersion}")
|
||||||
|
api("com.formdev:flatlaf-fonts-inter:4.1")
|
||||||
|
api("com.formdev:flatlaf-fonts-jetbrains-mono:2.304")
|
||||||
|
api("com.formdev:flatlaf-fonts-roboto:2.137")
|
||||||
|
api("com.formdev:flatlaf-fonts-roboto-mono:3.000")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,19 @@
|
||||||
package org.apache.jmeter.gui.action;
|
package org.apache.jmeter.gui.action;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.prefs.Preferences;
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
import org.apache.jmeter.gui.GuiPackage;
|
import org.apache.jmeter.gui.GuiPackage;
|
||||||
import org.apache.jmeter.gui.util.JMeterMenuBar;
|
import org.apache.jmeter.gui.util.JMeterMenuBar;
|
||||||
|
@ -32,9 +40,8 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.intellijthemes.*;
|
import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes;
|
||||||
import com.github.weisj.darklaf.LafManager;
|
import com.github.weisj.darklaf.LafManager;
|
||||||
import com.github.weisj.darklaf.theme.DarculaTheme;
|
|
||||||
import com.github.weisj.darklaf.theme.Theme;
|
import com.github.weisj.darklaf.theme.Theme;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
|
|
||||||
|
@ -103,7 +110,6 @@ public class LookAndFeelCommand extends AbstractAction {
|
||||||
if (System.getProperty("darklaf.treeRowPopup") == null) {
|
if (System.getProperty("darklaf.treeRowPopup") == null) {
|
||||||
System.setProperty("darklaf.treeRowPopup", "false");
|
System.setProperty("darklaf.treeRowPopup", "false");
|
||||||
}
|
}
|
||||||
UIManager.installLookAndFeel(JMeterMenuBar.DARCULA_LAF, JMeterMenuBar.DARCULA_LAF_CLASS);
|
|
||||||
|
|
||||||
//Add FlatLAF Themes
|
//Add FlatLAF Themes
|
||||||
for (String flatLaf : new String[]{"FlatLightLaf", "FlatDarkLaf", "FlatIntelliJLaf", "FlatDarculaLaf"}) {
|
for (String flatLaf : new String[]{"FlatLightLaf", "FlatDarkLaf", "FlatIntelliJLaf", "FlatDarculaLaf"}) {
|
||||||
|
@ -126,7 +132,7 @@ public class LookAndFeelCommand extends AbstractAction {
|
||||||
|
|
||||||
List<MenuItem> items = new ArrayList<>();
|
List<MenuItem> items = new ArrayList<>();
|
||||||
for (UIManager.LookAndFeelInfo laf : JMeterMenuBar.getAllLAFs()) {
|
for (UIManager.LookAndFeelInfo laf : JMeterMenuBar.getAllLAFs()) {
|
||||||
if (!laf.getClassName().equals(JMeterMenuBar.DARCULA_LAF_CLASS)) {
|
if (!laf.getClassName().equals(JMeterMenuBar.DARKLAF_LAF_CLASS)) {
|
||||||
items.add(MenuItem.of(laf.getName(), laf.getClassName()));
|
items.add(MenuItem.of(laf.getName(), laf.getClassName()));
|
||||||
} else {
|
} else {
|
||||||
for (Theme theme : LafManager.getRegisteredThemes()) {
|
for (Theme theme : LafManager.getRegisteredThemes()) {
|
||||||
|
@ -161,6 +167,8 @@ public class LookAndFeelCommand extends AbstractAction {
|
||||||
public static String getJMeterLaf(){
|
public static String getJMeterLaf(){
|
||||||
String laf = PREFS.get(USER_PREFS_KEY, null);
|
String laf = PREFS.get(USER_PREFS_KEY, null);
|
||||||
if (laf != null) {
|
if (laf != null) {
|
||||||
|
for (UIManager.LookAndFeelInfo lafInfo : JMeterMenuBar.getAllLAFs())
|
||||||
|
if (lafInfo.getName().equalsIgnoreCase(laf))
|
||||||
return checkLafName(laf);
|
return checkLafName(laf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,10 +184,7 @@ public class LookAndFeelCommand extends AbstractAction {
|
||||||
if (laf != null) {
|
if (laf != null) {
|
||||||
return checkLafName(laf);
|
return checkLafName(laf);
|
||||||
}
|
}
|
||||||
laf = JMeterUtils.getPropDefault(JMETER_LAF, JMeterMenuBar.DARCULA_LAF_CLASS);
|
|
||||||
if (laf != null) {
|
|
||||||
return checkLafName(laf);
|
|
||||||
}
|
|
||||||
return UIManager.getCrossPlatformLookAndFeelClassName();
|
return UIManager.getCrossPlatformLookAndFeelClassName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,12 +199,11 @@ public class LookAndFeelCommand extends AbstractAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
String jMeterLaf = getJMeterLaf();
|
String jMeterLaf = getJMeterLaf();
|
||||||
if (jMeterLaf.equals(JMeterMenuBar.DARCULA_LAF_CLASS)) {
|
if (jMeterLaf != null) {
|
||||||
// Convert old Darcula to new Darklaf-Darcula LaF
|
return MenuItem.of("default", jMeterLaf).command; // $NON-NLS-1$
|
||||||
return MenuItem.ofDarklafTheme(new DarculaTheme()).command;
|
} else {
|
||||||
|
return MenuItem.of("default", UIManager.getCrossPlatformLookAndFeelClassName()).command; // $NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
return MenuItem.of("default", jMeterLaf).command; // $NON-NLS-1$
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if LAF is a built-in one
|
// Check if LAF is a built-in one
|
||||||
|
|
|
@ -40,8 +40,6 @@ import javax.swing.MenuElement;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.UIManager.LookAndFeelInfo;
|
import javax.swing.UIManager.LookAndFeelInfo;
|
||||||
|
|
||||||
import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes;
|
|
||||||
|
|
||||||
import org.apache.jmeter.gui.GuiPackage;
|
import org.apache.jmeter.gui.GuiPackage;
|
||||||
import org.apache.jmeter.gui.action.ActionNames;
|
import org.apache.jmeter.gui.action.ActionNames;
|
||||||
import org.apache.jmeter.gui.action.ActionRouter;
|
import org.apache.jmeter.gui.action.ActionRouter;
|
||||||
|
@ -104,10 +102,8 @@ public class JMeterMenuBar extends JMenuBar implements LocaleChangeListener {
|
||||||
|
|
||||||
public static final String SYSTEM_LAF = "System"; // $NON-NLS-1$
|
public static final String SYSTEM_LAF = "System"; // $NON-NLS-1$
|
||||||
public static final String CROSS_PLATFORM_LAF = "CrossPlatform"; // $NON-NLS-1$
|
public static final String CROSS_PLATFORM_LAF = "CrossPlatform"; // $NON-NLS-1$
|
||||||
public static final String DARCULA_LAF = "Darcula"; // $NON-NLS-1$
|
|
||||||
public static final String DARKLAF_LAF = "Darklaf"; // $NON-NLS-1$
|
public static final String DARKLAF_LAF = "Darklaf"; // $NON-NLS-1$
|
||||||
public static final String FLAT_LAF = "FlatLaf"; // $NON-NLS-1$
|
public static final String FLAT_LAF = "FlatLaf"; // $NON-NLS-1$
|
||||||
public static final String DARCULA_LAF_CLASS = "com.bulenkov.darcula.DarculaLaf"; // $NON-NLS-1$
|
|
||||||
public static final String DARKLAF_LAF_CLASS = "com.github.weisj.darklaf.DarkLaf"; // $NON-NLS-1$
|
public static final String DARKLAF_LAF_CLASS = "com.github.weisj.darklaf.DarkLaf"; // $NON-NLS-1$
|
||||||
public static final String FLATLAF_LAF_CLASS = "com.formdev.flatlaf.FlatLightLaf"; // $NON-NLS-1$
|
public static final String FLATLAF_LAF_CLASS = "com.formdev.flatlaf.FlatLightLaf"; // $NON-NLS-1$
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,9 @@ import org.apache.jorphan.gui.JFactory;
|
||||||
import org.apache.jorphan.gui.JMeterUIDefaults;
|
import org.apache.jorphan.gui.JMeterUIDefaults;
|
||||||
import org.apache.jorphan.gui.ui.TextComponentUI;
|
import org.apache.jorphan.gui.ui.TextComponentUI;
|
||||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||||
|
import org.fife.ui.rsyntaxtextarea.Style;
|
||||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||||
|
import org.fife.ui.rsyntaxtextarea.SyntaxScheme;
|
||||||
import org.fife.ui.rsyntaxtextarea.Theme;
|
import org.fife.ui.rsyntaxtextarea.Theme;
|
||||||
import org.fife.ui.rtextarea.RUndoManager;
|
import org.fife.ui.rtextarea.RUndoManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -95,6 +97,7 @@ public class JSyntaxTextArea extends RSyntaxTextArea {
|
||||||
public static JSyntaxTextArea getInstance(int rows, int cols, boolean disableUndo) {
|
public static JSyntaxTextArea getInstance(int rows, int cols, boolean disableUndo) {
|
||||||
try {
|
try {
|
||||||
JSyntaxTextArea jSyntaxTextArea = new JSyntaxTextArea(rows, cols, disableUndo);
|
JSyntaxTextArea jSyntaxTextArea = new JSyntaxTextArea(rows, cols, disableUndo);
|
||||||
|
jSyntaxTextArea.createPopupMenu();
|
||||||
JFactory.withDynamic(jSyntaxTextArea, JSyntaxTextArea::applyTheme);
|
JFactory.withDynamic(jSyntaxTextArea, JSyntaxTextArea::applyTheme);
|
||||||
// Gutter styling is only applied if the text area is contained in a scroll pane.
|
// Gutter styling is only applied if the text area is contained in a scroll pane.
|
||||||
jSyntaxTextArea.addHierarchyListener(GUTTER_THEME_PATCHER);
|
jSyntaxTextArea.addHierarchyListener(GUTTER_THEME_PATCHER);
|
||||||
|
@ -148,25 +151,50 @@ public class JSyntaxTextArea extends RSyntaxTextArea {
|
||||||
final boolean isFlatlafTheme = LookAndFeelCommand.isFlatlafTheme();
|
final boolean isFlatlafTheme = LookAndFeelCommand.isFlatlafTheme();
|
||||||
final Theme theme = isDarklafTheme ? new DarklafRSyntaxTheme(jSyntaxTextArea) : (LookAndFeelCommand.isDark() ? DEFAULT_DARK_THEME : DEFAULT_THEME);
|
final Theme theme = isDarklafTheme ? new DarklafRSyntaxTheme(jSyntaxTextArea) : (LookAndFeelCommand.isDark() ? DEFAULT_DARK_THEME : DEFAULT_THEME);
|
||||||
|
|
||||||
|
// Calculate scaled font size
|
||||||
|
float scale = JMeterUIDefaults.INSTANCE.getScale();
|
||||||
|
Font baseFont;
|
||||||
|
if (USER_FONT_FAMILY != null) {
|
||||||
|
baseFont = JMeterUIDefaults.createFont(USER_FONT_FAMILY, Font.PLAIN, USER_FONT_SIZE > 0 ? USER_FONT_SIZE : 12);
|
||||||
|
} else {
|
||||||
|
baseFont = jSyntaxTextArea.getFont();
|
||||||
|
}
|
||||||
|
if (Math.abs(scale - 1.0f) > 0.01) {
|
||||||
|
baseFont = baseFont.deriveFont(baseFont.getSize2D() * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply theme first
|
||||||
|
if (theme != null) {
|
||||||
|
theme.apply(jSyntaxTextArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply scaled font to all token types
|
||||||
|
SyntaxScheme scheme = jSyntaxTextArea.getSyntaxScheme();
|
||||||
|
for (int i = 0; i < scheme.getStyleCount(); i++) {
|
||||||
|
Style style = scheme.getStyle(i);
|
||||||
|
if (style != null) {
|
||||||
|
if (style.font != null) {
|
||||||
|
// Keep the style (bold/italic) but use scaled size
|
||||||
|
style.font = style.font.deriveFont(baseFont.getSize2D());
|
||||||
|
} else {
|
||||||
|
style.font = baseFont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jSyntaxTextArea.setFont(baseFont);
|
||||||
|
jSyntaxTextArea.setSyntaxScheme(scheme);
|
||||||
|
jSyntaxTextArea.setFractionalFontMetricsEnabled(true);
|
||||||
|
|
||||||
if (isFlatlafTheme) {
|
if (isFlatlafTheme) {
|
||||||
jSyntaxTextArea.setForeground(UIManager.getColor("TextArea.foreground"));
|
jSyntaxTextArea.setForeground(UIManager.getColor("TextArea.foreground"));
|
||||||
jSyntaxTextArea.setCaretColor(UIManager.getColor("TextArea.caretForeground"));
|
jSyntaxTextArea.setCaretColor(UIManager.getColor("TextArea.caretForeground"));
|
||||||
jSyntaxTextArea.setSelectionColor(UIManager.getColor("TextArea.selectionBackground"));
|
jSyntaxTextArea.setSelectionColor(UIManager.getColor("TextArea.selectionBackground"));
|
||||||
jSyntaxTextArea.setSelectedTextColor(UIManager.getColor("TextArea.selectionForeground"));
|
jSyntaxTextArea.setSelectedTextColor(UIManager.getColor("TextArea.selectionForeground"));
|
||||||
//not set in all themes
|
if (UIManager.getColor("Hyperlink.linkColor") != null) {
|
||||||
if (UIManager.getColor("Hyperlink.linkColor") != null)
|
|
||||||
jSyntaxTextArea.setHyperlinkForeground(UIManager.getColor("Hyperlink.linkColor"));
|
jSyntaxTextArea.setHyperlinkForeground(UIManager.getColor("Hyperlink.linkColor"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theme != null) {
|
|
||||||
theme.apply(jSyntaxTextArea);
|
|
||||||
Font font = jSyntaxTextArea.getFont();
|
|
||||||
float scale = JMeterUIDefaults.INSTANCE.getScale();
|
|
||||||
if (Math.abs(scale - 1.0f) > 0.01) {
|
|
||||||
font = font.deriveFont(font.getSize2D() * scale);
|
|
||||||
jSyntaxTextArea.setFont(font);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!isDarklafTheme) {
|
if (!isDarklafTheme) {
|
||||||
// Darklaf themes provide a custom background color for editors, so we don't overwrite it.
|
// Darklaf themes provide a custom background color for editors, so we don't overwrite it.
|
||||||
Color color = UIManager.getColor("TextArea.background");
|
Color color = UIManager.getColor("TextArea.background");
|
||||||
|
@ -258,6 +286,16 @@ public class JSyntaxTextArea extends RSyntaxTextArea {
|
||||||
super.setMarkOccurrences(HIGHLIGHT_OCCURRENCES);
|
super.setMarkOccurrences(HIGHLIGHT_OCCURRENCES);
|
||||||
this.disableUndo = disableUndo;
|
this.disableUndo = disableUndo;
|
||||||
|
|
||||||
|
// Add component listener to handle window resizing
|
||||||
|
addComponentListener(new java.awt.event.ComponentAdapter() {
|
||||||
|
@Override
|
||||||
|
public void componentResized(java.awt.event.ComponentEvent e) {
|
||||||
|
// Ensure text wraps to the new width
|
||||||
|
revalidate();
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
int fontSize = USER_FONT_SIZE > 0 ? USER_FONT_SIZE : getFont().getSize();
|
int fontSize = USER_FONT_SIZE > 0 ? USER_FONT_SIZE : getFont().getSize();
|
||||||
Font font = getFont();
|
Font font = getFont();
|
||||||
if (USER_FONT_FAMILY != null) {
|
if (USER_FONT_FAMILY != null) {
|
||||||
|
|
|
@ -103,11 +103,13 @@ public class JMeterUIDefaults {
|
||||||
@API(since = "5.3", status = API.Status.INTERNAL)
|
@API(since = "5.3", status = API.Status.INTERNAL)
|
||||||
public void install() {
|
public void install() {
|
||||||
DynamicStyle.onLaFChange(() -> {
|
DynamicStyle.onLaFChange(() -> {
|
||||||
|
log.info("LAF changed, updating JMeter-specific properties"); // $NON-NLS-1$
|
||||||
// We put JMeter-specific properties into getLookAndFeelDefaults,
|
// We put JMeter-specific properties into getLookAndFeelDefaults,
|
||||||
// so the properties are removed when LaF is changed
|
// so the properties are removed when LaF is changed
|
||||||
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
|
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
|
||||||
|
|
||||||
if (Math.abs(scale - 1.0f) > 0.01f) {
|
if (Math.abs(scale - 1.0f) > 0.01f) {
|
||||||
|
log.info("Applying scale factor: {}", scale); // $NON-NLS-1$
|
||||||
scaleFonts(defaults);
|
scaleFonts(defaults);
|
||||||
scaleIntProperties(defaults, scale);
|
scaleIntProperties(defaults, scale);
|
||||||
// We don't want to make controls extra big, so we damp the scaling factors
|
// We don't want to make controls extra big, so we damp the scaling factors
|
||||||
|
@ -183,8 +185,9 @@ public class JMeterUIDefaults {
|
||||||
if (f == null) {
|
if (f == null) {
|
||||||
height = 16 * scale;
|
height = 16 * scale;
|
||||||
} else {
|
} else {
|
||||||
Canvas c = new Canvas();
|
//Canvas c = new Canvas();
|
||||||
height = c.getFontMetrics(f).getHeight();
|
//height = c.getFontMetrics(f).getHeight();
|
||||||
|
height = f.getSize2D();
|
||||||
}
|
}
|
||||||
// Set line height to be 1.3 of the font size. The number of completely made up,
|
// Set line height to be 1.3 of the font size. The number of completely made up,
|
||||||
// 1.2 seems to be the minimal usable scale. 1.3 looks good.
|
// 1.2 seems to be the minimal usable scale. 1.3 looks good.
|
||||||
|
|
Loading…
Reference in New Issue