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-core: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.github.ben-manes.caffeine:caffeine:2.9.3")
|
||||
api("com.github.weisj:darklaf-core:2.7.3")
|
||||
|
@ -144,11 +144,16 @@ dependencies {
|
|||
api("xml-apis:xml-apis:1.4.01")
|
||||
api("xmlpull:xmlpull:1.1.3.1")
|
||||
//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}:linux-x86_64@so")
|
||||
api("com.formdev:flatlaf:${flatlafVersion}:macos-x86_64@dylib")
|
||||
api("com.formdev:flatlaf:${flatlafVersion}:windows-x86_64@dll")
|
||||
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;
|
||||
|
||||
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.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
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.util.JMeterMenuBar;
|
||||
|
@ -32,9 +40,8 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
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.theme.DarculaTheme;
|
||||
import com.github.weisj.darklaf.theme.Theme;
|
||||
import com.google.auto.service.AutoService;
|
||||
|
||||
|
@ -103,7 +110,6 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
if (System.getProperty("darklaf.treeRowPopup") == null) {
|
||||
System.setProperty("darklaf.treeRowPopup", "false");
|
||||
}
|
||||
UIManager.installLookAndFeel(JMeterMenuBar.DARCULA_LAF, JMeterMenuBar.DARCULA_LAF_CLASS);
|
||||
|
||||
//Add FlatLAF Themes
|
||||
for (String flatLaf : new String[]{"FlatLightLaf", "FlatDarkLaf", "FlatIntelliJLaf", "FlatDarculaLaf"}) {
|
||||
|
@ -126,7 +132,7 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
|
||||
List<MenuItem> items = new ArrayList<>();
|
||||
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()));
|
||||
} else {
|
||||
for (Theme theme : LafManager.getRegisteredThemes()) {
|
||||
|
@ -161,6 +167,8 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
public static String getJMeterLaf(){
|
||||
String laf = PREFS.get(USER_PREFS_KEY, null);
|
||||
if (laf != null) {
|
||||
for (UIManager.LookAndFeelInfo lafInfo : JMeterMenuBar.getAllLAFs())
|
||||
if (lafInfo.getName().equalsIgnoreCase(laf))
|
||||
return checkLafName(laf);
|
||||
}
|
||||
|
||||
|
@ -176,10 +184,7 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
if (laf != null) {
|
||||
return checkLafName(laf);
|
||||
}
|
||||
laf = JMeterUtils.getPropDefault(JMETER_LAF, JMeterMenuBar.DARCULA_LAF_CLASS);
|
||||
if (laf != null) {
|
||||
return checkLafName(laf);
|
||||
}
|
||||
|
||||
return UIManager.getCrossPlatformLookAndFeelClassName();
|
||||
}
|
||||
|
||||
|
@ -194,12 +199,11 @@ public class LookAndFeelCommand extends AbstractAction {
|
|||
}
|
||||
|
||||
String jMeterLaf = getJMeterLaf();
|
||||
if (jMeterLaf.equals(JMeterMenuBar.DARCULA_LAF_CLASS)) {
|
||||
// Convert old Darcula to new Darklaf-Darcula LaF
|
||||
return MenuItem.ofDarklafTheme(new DarculaTheme()).command;
|
||||
if (jMeterLaf != null) {
|
||||
return MenuItem.of("default", jMeterLaf).command; // $NON-NLS-1$
|
||||
} 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
|
||||
|
|
|
@ -40,8 +40,6 @@ import javax.swing.MenuElement;
|
|||
import javax.swing.UIManager;
|
||||
import javax.swing.UIManager.LookAndFeelInfo;
|
||||
|
||||
import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes;
|
||||
|
||||
import org.apache.jmeter.gui.GuiPackage;
|
||||
import org.apache.jmeter.gui.action.ActionNames;
|
||||
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 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 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 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.ui.TextComponentUI;
|
||||
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
|
||||
import org.fife.ui.rsyntaxtextarea.Style;
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
|
||||
import org.fife.ui.rsyntaxtextarea.SyntaxScheme;
|
||||
import org.fife.ui.rsyntaxtextarea.Theme;
|
||||
import org.fife.ui.rtextarea.RUndoManager;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -95,6 +97,7 @@ public class JSyntaxTextArea extends RSyntaxTextArea {
|
|||
public static JSyntaxTextArea getInstance(int rows, int cols, boolean disableUndo) {
|
||||
try {
|
||||
JSyntaxTextArea jSyntaxTextArea = new JSyntaxTextArea(rows, cols, disableUndo);
|
||||
jSyntaxTextArea.createPopupMenu();
|
||||
JFactory.withDynamic(jSyntaxTextArea, JSyntaxTextArea::applyTheme);
|
||||
// Gutter styling is only applied if the text area is contained in a scroll pane.
|
||||
jSyntaxTextArea.addHierarchyListener(GUTTER_THEME_PATCHER);
|
||||
|
@ -148,25 +151,50 @@ public class JSyntaxTextArea extends RSyntaxTextArea {
|
|||
final boolean isFlatlafTheme = LookAndFeelCommand.isFlatlafTheme();
|
||||
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) {
|
||||
jSyntaxTextArea.setForeground(UIManager.getColor("TextArea.foreground"));
|
||||
jSyntaxTextArea.setCaretColor(UIManager.getColor("TextArea.caretForeground"));
|
||||
jSyntaxTextArea.setSelectionColor(UIManager.getColor("TextArea.selectionBackground"));
|
||||
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"));
|
||||
}
|
||||
|
||||
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) {
|
||||
// Darklaf themes provide a custom background color for editors, so we don't overwrite it.
|
||||
Color color = UIManager.getColor("TextArea.background");
|
||||
|
@ -258,6 +286,16 @@ public class JSyntaxTextArea extends RSyntaxTextArea {
|
|||
super.setMarkOccurrences(HIGHLIGHT_OCCURRENCES);
|
||||
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();
|
||||
Font font = getFont();
|
||||
if (USER_FONT_FAMILY != null) {
|
||||
|
|
|
@ -103,11 +103,13 @@ public class JMeterUIDefaults {
|
|||
@API(since = "5.3", status = API.Status.INTERNAL)
|
||||
public void install() {
|
||||
DynamicStyle.onLaFChange(() -> {
|
||||
log.info("LAF changed, updating JMeter-specific properties"); // $NON-NLS-1$
|
||||
// We put JMeter-specific properties into getLookAndFeelDefaults,
|
||||
// so the properties are removed when LaF is changed
|
||||
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
|
||||
|
||||
if (Math.abs(scale - 1.0f) > 0.01f) {
|
||||
log.info("Applying scale factor: {}", scale); // $NON-NLS-1$
|
||||
scaleFonts(defaults);
|
||||
scaleIntProperties(defaults, scale);
|
||||
// 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) {
|
||||
height = 16 * scale;
|
||||
} else {
|
||||
Canvas c = new Canvas();
|
||||
height = c.getFontMetrics(f).getHeight();
|
||||
//Canvas c = new Canvas();
|
||||
//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,
|
||||
// 1.2 seems to be the minimal usable scale. 1.3 looks good.
|
||||
|
|
Loading…
Reference in New Issue