GP-4154 - Theming - Fixed font issues; updated font usage with attributes

This commit is contained in:
dragonmacher 2024-02-23 13:13:06 -05:00
parent c5bad0a88f
commit b586d65a3b
91 changed files with 1309 additions and 1191 deletions

View File

@ -26,7 +26,8 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import db.Transaction;
import docking.action.DockingAction;
@ -265,8 +266,8 @@ public class DebuggerPcodeStepperProvider extends ComponentProviderAdapter {
}
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(fixedWidthFont);
protected Font getDefaultFont() {
return fixedWidthFont;
}
@Override

View File

@ -25,7 +25,6 @@ import java.util.function.BiFunction;
import javax.swing.*;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.table.TableModel;
import javax.swing.text.View;
import ghidra.docking.settings.Settings;
@ -92,11 +91,7 @@ public class CustomToStringCellRenderer<T> extends AbstractGColumnRenderer<T> {
}
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(getCustomFont());
}
protected Font getCustomFont() {
protected Font getDefaultFont() {
switch (customFont) {
default:
case DEFAULT:

View File

@ -15,11 +15,9 @@
*/
package ghidra.machinelearning.functionfinding;
import java.awt.Font;
import java.util.List;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import docking.widgets.table.AbstractDynamicTableColumn;
import docking.widgets.table.TableColumnDescriptor;
import ghidra.docking.settings.Settings;
@ -48,7 +46,7 @@ public class SimilarStartsTableModel extends AddressBasedTableModel<SimilarStart
* Construct a table model for a table to display the closest function starts to
* a potential function start
* @param plugin owning program
* @param program program
* @param program program
* @param rows similar function starts
* @param randomForestRow model and params
*/
@ -123,9 +121,10 @@ public class SimilarStartsTableModel extends AddressBasedTableModel<SimilarStart
@Override
public GColumnRenderer<String> getColumnRenderer() {
final GColumnRenderer<String> monospacedRenderer = new AbstractGColumnRenderer<>() {
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(getFixedWidthFont());
protected Font getDefaultFont() {
return fixedWidthFont;
}
@Override

View File

@ -15,7 +15,8 @@
*/
package ghidra.examples;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.*;
import javax.swing.*;
@ -30,8 +31,8 @@ import ghidra.util.HelpLocation;
import ghidra.util.Msg;
public class HelloWorldComponentProvider extends ComponentProviderAdapter {
private final static HelpLocation HELP = new HelpLocation("SampleHelpTopic",
"SampleHelpTopic_Anchor_Name");
private final static HelpLocation HELP =
new HelpLocation("SampleHelpTopic", "SampleHelpTopic_Anchor_Name");
private MyButton activeButtonObj;
private JPanel mainPanel;
private DockingAction action;
@ -64,8 +65,8 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
// the menu item will appear on the local toolbar drop down.
Icon icon = new GIcon("icon.sample.action.hello.world");
action.setMenuBarData(new MenuData(new String[] { "Misc", "Hello World" }, icon));
action.setKeyBindingData(new KeyBindingData(KeyStroke.getKeyStroke(KeyEvent.VK_W,
InputEvent.CTRL_MASK)));
action.setKeyBindingData(
new KeyBindingData(KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_MASK)));
// puts the action on the local toolbar.
action.setToolBarData(new ToolBarData(icon));
@ -81,11 +82,11 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
public void actionPerformed(ActionContext context) {
announce("Hello World");
// To get the context object,
// To get the context object,
Object contextObject = context.getContextObject();
// ...now we can cast activeObj to be a object of MyButton
// if that is necessary, as the overridden isAddToPopup() method below
// if that is necessary, as the overridden isAddToPopup() method below
// will not add the popup action if the context object is not our button
@SuppressWarnings("unused")
@ -120,8 +121,6 @@ public class HelloWorldComponentProvider extends ComponentProviderAdapter {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
panel.setBorder(BorderFactory.createTitledBorder("Example of a Component"));
activeButtonObj = new MyButton("Hello World");
Font f = activeButtonObj.getFont();
activeButtonObj.setFont(f.deriveFont(Font.BOLD, 14));
panel.add(activeButtonObj);
mainPanel.add(panel, BorderLayout.CENTER);
}

View File

@ -16,12 +16,11 @@
package ghidra.features.bsim.gui.overview;
import java.awt.Component;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import docking.widgets.table.*;
import generic.lsh.vector.LSHVectorFactory;
@ -233,8 +232,8 @@ public class BSimOverviewModel extends AddressBasedTableModel<BSimOverviewRowObj
}
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(fixedWidthFont);
protected Font getDefaultFont() {
return fixedWidthFont;
}
@Override

View File

@ -28,6 +28,7 @@ import docking.DockingWindowManager;
import docking.widgets.EmptyBorderButton;
import docking.widgets.combobox.GComboBox;
import docking.widgets.textfield.FloatingPointTextField;
import generic.theme.Gui;
import ghidra.features.bsim.query.BSimServerInfo;
import ghidra.features.bsim.query.description.DatabaseInformation;
import ghidra.features.bsim.query.facade.QueryDatabaseException;
@ -243,7 +244,7 @@ public abstract class AbstractBSimSearchDialog extends DialogComponentProvider {
contentPanel.add(comp, fullWidth ? BorderLayout.CENTER : BorderLayout.WEST);
JLabel label = new JLabel(name);
label.setFont(label.getFont().deriveFont(Font.BOLD));
Gui.registerFont(label, Font.BOLD);
titlePanel.add(label, BorderLayout.NORTH);
return panel;
@ -260,7 +261,7 @@ public abstract class AbstractBSimSearchDialog extends DialogComponentProvider {
//==================================================================================================
// test methods
//==================================================================================================
//==================================================================================================
protected void setServer(BSimServerInfo info) {
initializeConnection(info);
}
@ -271,7 +272,7 @@ public abstract class AbstractBSimSearchDialog extends DialogComponentProvider {
//==================================================================================================
// Inner Classes
//==================================================================================================
//==================================================================================================
protected abstract class BSimQueryTask extends Task {
protected Exception errorException;

View File

@ -18,11 +18,10 @@ package ghidra.features.bsim.gui.search.results;
import static ghidra.features.bsim.gui.search.results.BSimResultStatus.*;
import java.awt.Component;
import java.awt.Font;
import java.util.*;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import docking.widgets.table.*;
import generic.lsh.vector.LSHVectorFactory;
@ -56,7 +55,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
private Collection<BSimMatchResult> results = new ArrayList<BSimMatchResult>();
// Maps functions (represented by addresses) to the number of matches in the query.
// This is here to provide quick access for the MatchCountTableColumn.
// This is here to provide quick access for the MatchCountTableColumn.
private Map<Address, Integer> functionMatchMap = new HashMap<>();
public BSimMatchResultsModel(PluginTool tool, DatabaseInformation info,
@ -70,15 +69,15 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
return; // Info can be null, even if FunctionDatabase return Ready (not created yet)
}
if (info.execats != null) {
for (int i = 0; i < info.execats.size(); ++i) {
addTableColumn(new ExecCategoryColumn(info.execats.get(i)));
for (String element : info.execats) {
addTableColumn(new ExecCategoryColumn(element));
}
}
if (info.functionTags != null) {
int mask = 1;
mask <<= FunctionTagBSimFilterType.RESERVED_BITS;
for (int i = 0; i < info.functionTags.size(); ++i) {
addTableColumn(new FunctionTagColumn(info.functionTags.get(i), mask));
for (String element : info.functionTags) {
addTableColumn(new FunctionTagColumn(element, mask));
mask <<= 1;
}
}
@ -90,7 +89,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
// Must add this column here because it requires that the queryManager
// be available. At the time createTableColumnDescriptor() is called this
// be available. At the time createTableColumnDescriptor() is called this
// is not the case. The index is set to '-1' so it will be placed at the end
// of the list.
if (lshVectorFactory != null) {
@ -114,12 +113,12 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
descriptor.addHiddenColumn(new CompilerMatchColumn());
descriptor.addHiddenColumn(new MatchCountTableColumn());
descriptor.addHiddenColumn(new FunctionSizeTableColumn());
descriptor.addHiddenColumn(new FunctionTagColumn("Known Library",
FunctionTagBSimFilterType.KNOWN_LIBRARY_MASK));
descriptor.addHiddenColumn(
new FunctionTagColumn("Known Library", FunctionTagBSimFilterType.KNOWN_LIBRARY_MASK));
descriptor.addHiddenColumn(new FunctionTagColumn("Has Unimplemented",
FunctionTagBSimFilterType.HAS_UNIMPLEMENTED_MASK));
descriptor.addHiddenColumn(new FunctionTagColumn("Has Bad Data",
FunctionTagBSimFilterType.HAS_BADDATA_MASK));
descriptor.addHiddenColumn(
new FunctionTagColumn("Has Bad Data", FunctionTagBSimFilterType.HAS_BADDATA_MASK));
descriptor.addVisibleColumn(
DiscoverableTableUtils.adaptColumForModel(this, new AddressTableColumn()));
descriptor.addHiddenColumn(new MatchingFunctionAddressTableColumn());
@ -171,9 +170,9 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
/**
* Parses the given result set to find the number of matches associated with
* each base function.
*
* Parses the given result set to find the number of matches associated with
* each base function.
*
* @param queryResults the query results to inspect
*/
private void parseFunctionMatchCounts(Collection<BSimMatchResult> queryResults) {
@ -192,7 +191,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
/**
* Associate a given FunctionDescription with the entry point of the matching function in a program
* @param desc is the FunctionDescription to recover
* @param prog is the Program (possibly) containing the Function object
* @param prog is the Program (possibly) containing the Function object
* @return the entry point address of the function (if it exists), or just the address within the default space
*/
public static Address recoverAddress(FunctionDescription desc, Program prog) {
@ -288,10 +287,10 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
Address address = rowObject.getAddress();
Function function = program.getFunctionManager().getFunctionAt(address);
Function function = p.getFunctionManager().getFunctionAt(address);
boolean showNamespace = SHOW_NAMESPACE.getValue(settings);
if (function != null) {
return function.getName(showNamespace);
@ -319,7 +318,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
String name = rowObject.getSimilarFunctionName();
boolean showNamespace = SHOW_NAMESPACE.getValue(settings);
@ -365,7 +364,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
/**
* Column for showing the number of matches each base function has.
*
*
* Note the use of the {@link BSimMatchResultsModel#functionMatchMap}; this is
* for performance reasons. We don't want this class looping over the entire
* result set calculating match counts every time the table is refreshed.
@ -380,7 +379,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public Integer getValue(BSimMatchResult rowObject, Settings settings, Program program,
public Integer getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider provider) throws IllegalArgumentException {
return functionMatchMap.get(rowObject.getAddress());
}
@ -392,7 +391,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
/**
* Column for showing the address of the matching function.
* Column for showing the address of the matching function.
*/
private static class MatchingFunctionAddressTableColumn
extends AbstractProgramBasedDynamicTableColumn<BSimMatchResult, Long> {
@ -404,7 +403,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public Long getValue(BSimMatchResult rowObject, Settings settings, Program data,
public Long getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
Long addr = rowObject.getMatchFunctionDescription().getAddress();
return addr;
@ -437,8 +436,8 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(fixedWidthFont);
protected Font getDefaultFont() {
return fixedWidthFont;
}
@Override
@ -464,10 +463,10 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public Long getValue(BSimMatchResult rowObject, Settings settings, Program program,
public Long getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider provider) throws IllegalArgumentException {
Address address = rowObject.getAddress();
Function function = program.getFunctionManager().getFunctionAt(address);
Function function = p.getFunctionManager().getFunctionAt(address);
return function.getBody().getNumAddresses();
}
@ -482,7 +481,6 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
private String columnName;
ExecDateColumn(String name) {
super();
columnName = name;
}
@ -492,7 +490,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public Date getValue(BSimMatchResult rowObject, Settings settings, Program program,
public Date getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getDate();
}
@ -519,7 +517,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getExeCategoryAlphabetic(columnName);
}
@ -540,7 +538,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getArchitecture();
}
@ -561,7 +559,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getCompilerName();
}
@ -582,7 +580,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public String getValue(BSimMatchResult rowObject, Settings settings, Program program,
public String getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getMd5();
}
@ -604,7 +602,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program,
public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getSimilarity();
}
@ -630,7 +628,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program,
public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.getSignificance();
}
@ -662,7 +660,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public Double getValue(BSimMatchResult rowObject, Settings settings, Program program,
public Double getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return vectorFactory.getSelfSignificance(
rowObject.getMatchFunctionDescription().getSignatureRecord().getLSHVector());
@ -696,7 +694,7 @@ public class BSimMatchResultsModel extends AddressBasedTableModel<BSimMatchResul
}
@Override
public Boolean getValue(BSimMatchResult rowObject, Settings settings, Program data,
public Boolean getValue(BSimMatchResult rowObject, Settings settings, Program p,
ServiceProvider serviceProvider) throws IllegalArgumentException {
return rowObject.isFlagSet(mask);
}

View File

@ -23,6 +23,7 @@ import java.util.stream.Collectors;
import javax.swing.*;
import docking.DialogComponentProvider;
import generic.theme.Gui;
import ghidra.features.bsim.gui.BSimSearchPlugin;
import ghidra.features.bsim.gui.search.dialog.BSimFilterSet;
import ghidra.features.bsim.gui.search.dialog.BSimFilterSet.FilterEntry;
@ -64,7 +65,7 @@ public class BSimSearchInfoDisplayDialog extends DialogComponentProvider {
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JLabel dataLabel = new JLabel("Search Options:");
dataLabel.setFont(dataLabel.getFont().deriveFont(Font.ITALIC));
Gui.registerFont(dataLabel, Font.ITALIC);
panel.add(dataLabel);
panel.add(new JLabel(""));
@ -89,7 +90,7 @@ public class BSimSearchInfoDisplayDialog extends DialogComponentProvider {
panel.add(new JLabel(""));
panel.add(new JLabel(""));
JLabel filterLabel = new JLabel("Filters:");
filterLabel.setFont(filterLabel.getFont().deriveFont(Font.ITALIC));
Gui.registerFont(filterLabel, Font.ITALIC);
panel.add(filterLabel);
panel.add(new JLabel(""));

View File

@ -166,19 +166,26 @@ color.bg.plugin.windowlocation.screens = color.palette.orange
color.bg.plugin.windowlocation.window.selected = color.palette.lime
color.fg.plugin.windowlocation.window.text = color.palette.gray
font.print = SansSerif-PLAIN-10
font.splash.infopanel = SansSerif-BOLD-14
font.plugin.assembly.dual.text.field = font.monospaced
font.plugin.console = font.monospaced
font.plugin.entropy.label.knot = sansserif-bold-12
font.plugin.function.text.editor = sansserif-plain-18
font.plugin.instruction.table.renderer = courier-plain-14
font.plugin.instruction.info = font.monospaced[14]
font.plugin.service.text.editor = font.monospaced
font.plugin.scripts.text.editor = font.monospaced
font.plugin.assembly.dual.text.field = font.monospaced
font.plugin.instruction.table.renderer = courier-plain-14
font.plugin.entropy.label.knot = SansSerif-BOLD-12
font.plugin.instruction.info = font.monospaced[14]
font.plugin.tabs = SansSerif-PLAIN-11
font.plugin.tabs.list = SansSerif-BOLD-9
font.plugin.tips = Dialog-PLAIN-12
font.plugin.tips.label = font.plugin.tips[BOLD]
font.plugin.strings.buttons = sansserif-plain-10
font.plugin.tabs = sansserif-plain-11
font.plugin.tabs.list = sansserif-bold-9
font.plugin.tips = dialog-plain-12
font.plugin.tips.label = font.plugin.tips[bold]
font.plugin.terminal = font.monospaced
font.plugin.terminal.completion.list = dialog-plain-12
font.plugin.window.location = font.monospaced[40]

View File

@ -17,6 +17,7 @@ package ghidra.app.merge;
import java.awt.Color;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Palette;
public interface MergeConstants {
@ -29,13 +30,13 @@ public interface MergeConstants {
public static final String LATEST_TITLE = "Latest";
public static final String MY_TITLE = "Checked Out";
public Color CONFLICT_COLOR = Palette.MAROON;
public GColor CONFLICT_COLOR = Palette.MAROON;
public static final Color HIGHLIGHT_COLOR = Palette.LIGHT_GRAY;
// The following are standardized names for use in passing resolve
// The following are standardized names for use in passing resolve
// information between individual merge managers.
// For example:
// the data type merger knows what data type in the result is equivalent
// the data type merger knows what data type in the result is equivalent
// to a given data type from my checked out program. The code unit and
// function mergers need to be able to get this information so they
// don't unknowingly re-introduce a data type that was already eliminated

View File

@ -16,13 +16,14 @@
package ghidra.app.merge.datatypes;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.util.Arrays;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.*;
import generic.theme.*;
import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.app.merge.MergeConstants;
import ghidra.docking.settings.Settings;
@ -36,23 +37,21 @@ import ghidra.util.UniversalID;
/**
* Panel to show the contents of a Data Type.
*
*
*/
class DataTypePanel extends JPanel {
public Color SOURCE_COLOR = Palette.GREEN;
public GColor SOURCE_COLOR = Palette.GREEN;
private DataType dataType;
private JTextPane textPane;
private StyledDocument doc;
private SimpleAttributeSet pathAttrSet;
private SimpleAttributeSet nameAttrSet;
private SimpleAttributeSet sourceAttrSet;
private SimpleAttributeSet offsetAttrSet;
private SimpleAttributeSet contentAttrSet;
private SimpleAttributeSet fieldNameAttrSet;
private SimpleAttributeSet commentAttrSet;
private SimpleAttributeSet deletedAttrSet;
private SimpleAttributeSet pathAttrs;
private SimpleAttributeSet nameAttrs;
private SimpleAttributeSet sourceAttrs;
private SimpleAttributeSet offsetAttrs;
private SimpleAttributeSet contentAttrs;
private SimpleAttributeSet fieldNameAttrs;
private SimpleAttributeSet commentAttrs;
private SimpleAttributeSet deletedAttrs;
DataTypePanel(DataType dataType) {
super(new BorderLayout());
@ -91,58 +90,27 @@ class DataTypePanel extends JPanel {
add(textPane, BorderLayout.CENTER);
textPane.setEditable(false);
pathAttrSet = new SimpleAttributeSet();
pathAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
pathAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
pathAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
pathAttrSet.addAttribute(StyleConstants.Foreground, MergeConstants.CONFLICT_COLOR);
Font monospaced = Gui.getFont("font.monospaced");
Font bold = Gui.getFont("font.standard.bold");
nameAttrSet = new SimpleAttributeSet();
nameAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
nameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
nameAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
sourceAttrSet = new SimpleAttributeSet();
sourceAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
sourceAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
sourceAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
sourceAttrSet.addAttribute(StyleConstants.Foreground, SOURCE_COLOR);
offsetAttrSet = new SimpleAttributeSet();
offsetAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
offsetAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
offsetAttrSet.addAttribute(StyleConstants.Foreground, Palette.BLACK);
contentAttrSet = new SimpleAttributeSet();
contentAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
contentAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
contentAttrSet.addAttribute(StyleConstants.Foreground, Palette.BLUE);
fieldNameAttrSet = new SimpleAttributeSet();
fieldNameAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
fieldNameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
fieldNameAttrSet.addAttribute(StyleConstants.Foreground, Palette.MAGENTA);
commentAttrSet = new SimpleAttributeSet();
commentAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
commentAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
commentAttrSet.addAttribute(StyleConstants.Foreground, Palette.LIME);
deletedAttrSet = new SimpleAttributeSet();
deletedAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
deletedAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
deletedAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
deletedAttrSet.addAttribute(StyleConstants.Foreground, Palette.RED);
pathAttrs = new GAttributes(bold, MergeConstants.CONFLICT_COLOR);
nameAttrs = new GAttributes(bold);
sourceAttrs = new GAttributes(bold, SOURCE_COLOR);
offsetAttrs = new GAttributes(monospaced, Palette.BLACK);
contentAttrs = new GAttributes(monospaced, Palette.BLUE);
fieldNameAttrs = new GAttributes(monospaced, Palette.MAGENTA);
commentAttrs = new GAttributes(monospaced, Palette.LIME);
deletedAttrs = new GAttributes(bold, Palette.RED);
setDataType(dataType);
}
private void formatPath(DataType dt) {
insertString("Path: " + dt.getCategoryPath() + "\n\n", pathAttrSet);
insertString("Path: " + dt.getCategoryPath() + "\n\n", pathAttrs);
}
private void formatSourceArchive(DataType dt) {
insertString("Source Archive: " + getSourceArchiveName(dt) + "\n", sourceAttrSet);
insertString("Source Archive: " + getSourceArchiveName(dt) + "\n", sourceAttrs);
}
private String getSourceArchiveName(DataType dt) {
@ -156,21 +124,21 @@ class DataTypePanel extends JPanel {
private void formatAlignment(Composite composite) {
String str = CompositeInternal.getAlignmentAndPackingString(composite);
insertString(str + "\n\n", sourceAttrSet);
insertString(str + "\n\n", sourceAttrs);
}
private void insertAlignment(Composite composite) {
StringBuffer alignmentBuffer = new StringBuffer();
alignmentBuffer.append("Alignment: ");
alignmentBuffer.append(Integer.toString(composite.getAlignment()));
insertString(alignmentBuffer.toString() + "\n", sourceAttrSet);
insertString(alignmentBuffer.toString() + "\n", sourceAttrs);
}
private void insertLength(Composite composite) {
StringBuffer lengthBuffer = new StringBuffer();
lengthBuffer.append("Length: ");
lengthBuffer.append(Integer.toString(composite.getLength()));
insertString(lengthBuffer.toString() + "\n", sourceAttrSet);
insertString(lengthBuffer.toString() + "\n", sourceAttrs);
}
private int max(String str, int length) {
@ -184,8 +152,7 @@ class DataTypePanel extends JPanel {
DataType dt = dtc.getDataType();
StringBuilder buffer = new StringBuilder();
buffer.append(dt.getName());
if (dt instanceof BitFieldDataType &&
!((Composite) dtc.getParent()).isPackingEnabled()) {
if (dt instanceof BitFieldDataType && !((Composite) dtc.getParent()).isPackingEnabled()) {
BitFieldDataType bfDt = (BitFieldDataType) dt;
buffer.append("(");
buffer.append(Integer.toString(bfDt.getBitOffset()));
@ -210,23 +177,23 @@ class DataTypePanel extends JPanel {
offsetStr = "0x" + Integer.toHexString(dtc.getOffset());
offsetStr = StringUtilities.pad(offsetStr, ' ', offsetWidth - offsetStr.length());
offsetStr += ": ";
insertString(" " + offsetStr + " ", offsetAttrSet);
insertString(" " + offsetStr + " ", offsetAttrs);
}
fieldName = pad(fieldName, fieldNameWidth);
String typeName = pad(getDataTypeName(dtc), dtNameWidth);
insertString(" " + typeName + " ", contentAttrSet);
insertString(fieldName + " ", fieldNameAttrSet);
insertString(comment, commentAttrSet);
insertString("\n", contentAttrSet);
insertString(" " + typeName + " ", contentAttrs);
insertString(fieldName + " ", fieldNameAttrs);
insertString(comment, commentAttrs);
insertString("\n", contentAttrs);
}
private void formatCompositeText(Composite comp) {
formatSourceArchive(comp);
formatPath(comp);
formatAlignment(comp);
insertString(comp.getDisplayName(), nameAttrSet);
insertString(" { \n", contentAttrSet);
insertString(comp.getDisplayName(), nameAttrs);
insertString(" { \n", contentAttrs);
boolean showComponentOffset = false;
@ -247,7 +214,7 @@ class DataTypePanel extends JPanel {
renderComponent(component, maxDtNameLength, maxFieldNameLength, offsetLength);
}
insertString("}\n\n", contentAttrSet);
insertString("}\n\n", contentAttrs);
insertAlignment(comp);
insertLength(comp);
}
@ -279,8 +246,8 @@ class DataTypePanel extends JPanel {
private void formatEnumText(Enum enuum) {
formatSourceArchive(enuum);
formatPath(enuum);
insertString(enuum.getDisplayName(), nameAttrSet);
insertString(" { \n", contentAttrSet);
insertString(enuum.getDisplayName(), nameAttrs);
insertString(" { \n", contentAttrs);
StringBuffer sb = new StringBuffer();
@ -303,7 +270,7 @@ class DataTypePanel extends JPanel {
renderEnumEntry(entry, maxNameLength, maxValueLength);
}
sb.append("}\n");
insertString(sb.toString(), contentAttrSet);
insertString(sb.toString(), contentAttrs);
}
private void renderEnumEntry(EnumEntry entry, int maxNameLength, int maxValueLength) {
@ -311,20 +278,20 @@ class DataTypePanel extends JPanel {
name = pad(name, maxNameLength);
String valStr = Long.toHexString(entry.value);
valStr = pad(valStr, maxValueLength);
insertString(" " + name, fieldNameAttrSet);
insertString(" = 0x" + valStr, contentAttrSet);
insertString(" " + name, fieldNameAttrs);
insertString(" = 0x" + valStr, contentAttrs);
if (entry.comment != null) {
insertString(" " + entry.comment, commentAttrSet);
insertString(" " + entry.comment, commentAttrs);
}
insertString("\n", contentAttrSet);
insertString("\n", contentAttrs);
}
private void formatTypeDefText(TypeDef td) {
formatSourceArchive(td);
formatPath(td);
insertString(td.getDisplayName(), nameAttrSet);
insertString("\n", contentAttrSet);
insertString(" TypeDef on " + td.getDataType().getDisplayName(), contentAttrSet);
insertString(td.getDisplayName(), nameAttrs);
insertString("\n", contentAttrs);
insertString(" TypeDef on " + td.getDataType().getDisplayName(), contentAttrs);
}
private void formatDataTypeSettings(DataType dt) {
@ -336,10 +303,10 @@ class DataTypePanel extends JPanel {
if (defs.length == 0) {
return;
}
insertString("\n\nSettings\n", sourceAttrSet);
insertString("\n\nSettings\n", sourceAttrs);
for (SettingsDefinition def : defs) {
insertString(" " + def.getName() + ": " + def.getValueString(settings) + "\n",
contentAttrSet);
contentAttrs);
}
}
@ -350,18 +317,18 @@ class DataTypePanel extends JPanel {
DataType returnType = fd.getReturnType();
if (fd.hasNoReturn()) {
insertString(FunctionSignature.NORETURN_DISPLAY_STRING + " ", contentAttrSet);
insertString(FunctionSignature.NORETURN_DISPLAY_STRING + " ", contentAttrs);
}
insertString(returnType.getDisplayName(), contentAttrSet);
insertString(returnType.getDisplayName(), contentAttrs);
String callingConventionName = fd.getCallingConventionName();
if (!Function.UNKNOWN_CALLING_CONVENTION_STRING.equals(callingConventionName)) {
insertString(callingConventionName + " ", contentAttrSet);
insertString(callingConventionName + " ", contentAttrs);
}
insertString(" " + fd.getDisplayName(), nameAttrSet);
insertString(" (", contentAttrSet);
insertString(" " + fd.getDisplayName(), nameAttrs);
insertString(" (", contentAttrs);
boolean hasVarArgs = fd.hasVarArgs();
if ((vars.length == 0) && !hasVarArgs) {
insertString(")", contentAttrSet);
insertString(")", contentAttrs);
return;
}
int maxLength = 0;
@ -390,17 +357,17 @@ class DataTypePanel extends JPanel {
sb.append(FunctionSignature.VAR_ARGS_DISPLAY_STRING);
}
sb.append(")");
insertString(sb.toString(), contentAttrSet);
insertString(sb.toString(), contentAttrs);
}
private void formatDataType(DataType dt) {
if (dt == null) {
insertString("\n\nDeleted", deletedAttrSet);
insertString("\n\nDeleted", deletedAttrs);
return;
}
formatSourceArchive(dt);
formatPath(dt);
insertString(dt.getDisplayName(), nameAttrSet);
insertString(dt.getDisplayName(), nameAttrs);
}
private String pad(String str, int length) {

View File

@ -16,13 +16,16 @@
package ghidra.app.merge.datatypes;
import java.awt.BorderLayout;
import java.awt.Font;
import java.util.Date;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.*;
import generic.theme.GAttributes;
import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.Gui;
import ghidra.program.model.data.ArchiveType;
import ghidra.program.model.data.SourceArchive;
import ghidra.util.Msg;
@ -35,9 +38,9 @@ class SourceArchivePanel extends JPanel {
private SourceArchive sourceArchive;
private JTextPane textPane;
private StyledDocument doc;
private SimpleAttributeSet headingAttrSet;
private SimpleAttributeSet valueAttrSet;
private SimpleAttributeSet deletedAttrSet;
private SimpleAttributeSet headingAttrs;
private SimpleAttributeSet valueAttrs;
private SimpleAttributeSet deletedAttrs;
SourceArchivePanel() {
super(new BorderLayout());
@ -57,28 +60,19 @@ class SourceArchivePanel extends JPanel {
add(textPane, BorderLayout.CENTER);
textPane.setEditable(false);
headingAttrSet = new SimpleAttributeSet();
headingAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
headingAttrSet.addAttribute(StyleConstants.FontSize, 12);
headingAttrSet.addAttribute(StyleConstants.Foreground, Palette.BLUE);
Font monospaced = Gui.getFont("font.monospaced");
Font bold = Gui.getFont("font.standard.bold");
valueAttrSet = new SimpleAttributeSet();
valueAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
valueAttrSet.addAttribute(StyleConstants.FontSize, 11);
valueAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
deletedAttrSet = new SimpleAttributeSet();
deletedAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
deletedAttrSet.addAttribute(StyleConstants.FontSize, 12);
deletedAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
deletedAttrSet.addAttribute(StyleConstants.Foreground, Palette.RED);
headingAttrs = new GAttributes(monospaced, Palette.BLUE);
valueAttrs = new GAttributes(bold);
deletedAttrs = new GAttributes(bold, Palette.RED);
setSourceArchive(null);
}
private void formatSourceArchive() {
if (sourceArchive == null) {
insertString("\n\nDeleted", deletedAttrSet);
insertString("\n\nDeleted", deletedAttrs);
return;
}
// formatArchiveID();
@ -91,19 +85,19 @@ class SourceArchivePanel extends JPanel {
@SuppressWarnings("unused")
private void formatArchiveID() {
insertString(" Archive ID: ", headingAttrSet);
insertString(sourceArchive.getSourceArchiveID().getValue() + "\n", valueAttrSet);
insertString(" Archive ID: ", headingAttrs);
insertString(sourceArchive.getSourceArchiveID().getValue() + "\n", valueAttrs);
}
private void formatName() {
insertString("Name: ", headingAttrSet);
insertString(sourceArchive.getName() + "\n", valueAttrSet);
insertString("Name: ", headingAttrs);
insertString(sourceArchive.getName() + "\n", valueAttrs);
}
@SuppressWarnings("unused")
private void formatFileID() {
insertString(" File ID: ", headingAttrSet);
insertString(sourceArchive.getDomainFileID() + "\n", valueAttrSet);
insertString(" File ID: ", headingAttrs);
insertString(sourceArchive.getDomainFileID() + "\n", valueAttrs);
}
@SuppressWarnings("unused")
@ -112,21 +106,20 @@ class SourceArchivePanel extends JPanel {
String typeString = (archiveType == ArchiveType.FILE) ? "File Archive"
: (archiveType == ArchiveType.PROGRAM) ? "Program"
: (archiveType == ArchiveType.PROJECT) ? "Project Archive"
: (archiveType == ArchiveType.BUILT_IN) ? "Built-In"
: "Invalid";
insertString(" Type: ", headingAttrSet);
insertString(typeString + "\n", valueAttrSet);
: (archiveType == ArchiveType.BUILT_IN) ? "Built-In" : "Invalid";
insertString(" Type: ", headingAttrs);
insertString(typeString + "\n", valueAttrs);
}
private void formatSyncTime() {
String syncTime = new Date(sourceArchive.getLastSyncTime()).toString();
insertString("Last Sync Time: ", headingAttrSet);
insertString(syncTime + "\n", valueAttrSet);
insertString("Last Sync Time: ", headingAttrs);
insertString(syncTime + "\n", valueAttrs);
}
private void formatDirtyFlag() {
insertString("Changed Since Last Sync? ", headingAttrSet);
insertString((sourceArchive.isDirty() ? "yes" : "no") + "\n", valueAttrSet);
insertString("Changed Since Last Sync? ", headingAttrs);
insertString((sourceArchive.isDirty() ? "yes" : "no") + "\n", valueAttrs);
}
private void insertString(String str, SimpleAttributeSet attributeSet) {

View File

@ -24,13 +24,14 @@ import docking.widgets.label.GIconLabel;
import generic.theme.GIcon;
import generic.theme.GThemeDefaults.Colors;
import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.util.layout.PairLayout;
import resources.Icons;
/**
* Panel to show whether tree name and tree structure changed.
*
*
*
*
*/
class TreeChangePanel extends JPanel {
@ -74,9 +75,7 @@ class TreeChangePanel extends JPanel {
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
treeNameLabel = new GDLabel("Tree Name");
Font font = treeNameLabel.getFont();
font = font.deriveFont(Font.BOLD);
treeNameLabel.setFont(font);
Gui.registerFont(treeNameLabel, Font.BOLD);
nameLabel = new GDLabel("Name Changed");
nameIconLabel = new GIconLabel(CHANGED_ICON);

View File

@ -27,8 +27,8 @@ import ghidra.util.Msg;
/**
* Panel that shows the current conflict number and the total number of
* conflicts.
*
*
*
*
*/
public class ConflictCountPanel extends JPanel {
@ -87,7 +87,6 @@ public class ConflictCountPanel extends JPanel {
set.addAttribute(StyleConstants.Foreground, Messages.ERROR);
textAttrSet = new SimpleAttributeSet();
textAttrSet.addAttribute(StyleConstants.FontSize, 12);
countAttrSet = new SimpleAttributeSet();
countAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);

View File

@ -22,6 +22,7 @@ import javax.swing.*;
import docking.widgets.label.GDLabel;
import generic.theme.GThemeDefaults.Colors;
import generic.theme.Gui;
import ghidra.framework.options.CustomOptionsEditor;
import ghidra.util.layout.PairLayout;
@ -109,7 +110,7 @@ public class StoredAnalyzerTimesPropertyEditor extends PropertyEditorSupport
}
label = new GDLabel("TOTAL", SwingConstants.RIGHT);
label.setFont(label.getFont().deriveFont(Font.BOLD));
Gui.registerFont(label, Font.BOLD);
panel.add(label);
JTextField valueField =

View File

@ -25,6 +25,7 @@ import docking.widgets.OptionDialog;
import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GDLabel;
import generic.theme.Gui;
import ghidra.framework.GenericRunInfo;
import ghidra.framework.model.ProjectLocator;
import ghidra.framework.plugintool.PluginTool;
@ -91,8 +92,8 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
archiveField.setText(archivePathName);
}
});
Font font = archiveBrowse.getFont();
archiveBrowse.setFont(font.deriveFont(Font.BOLD));
Gui.registerFont(archiveBrowse, Font.BOLD);
archiveBrowse.setName("archiveBrowse");
// Layout the components.
@ -179,7 +180,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
* @param pArchivePathName the archive file name to display when the dialog pops up.
* @param tool the tool
*
* @return true if the user submitted valid values for the project and
* @return true if the user submitted valid values for the project and
* archive file, false if user cancelled.
*/
public boolean showDialog(ProjectLocator pProjectLocator, String pArchivePathName,
@ -222,7 +223,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
/////////////////////////////////////////////
/**
* Check the entry to determine if the user input is valid for archiving
* Check the entry to determine if the user input is valid for archiving
* a project.
*
* @return boolean true if input is OK
@ -269,8 +270,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
return file.getAbsolutePath()
.toLowerCase()
.endsWith(
ArchivePlugin.ARCHIVE_EXTENSION);
.endsWith(ArchivePlugin.ARCHIVE_EXTENSION);
}
@Override
@ -302,7 +302,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
}
/**
* Brings up a file chooser for the user to specify a directory and
* Brings up a file chooser for the user to specify a directory and
* filename of the archive file.
* @param approveButtonText The label for the "Open" button on the file chooser
* @param approveToolTip The tool tip for the "Open" button on the file chooser
@ -311,8 +311,7 @@ public class ArchiveDialog extends ReusableDialogComponentProvider {
private String chooseArchiveFile(String approveButtonText, String approveToolTip) {
GhidraFileChooser jarFileChooser =
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
archivePathName);
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives", archivePathName);
jarFileChooser.setTitle("Archive a Ghidra Project");
File jarFile = null;
if (archivePathName != null && archivePathName.length() != 0) {

View File

@ -26,6 +26,7 @@ import docking.ReusableDialogComponentProvider;
import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.label.GDLabel;
import generic.theme.Gui;
import ghidra.framework.GenericRunInfo;
import ghidra.framework.model.ProjectLocator;
import ghidra.framework.preferences.Preferences;
@ -33,7 +34,7 @@ import ghidra.util.*;
import ghidra.util.filechooser.ExtensionFileFilter;
/**
* Dialog to prompt the user for the archive file to restore
* Dialog to prompt the user for the archive file to restore
* and where to restore it to.
*/
public class RestoreDialog extends ReusableDialogComponentProvider {
@ -112,8 +113,8 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
}
}
});
Font font = archiveBrowse.getFont();
archiveBrowse.setFont(font.deriveFont(Font.BOLD));
Gui.registerFont(archiveBrowse, Font.BOLD);
restoreLabel = new GDLabel(" Restore Directory ");
restoreField = new JTextField();
@ -129,8 +130,8 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
restoreField.setText(dirPath);
}
});
font = restoreBrowse.getFont();
restoreBrowse.setFont(font.deriveFont(Font.BOLD));
Gui.registerFont(restoreBrowse, Font.BOLD);
projectNameLabel = new GDLabel(" Project Name ");
projectNameField = new JTextField();
@ -365,7 +366,7 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
}
/**
* Creates a directory chooser for selecting the directory where the
* Creates a directory chooser for selecting the directory where the
* archive will be restored..
* @return the file chooser.
*/
@ -380,7 +381,7 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
}
/**
* Brings up a file chooser for the user to specify a directory and
* Brings up a file chooser for the user to specify a directory and
* filename that are used for the Project location and name
* @param approveButtonText The label for the "Open" button on the file chooser
* @param approveToolTip The tool tip for the "Open" button on the file chooser
@ -389,8 +390,7 @@ public class RestoreDialog extends ReusableDialogComponentProvider {
String chooseArchiveFile(String approveButtonText, String approveToolTip) {
GhidraFileChooser jarFileChooser =
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives",
archivePathName);
createFileChooser(ArchivePlugin.ARCHIVE_EXTENSION, "Ghidra Archives", archivePathName);
jarFileChooser.setTitle("Restore a Ghidra Project - Archive");
String lastDirSelected = Preferences.getProperty(ArchivePlugin.LAST_ARCHIVE_DIR);
if (lastDirSelected != null) {

View File

@ -16,12 +16,13 @@
package ghidra.app.plugin.core.comments;
import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.text.*;
import generic.theme.GColor;
import generic.theme.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.CommentHistory;
import ghidra.program.model.listing.Program;
@ -36,8 +37,8 @@ import ghidra.util.Msg;
class CommentHistoryPanel extends JPanel {
private final static String NO_HISTORY = "No History Found";
private SimpleAttributeSet userAttrSet;
private SimpleAttributeSet dateAttrSet;
private SimpleAttributeSet userAttrs;
private SimpleAttributeSet dateAttrs;
private SimpleAttributeSet textAttrSet;
private SimpleAttributeSet tabAttrSet;
@ -47,7 +48,7 @@ class CommentHistoryPanel extends JPanel {
private int commentType;
/**
* Construct a new CommentHistoryPanel
* Construct a new CommentHistoryPanel
* @param commentType comment type
*/
CommentHistoryPanel(int commentType) {
@ -60,7 +61,7 @@ class CommentHistoryPanel extends JPanel {
/**
* Show the comment history
* @param program program
* @param program program
* @param addr address of comment history
*/
void showCommentHistory(Program program, Address addr) {
@ -100,11 +101,11 @@ class CommentHistoryPanel extends JPanel {
if (offset > 0) {
userName = "\n" + userName;
}
doc.insertString(offset, userName, userAttrSet);
doc.insertString(offset, userName, userAttrs);
offset = doc.getLength();
doc.insertString(offset,
"\t" + DateUtils.formatDateTimestamp(history.getModificationDate()), dateAttrSet);
"\t" + DateUtils.formatDateTimestamp(history.getModificationDate()), dateAttrs);
doc.setParagraphAttributes(offset, 1, tabAttrSet, false);
offset = doc.getLength();
@ -112,25 +113,13 @@ class CommentHistoryPanel extends JPanel {
}
private void setUpAttributes() {
textAttrSet = new SimpleAttributeSet();
textAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
textAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
textAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.plugin.comments.history.text"));
userAttrSet = new SimpleAttributeSet();
userAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
userAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
userAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
userAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.plugin.comments.history.user"));
dateAttrSet = new SimpleAttributeSet();
dateAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
dateAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
dateAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
dateAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.plugin.comments.history.date"));
Font bold = Gui.getFont("font.standard.bold");
Font monospaced = Gui.getFont("font.monospaced");
textAttrSet =
new GAttributes(monospaced, new GColor("color.fg.plugin.comments.history.text"));
userAttrs = new GAttributes(bold, new GColor("color.fg.plugin.comments.history.user"));
dateAttrs = new GAttributes(bold, new GColor("color.fg.plugin.comments.history.date"));
tabAttrSet = new SimpleAttributeSet();
TabStop tabs = new TabStop(100, StyleConstants.ALIGN_LEFT, TabStop.LEAD_NONE);

View File

@ -39,6 +39,7 @@ import docking.widgets.pathmanager.PathnameTablePanel;
import docking.widgets.table.GTableCellRenderer;
import docking.widgets.table.GTableCellRenderingData;
import generic.jar.ResourceFile;
import generic.theme.Gui;
import ghidra.app.plugin.core.processors.SetLanguageDialog;
import ghidra.app.util.cparser.C.CParserUtils;
import ghidra.framework.Application;
@ -371,8 +372,7 @@ class ParseDialog extends ReusableDialogComponentProvider {
updateArchitectureDescription();
languageButton.setName("Set Processor Architecture");
Font font = languageButton.getFont();
languageButton.setFont(font.deriveFont(Font.BOLD));
Gui.registerFont(languageButton, Font.BOLD);
JPanel panel = new JPanel(new BorderLayout());
panel.add(languageTextField, BorderLayout.CENTER);

View File

@ -246,8 +246,6 @@ public class FunctionEditorDialog extends DialogComponentProvider implements Mod
signatureFieldUndoRedoKeeper = DockingUtils.installUndoRedo(signatureTextField);
Font font = signatureTextField.getFont();
signatureTextField.setFont(font.deriveFont(18.0f));
panel.add(signatureTextField);
signatureTextField.setEscapeListener(e -> {

View File

@ -15,7 +15,8 @@
*/
package ghidra.app.plugin.core.function.editor;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
@ -26,12 +27,16 @@ import javax.swing.text.*;
import docking.actions.KeyBindingUtils;
import generic.theme.GColor;
import generic.theme.Gui;
import ghidra.util.Swing;
class FunctionSignatureTextField extends JTextPane {
private static final String ENTER_ACTION_NAME = "ENTER";
private static final String ESCAPE_ACTION_NAME = "ESCAPE";
private static final String TAB_ACTION_NAME = "TAB";
private static final String FONT_ID = "font.plugin.function.text.editor";
public static Color DEFAULT_COLOR =
new GColor("color.fg.plugin.function.editor.dialog.textfield.default");
public static Color PARAMETER_NAME_COLOR =
@ -52,8 +57,7 @@ class FunctionSignatureTextField extends JTextPane {
private SimpleAttributeSet errorAttributes;
FunctionSignatureTextField() {
Font myFont = getFont();
setFont(myFont.deriveFont(24.0f));
Gui.registerFont(this, FONT_ID);
doc = getStyledDocument();
AttributeSet inputAttributes = getInputAttributes();

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.widgets.textarea;
package ghidra.app.plugin.core.instructionsearch.ui;
import java.awt.*;
@ -23,8 +23,8 @@ import generic.theme.GThemeDefaults.Colors;
import generic.theme.GThemeDefaults.Colors.Messages;
/**
* Simple text area that shows a text hint when the field is empty.
*
* Simple text area that shows a text hint when the field is empty.
*
* Hint text will be shown in light grey, italicized, and in angle brackets. Normal text will
* be plain black.
*/
@ -34,7 +34,7 @@ public class HintTextArea extends JTextArea {
/**
* Constructs the class with the hint text to be shown.
*
*
* @param hint the hint
*/
public HintTextArea(String hint) {
@ -42,8 +42,8 @@ public class HintTextArea extends JTextArea {
}
/**
* Need to override the setText method so we can set font attributes.
*
* Need to override the setText method so we can set formatting attributes.
*
* @param text the text
*/
@Override
@ -74,7 +74,27 @@ public class HintTextArea extends JTextArea {
* Sets the text attributes to be used when NOT viewing the hint.
*/
protected void setAttributes() {
this.setFont(getFont().deriveFont(Font.PLAIN));
setForeground(Colors.FOREGROUND);
}
/**
* Sets the text attributes to be used when there is an error in the input.
*/
private void setErrorAttributes() {
setForeground(Colors.ERROR);
}
/**
* Invoked. when the text in the box does not pass validation.
*/
public void setError() {
setErrorAttributes();
}
/**
* Invoked when the text in the box passes validation.
*/
public void setValid() {
setAttributes();
}
}

View File

@ -1,62 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.plugin.core.instructionsearch.ui;
import java.awt.Font;
import docking.widgets.textarea.HintTextArea;
import generic.theme.GThemeDefaults.Colors;
/**
* Allows users to provide a text hint in a text field, shown only when the text is empty.
* <p>
* Hint text will be shown in light grey, italicized, and in angle brackets. Normal text will
* be plain black.
*/
public class HintTextAreaIS extends HintTextArea {
/**
* Constructs the class with the hint text to be shown.
*
* @param hint the hint
*/
public HintTextAreaIS(final String hint) {
super(hint);
}
/**
* Invoked. when the text in the box does not pass validation.
*/
public void setError() {
setErrorAttributes();
}
/**
* Invoked when the text in the box passes validation.
*/
public void setValid() {
setAttributes();
}
/**
* Sets the text attributes to be used when there is an error in the input.
*/
private void setErrorAttributes() {
this.setFont(getFont().deriveFont(Font.PLAIN));
setForeground(Colors.ERROR);
}
}

View File

@ -47,7 +47,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
// The input text area. This is a generic JTextArea but displays a textual 'hint' to inform
// the user of what type of input is required.
private HintTextAreaIS inputBytesTA;
private HintTextArea inputBytesTA;
private SelectionModeWidget selectionModeWidget;
private EndianFlipWidget endianFlipWidget;
@ -79,7 +79,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
/**
* Constructor.
*
*
* @param program the current program
* @param dialog the parent search dialog
*/
@ -108,7 +108,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
* Load a set of bytes (in string form; hex or binary) into the search
* dialog. The bytes are disassembled and displayed in the
* {@link InstructionTable}.
*
*
* @param bytes the bytes to load
*/
public void loadBytes(String bytes) {
@ -139,7 +139,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
/**
* Creates the visual components for this dialog.
*
*
* @return the new panel
*/
protected JPanel createWorkPanel() {
@ -148,7 +148,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
contentPanel.setMinimumSize(new Dimension(500, 300));
// Create the input text widget and give it a scrollbar.
inputBytesTA = new HintTextAreaIS(HINT_TEXT);
inputBytesTA = new HintTextArea(HINT_TEXT);
JScrollPane scrollPane = new JScrollPane(inputBytesTA);
inputBytesTA.addKeyListener(this);
@ -188,7 +188,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
msgPanel.clear();
// When bringing up the dialog, always populate it with whatever is in the main dialog so
// the user can edit those instructions if desired. And make sure to set the entire
// the user can edit those instructions if desired. And make sure to set the entire
// string to be selected so they can quickly delete them with a single keystroke.
//
// Note: To get the correct string for the instruction, we go to the search data
@ -251,20 +251,20 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
List<Byte> allBytes = InstructionSearchUtils.toByteArray(input);
// Now we have a valid byte string so we can start disassembling. To do this, we pass
// the entire string to the pseudo-disassembler and it will return the first
// the entire string to the pseudo-disassembler and it will return the first
// instruction. We save that one off, then remove those bytes from the main string and
// pass the now-shorter string to the disassembler, where it will return the next
// pass the now-shorter string to the disassembler, where it will return the next
// instruction, and so on, and so on...
//
// TODO: Possibly modify the PseudoDisassembler to disassemble the entire thing at
// TODO: Possibly modify the PseudoDisassembler to disassemble the entire thing at
// once, not just one instruction at a time.
//
// NOTE: Some instructions have operands that cannot be accurately calculated
// without having a specific instruction instance (ie: an operand that is an
// without having a specific instruction instance (ie: an operand that is an
// offset from the instruction address). This is obviously problematic because we
// aren't dealing with 'real' instructions that map to an address in a program;
// we're just loading bytes and trying to figure out what instructions they
// might represent. In these cases we just use the minimum address of the loaded
// aren't dealing with 'real' instructions that map to an address in a program;
// we're just loading bytes and trying to figure out what instructions they
// might represent. In these cases we just use the minimum address of the loaded
// program as the base address.
List<InstructionMetadata> instructions = new ArrayList<>();
@ -272,7 +272,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
while (allBytes.size() > 0) {
try {
// First call the disassembler to get the first instruction.
// First call the disassembler to get the first instruction.
Byte[] bytearray = new Byte[allBytes.size()];
bytearray = allBytes.toArray(bytearray);
@ -318,10 +318,10 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
/**
* Creates {@link OperandMetadata} objects for each operand in the
* instruction provided.
*
*
* @param instruction the instruction to parse
* @return list of operand metadata
* @throws MemoryAccessException
* @throws MemoryAccessException if there is an exception getting instruction bytes
*/
private List<OperandMetadata> createOperandMetadata(PseudoInstruction instruction)
throws MemoryAccessException {
@ -334,7 +334,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
operandMD.setOpType(instruction.getOperandType(i));
operandMD.setTextRep(instruction.getDefaultOperandRepresentation(i));
// The mask container is a bit tricky. The mask string we can get directly from the
// The mask container is a bit tricky. The mask string we can get directly from the
// prototype object in the pseudo instruction. For the value string we have to do
// a bit of calculating: we know the entire instruction byte string and we know
// this operand mask, so AND them together and we get the operand bytes.
@ -353,15 +353,15 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
/**
* Creates a {@link InstructionMetadata} object for the instruction
* provided.
*
*
* @param instruction the instruction to parse
* @return the instruction metadata
* @throws MemoryAccessException
* @throws MemoryAccessException if there is an exception getting instruction bytes
*/
private InstructionMetadata createInstructionMetadata(PseudoInstruction instruction)
throws MemoryAccessException {
// The mask array we can get directly from the prototype. For the value array we
// The mask array we can get directly from the prototype. For the value array we
// have to figure out which bits pertain to operands and just zero them out, so we're
// just left with the instruction (mnemonic) bits.
InstructionPrototype prototype = instruction.getPrototype();
@ -387,7 +387,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
* <li>value = 01101100 10001110</li>
* <li>--------------------------</li>
* <li>ret = 01101000 10000000</li>
*
*
* @param mask the mnemonic mask
* @param value the full instruction value string
* @return the cleared byte array
@ -400,7 +400,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
* Verifies that the input entered by the user is valid. Meaning:
* <li>The string represents a hex or binary number.</li>
* <li>The string contains only full bytes.</li>
*
*
* @return true if input is valid
*/
public boolean validateInput() {
@ -409,7 +409,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
/**
* Verifies that the given string is valid binary or hex input.
*
*
* @param input the string to validate
* @return true if valid
*/
@ -480,7 +480,7 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
/**
* Flags the given string as invalid input
*
*
*/
public void setInputInvalid() {
inputBytesTA.setError();
@ -505,12 +505,12 @@ public class InsertBytesWidget extends ReusableDialogComponentProvider implement
/**
* Need to capture keystrokes so we can validate input on the fly. Every
* time a character is typed we check the entire input for correctness.
*
*
* Note that this MUST be done in the release handler; in the type or press
* handler the input widget has not officially been updated with the new
* character.
*
* @param e
*
* @param e the event
*/
@Override
public void keyReleased(KeyEvent e) {

View File

@ -17,8 +17,8 @@ package ghidra.app.plugin.core.instructionsearch.ui;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.TableModel;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import docking.widgets.table.GTableCellRenderingData;
import generic.theme.Gui;
@ -45,20 +45,12 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
Object value = data.getValue();
JTable table = data.getTable();
int column = data.getColumnViewIndex();
boolean isSelected = data.isSelected();
boolean hasFocus = data.hasFocus();
// Do a null check on the input here to protect ourselves. This value can be null
// in certain cases (eg: change resolution on the screen [ctrl-+ on mac], then move the
// instruction window to a different monitor, then click on a cell).
if (value == null) {
return this;
}
// Get the data object backing the cell.
InstructionTableDataObject dataObject = (InstructionTableDataObject) value;
String strData = dataObject.getData();
@ -66,7 +58,7 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
JLabel theRenderer = (JLabel) super.getTableCellRendererComponent(renderData);
setTextAttributes(table, value, column);
setTextAttributes();
setBackgroundAttributes(isSelected, hasFocus, dataObject);
setBorderAttributes(dataObject, theRenderer);
setForegroundAttributes(dataObject, theRenderer);
@ -80,8 +72,6 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
private void setForegroundAttributes(InstructionTableDataObject dataObject,
JLabel theRenderer) {
// Change the foreground to use a font of our choosing. The main reason is that we
// want to use a monospaced font for binary rendering.
theRenderer.setForeground(dataObject.getForegroundColor());
Font newFont = theRenderer.getFont().deriveFont(dataObject.getFontStyle());
theRenderer.setFont(newFont);
@ -89,8 +79,6 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
private void setBackgroundAttributes(boolean isSelected, boolean hasFocus,
InstructionTableDataObject dataObject) {
// Set the background color based on what the cell says. If it's selected, make it a
// bit darker.
Color backgroundColor = dataObject.getBackgroundColor();
if (backgroundColor != null) {
if (isSelected || hasFocus) {
@ -102,10 +90,9 @@ public class InstructionTableCellRenderer extends GhidraTableCellRenderer {
}
}
private void setTextAttributes(JTable table, Object value, int col) {
private void setTextAttributes() {
setHorizontalAlignment(SwingConstants.LEFT);
TableModel model = table.getModel();
configureFont(table, model, col);
setFont(getDefaultFont());
setOpaque(true);
}
}

View File

@ -26,6 +26,7 @@ import javax.swing.event.ListDataListener;
import docking.widgets.list.GListCellRenderer;
import generic.theme.GThemeDefaults.Colors.Tooltips;
import generic.theme.Gui;
import generic.util.WindowUtilities;
import ghidra.app.plugin.core.console.CodeCompletion;
@ -34,23 +35,25 @@ import ghidra.app.plugin.core.console.CodeCompletion;
*/
public class CodeCompletionWindow extends JDialog {
private static final String FONT_ID = "font.plugin.terminal.completion.list";
protected final InterpreterPanel console;
protected final JTextPane outputTextField;
/* List of CodeCompletions.
* If the substitution value is null, then that attribute will not be
* selectable for substitution.
*/
protected List<CodeCompletion> completion_list;
protected List<CodeCompletion> completionData;
/* current list of completions */
protected JList jlist;
protected JList<CodeCompletion> jlist;
public CodeCompletionWindow(Window parent, InterpreterPanel cp, JTextPane textField) {
super(parent);
this.console = cp;
outputTextField = textField;
jlist = new JList();
completion_list = null;
jlist = new JList<>();
completionData = null;
setUndecorated(true);
/* don't steal focus from text input! */
@ -58,14 +61,14 @@ public class CodeCompletionWindow extends JDialog {
jlist.setBackground(Tooltips.BACKGROUND);
jlist.setCellRenderer(new CodeCompletionListCellRenderer());
/* add the ability to double-click a code completion */
// add the ability to double-click a code completion
MouseListener mouseListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
/* when the user clicks the popup window, make sure
* that the outputTextField gets the focus (so that the escape
* key and other hotkeys to manage the popup work correctly
*/
// when the user clicks the popup window, make sure that the outputTextField gets
// the focus (so that the escape key and other hotkeys to manage the popup work
// correctly
outputTextField.requestFocusInWindow();
/* double-click inserts a completion */
if (e.getClickCount() == 2) {
@ -74,9 +77,9 @@ public class CodeCompletionWindow extends JDialog {
}
};
jlist.addMouseListener(mouseListener);
/* actually put the components together */
getContentPane().add(new JScrollPane(jlist));
updateCompletionList(completion_list);
updateCompletionList(completionData);
jlist.addKeyListener(new KeyAdapter() {
@Override
@ -121,7 +124,7 @@ public class CodeCompletionWindow extends JDialog {
* @param list List of code completions
*/
public void updateCompletionList(List<CodeCompletion> list) {
completion_list = list;
completionData = list;
jlist.setModel(new CodeCompletionListModel(list));
jlist.setSelectionModel(new CodeCompletionListSelectionModel(list));
jlist.clearSelection();
@ -247,7 +250,7 @@ public class CodeCompletionWindow extends JDialog {
*/
@Override
public void setFont(Font font) {
jlist.setFont(font);
Gui.registerFont(jlist, FONT_ID);
}
/**
@ -256,7 +259,7 @@ public class CodeCompletionWindow extends JDialog {
*/
public void selectPrevious() {
for (int i = jlist.getSelectedIndex() - 1; i >= 0; i--) {
CodeCompletion completion = completion_list.get(i);
CodeCompletion completion = completionData.get(i);
if (CodeCompletion.isValid(completion)) {
jlist.setSelectedIndex(i);
jlist.ensureIndexIsVisible(i);
@ -271,11 +274,11 @@ public class CodeCompletionWindow extends JDialog {
*/
public void selectNext() {
if (null == completion_list) {
if (null == completionData) {
return;
}
for (int i = jlist.getSelectedIndex() + 1; i < completion_list.size(); i++) {
CodeCompletion completion = completion_list.get(i);
for (int i = jlist.getSelectedIndex() + 1; i < completionData.size(); i++) {
CodeCompletion completion = completionData.get(i);
if (CodeCompletion.isValid(completion)) {
jlist.setSelectedIndex(i);
jlist.ensureIndexIsVisible(i);
@ -296,18 +299,18 @@ public class CodeCompletionWindow extends JDialog {
if (-1 == i) {
return null;
}
return completion_list.get(i);
return completionData.get(i);
}
}
/**
* Code completion ListModel.
*/
class CodeCompletionListModel implements ListModel {
List<CodeCompletion> completion_list;
class CodeCompletionListModel implements ListModel<CodeCompletion> {
List<CodeCompletion> completionData;
public CodeCompletionListModel(List<CodeCompletion> completion_list) {
this.completion_list = completion_list;
this.completionData = completion_list;
}
@Override
@ -321,22 +324,22 @@ class CodeCompletionListModel implements ListModel {
}
@Override
public Object getElementAt(int index) {
if ((null == completion_list) || completion_list.isEmpty()) {
public CodeCompletion getElementAt(int index) {
if ((null == completionData) || completionData.isEmpty()) {
if (0 == index) {
return new CodeCompletion("(no completions available)", null, null);
}
return null;
}
return completion_list.get(index);
return completionData.get(index);
}
@Override
public int getSize() {
if ((null == completion_list) || completion_list.isEmpty()) {
if ((null == completionData) || completionData.isEmpty()) {
return 1;
}
return completion_list.size();
return completionData.size();
}
}
@ -405,12 +408,8 @@ class CodeCompletionListCellRenderer extends GListCellRenderer<CodeCompletion> {
@Override
public Component getListCellRendererComponent(JList<? extends CodeCompletion> list,
CodeCompletion codeCompletion, int index, boolean isSelected, boolean cellHasFocus) {
if (codeCompletion.getComponent() == null) {
return super.getListCellRendererComponent(list, codeCompletion, index, isSelected,
cellHasFocus);
}
JComponent component = codeCompletion.getComponent();
JLabel component = (JLabel) super.getListCellRendererComponent(list, codeCompletion, index,
isSelected, cellHasFocus);
// if it's selected, make sure it shows up that way
component.setOpaque(true);

View File

@ -28,8 +28,7 @@ import javax.swing.text.*;
import docking.DockingUtils;
import docking.actions.KeyBindingUtils;
import generic.theme.GColor;
import generic.theme.Gui;
import generic.theme.*;
import generic.util.WindowUtilities;
import ghidra.app.plugin.core.console.CodeCompletion;
import ghidra.framework.options.OptionsChangeListener;
@ -50,9 +49,9 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
"This is the font that will be used in the Console. " +
"Double-click the font example to change it.";
private static final Color NORMAL_COLOR = new GColor("color.fg.interpreterconsole");
private static final Color ERROR_COLOR = new GColor("color.fg.interpreterconsole.error");
private static final Color BG_COLOR = new GColor("color.bg.interpreterconsole");
private static final GColor NORMAL_COLOR = new GColor("color.fg.interpreterconsole");
private static final GColor ERROR_COLOR = new GColor("color.fg.interpreterconsole.error");
private static final GColor BG_COLOR = new GColor("color.bg.interpreterconsole");
public enum TextType {
STDOUT, STDERR, STDIN;
@ -84,16 +83,6 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
private boolean caretGuard = true;
private PluginTool tool;
private static SimpleAttributeSet createAttributes(Font font, Color color) {
SimpleAttributeSet attributeSet = new SimpleAttributeSet();
attributeSet.addAttribute(StyleConstants.FontFamily, font.getFamily());
attributeSet.addAttribute(StyleConstants.FontSize, font.getSize());
attributeSet.addAttribute(StyleConstants.Italic, font.isItalic());
attributeSet.addAttribute(StyleConstants.Bold, font.isBold());
attributeSet.addAttribute(StyleConstants.Foreground, color);
return attributeSet;
}
public InterpreterPanel(PluginTool tool, InterpreterConnection interpreter) {
this.tool = tool;
this.interpreter = interpreter;
@ -373,9 +362,11 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
private void updateFontAttributes(Font font) {
Font boldFont = font.deriveFont(Font.BOLD);
STDOUT_SET = createAttributes(font, NORMAL_COLOR);
STDERR_SET = createAttributes(font, ERROR_COLOR);
STDIN_SET = createAttributes(boldFont, NORMAL_COLOR);
STDOUT_SET = new GAttributes(font, NORMAL_COLOR);
STDOUT_SET = new GAttributes(font, NORMAL_COLOR);
STDERR_SET = new GAttributes(font, ERROR_COLOR);
STDIN_SET = new GAttributes(boldFont, NORMAL_COLOR);
setTextPaneFont(inputTextPane, boldFont);
setTextPaneFont(promptTextPane, font);
@ -389,8 +380,7 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
HelpLocation help = new HelpLocation(getName(), "ConsolePlugin");
options.setOptionsHelpLocation(help);
options.registerThemeFontBinding(FONT_OPTION_LABEL, FONT_ID, help,
FONT_DESCRIPTION);
options.registerThemeFontBinding(FONT_OPTION_LABEL, FONT_ID, help, FONT_DESCRIPTION);
options.registerOption(COMPLETION_WINDOW_TRIGGER_LABEL, CompletionWindowTrigger.TAB, help,
COMPLETION_WINDOW_TRIGGER_DESCRIPTION);
@ -490,8 +480,8 @@ public class InterpreterPanel extends JPanel implements OptionsChangeListener {
completionInsertionPosition = inputTextPane.getCaretPosition();
String text = getInputTextPaneText();
List<CodeCompletion> completions = InterpreterPanel.this.interpreter.getCompletions(
text, completionInsertionPosition);
List<CodeCompletion> completions =
InterpreterPanel.this.interpreter.getCompletions(text, completionInsertionPosition);
completionWindow.updateCompletionList(completions);
});
}

View File

@ -67,7 +67,7 @@ class MemoryMapProvider extends ComponentProviderAdapter {
private DockingAction deleteAction;
private DockingAction setBaseAction;
private MemoryMapPlugin plugin = null;
private MemoryMapPlugin plugin;
private Program program;
private MemoryMapManager memManager;
@ -135,8 +135,12 @@ class MemoryMapProvider extends ComponentProviderAdapter {
table.installNavigation(tool);
table.setAutoCreateColumnsFromModel(false);
GTableCellRenderer monoRenderer = new GTableCellRenderer();
monoRenderer.setFont(monoRenderer.getFixedWidthFont());
GTableCellRenderer monoRenderer = new GTableCellRenderer() {
@Override
protected Font getDefaultFont() {
return fixedWidthFont;
}
};
TableColumn column = table.getColumn(MemoryMapModel.START_COL);
column.setCellRenderer(monoRenderer);

View File

@ -1019,8 +1019,6 @@ public class EditReferencesProvider extends ComponentProviderAdapter
private class RefCellTextRenderer extends GTableCellRenderer {
RefCellTextRenderer() {
defaultFont = getFont();
boldFont = defaultFont.deriveFont(defaultFont.getStyle() | Font.BOLD);
setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
}

View File

@ -28,7 +28,6 @@ import docking.widgets.OptionDialog;
import docking.widgets.table.*;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.Gui;
import ghidra.app.cmd.register.SetRegisterCmd;
import ghidra.app.events.ProgramSelectionPluginEvent;
import ghidra.app.services.MarkerService;
@ -498,7 +497,11 @@ class RegisterValueRenderer extends GTableCellRenderer {
RegisterValueRenderer(JTable table) {
setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
Gui.registerFont(this, "font.monospaced");
}
@Override
protected Font getDefaultFont() {
return fixedWidthFont;
}
@Override

View File

@ -28,6 +28,7 @@ import javax.swing.event.ChangeListener;
import docking.DialogComponentProvider;
import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GLabel;
import generic.theme.GThemeDefaults.Ids.Fonts;
import generic.theme.Gui;
import ghidra.app.util.bean.FixedBitSizeValueField;
import ghidra.program.model.address.*;
@ -77,8 +78,6 @@ public class SetRegisterValueDialog extends DialogComponentProvider {
private JComponent buildWorkPanel(Register[] registers) {
registerComboBox = new GComboBox<>(wrapRegisters(registers));
Font f = registerComboBox.getFont().deriveFont(13f);
registerComboBox.setFont(f);
registerValueField = new FixedBitSizeValueField(32, true, false);
registerValueField.addChangeListener(new ChangeListener() {
@Override
@ -93,11 +92,11 @@ public class SetRegisterValueDialog extends DialogComponentProvider {
registerChanged();
}
});
f = Gui.getFont("font.monospaced");
addressRangeList = new JList();
addressRangeList.setEnabled(false);
addressRangeList.setFont(f);
Gui.registerFont(addressRangeList, Fonts.MONOSPACED);
JScrollPane scrollPane = new JScrollPane(addressRangeList);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Dimension d = scrollPane.getPreferredSize();

View File

@ -16,11 +16,12 @@
package ghidra.app.plugin.core.scalartable;
import java.awt.Component;
import java.awt.Font;
import java.math.BigInteger;
import java.util.Comparator;
import javax.swing.*;
import javax.swing.table.TableModel;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import docking.widgets.table.*;
import ghidra.docking.settings.Settings;
@ -321,7 +322,7 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
//==================================================================================================
// Columns & Column helpers
//==================================================================================================
//==================================================================================================
private class ScalarComparator implements Comparator<Scalar> {
@ -339,8 +340,7 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
return (o1.isSigned() ? 1 : -1);
}
return o1.isSigned()
? Long.compare(o1.getSignedValue(), o2.getSignedValue())
return o1.isSigned() ? Long.compare(o1.getSignedValue(), o2.getSignedValue())
: Long.compareUnsigned(o1.getUnsignedValue(), o2.getUnsignedValue());
}
}
@ -410,15 +410,14 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
}
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(fixedWidthFont);
protected Font getDefaultFont() {
return fixedWidthFont;
}
@Override
public ColumnConstraintFilterMode getColumnConstraintFilterMode() {
return ColumnConstraintFilterMode.ALLOW_ALL_FILTERS;
}
};
@Override
@ -440,10 +439,7 @@ public class ScalarSearchModel extends AddressBasedTableModel<ScalarRowObject> {
public Scalar getValue(ScalarRowObject rowObject, Settings settings, Program p,
ServiceProvider provider) throws IllegalArgumentException {
Scalar scalar = rowObject.getScalar();
Scalar unsigned = new Scalar(scalar.bitLength(), scalar.getUnsignedValue(), false);
return unsigned;
return new Scalar(scalar.bitLength(), scalar.getUnsignedValue(), false);
}
}

View File

@ -38,7 +38,7 @@ import docking.widgets.spinner.IntegerSpinner;
import docking.widgets.table.threaded.ThreadedTableModelListener;
import generic.jar.ResourceFile;
import generic.theme.GThemeDefaults;
import ghidra.app.services.GoToService;
import generic.theme.Gui;
import ghidra.app.services.StringTranslationService;
import ghidra.app.services.StringTranslationService.TranslateOptions;
import ghidra.docking.settings.Settings;
@ -72,6 +72,8 @@ public class EncodedStringsDialog extends DialogComponentProvider {
Map.entry(CharsetInfo.UTF16, UnicodeDataType.dataType),
Map.entry(CharsetInfo.UTF32, Unicode32DataType.dataType));
private static final String BUTTON_FONT_ID = "font.plugin.strings.buttons";
private final PluginTool tool;
private final EncodedStringsPlugin plugin;
private final Program program;
@ -148,7 +150,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param charsetName set the charset
*/
public void setSelectedCharset(String charsetName) {
@ -157,7 +159,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param b boolean
*/
public void setRequireValidStringOption(boolean b) {
@ -167,7 +169,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param b boolean
*/
public void setAllowLatinScriptOption(boolean b) {
@ -178,7 +180,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param b boolean
*/
public void setAllowCommonScriptOption(boolean b) {
@ -189,7 +191,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param b boolean
*/
public void setAllowAnyScriptOption(boolean b) {
@ -200,7 +202,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param requiredScript unicode script
*/
public void setRequiredScript(UnicodeScript requiredScript) {
@ -210,7 +212,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param b boolean
*/
public void setShowAdvancedOptions(boolean b) {
@ -221,7 +223,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param b boolean
*/
public void setShowScriptOptions(boolean b) {
@ -232,7 +234,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param b boolean
*/
public void setExcludeCodecErrors(boolean b) {
@ -243,7 +245,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @param b boolean
*/
public void setExcludeNonStdCtrlChars(boolean b) {
@ -254,7 +256,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @return table model
*/
public EncodedStringsTableModel getStringModel() {
@ -263,7 +265,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
/**
* For test/screen shot use
*
*
* @return button
*/
public JButton getCreateButton() {
@ -423,8 +425,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
table.setPreferredScrollableViewportSize(new Dimension(350, 150));
table.getSelectionModel().addListSelectionListener(e -> selectedRowChange());
GoToService goToService = tool.getService(GoToService.class);
table.installNavigation(goToService, goToService.getDefaultNavigatable());
table.installNavigation(tool);
filterPanel = new GhidraTableFilterPanel<>(table, tableModel);
}
@ -454,7 +455,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
public void keyPressed(KeyEvent e) {
// Note: we override the [ENTER] key handling to allow the user to invoke the
// dialog and just hit enter to create the string without having to do any
// clicking (otherwise the charset combobox consumes the keystroke)
// clicking (otherwise the charset combobox consumes the keystroke)
if (e.getKeyChar() == '\n') {
e.consume();
if (charsetComboBox.isPopupVisible()) {
@ -604,10 +605,10 @@ public class EncodedStringsDialog extends DialogComponentProvider {
scriptFailedCountLabel
.setToolTipText("Number of strings excluded due to failing script requirements.");
Font font = new JPanel().getFont().deriveFont(10.0f);
allowLatinScriptButton = new JToggleButton("A-Z");
allowLatinScriptButton.setName("ALLOW_LATIN_SCRIPT");
allowLatinScriptButton.setFont(font);
Gui.registerFont(allowLatinScriptButton, BUTTON_FONT_ID);
allowLatinScriptButton.setToolTipText(
"Allow Latin characters (e.g. A-Z, etc) to also be present in the string.");
allowLatinScriptButton.setSelected(true);
@ -620,7 +621,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
allowCommonScriptButton = new JToggleButton("0-9,!?");
allowCommonScriptButton.setName("ALLOW_COMMON_SCRIPT");
allowCommonScriptButton.setFont(font);
Gui.registerFont(allowCommonScriptButton, BUTTON_FONT_ID);
allowCommonScriptButton.setToolTipText(
"Allow common characters (e.g. 0-9, space, punctuation, etc) to also be present in the string.");
allowCommonScriptButton.setSelected(true);
@ -633,7 +634,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
allowAnyScriptButton = new JToggleButton("Any");
allowAnyScriptButton.setName("ALLOW_ANY_SCRIPT");
allowAnyScriptButton.setFont(font);
Gui.registerFont(allowAnyScriptButton, BUTTON_FONT_ID);
allowAnyScriptButton.setToolTipText(
"Allow all other character scripts to also be present in the string.");
allowAnyScriptButton.setSelected(true);
@ -747,13 +748,12 @@ public class EncodedStringsDialog extends DialogComponentProvider {
executeMonitoredRunnable("Creating Strings", true, true, 100, this::createStringsAndClose);
}
private void setActionItemEnablement(boolean b) {
createButton.setEnabled(b);
cancelButton.setEnabled(b);
private void setActionItemEnablement(boolean enabled) {
createButton.setEnabled(enabled);
cancelButton.setEnabled(enabled);
table.removeNavigation();
if (b) {
GoToService goToService = tool.getService(GoToService.class);
table.installNavigation(goToService, goToService.getDefaultNavigatable());
if (enabled) {
table.installNavigation(tool);
}
}
@ -834,11 +834,10 @@ public class EncodedStringsDialog extends DialogComponentProvider {
createButton.setEnabled(false);
return;
}
String createMessage = isSingleStringMode()
? "Create"
: "Create %s".formatted(rowCount == selectedRowCount || selectedRowCount == 0
? "All"
: "Selected (%d)".formatted(selectedRowCount));
String createMessage = isSingleStringMode() ? "Create"
: "Create %s"
.formatted(rowCount == selectedRowCount || selectedRowCount == 0 ? "All"
: "Selected (%d)".formatted(selectedRowCount));
createButton.setEnabled(true);
createButton.setText(createMessage);
@ -954,8 +953,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
return null;
}
File f = new File(filename);
ResourceFile rf = f.isAbsolute() && f.isFile()
? new ResourceFile(f)
ResourceFile rf = f.isAbsolute() && f.isFile() ? new ResourceFile(f)
: Application.findDataFileInAnyModule(filename);
if (rf == null) {
Msg.error(this, "Unable to find string model file: %s".formatted(filename));
@ -1012,8 +1010,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
private StringTranslationService getSelectedStringTranslationService(boolean ifEnabled) {
boolean enabled = showTranslateOptionsButton.isSelected();
return ifEnabled && !enabled
? null
return ifEnabled && !enabled ? null
: (StringTranslationService) translateComboBox.getSelectedItem();
}
@ -1081,7 +1078,7 @@ public class EncodedStringsDialog extends DialogComponentProvider {
* Execute a non-modal task that has progress and can be cancelled.
* <p>
* See {@link #executeProgressTask(Task, int)}.
*
*
* @param taskTitle String title of task
* @param canCancel boolean flag, if true task can be canceled by the user
* @param hasProgress boolean flag, if true the task has a progress meter

View File

@ -15,7 +15,6 @@
*/
package ghidra.app.plugin.debug;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
@ -59,22 +58,11 @@ public class DomainEventComponentProvider extends ComponentProviderAdapter {
return scrollPane;
}
/**
* @see docking.ComponentProvider#componentHidden()
*/
@Override
public void componentHidden() {
clear();
}
public Font getFont() {
return textArea.getFont();
}
public void setFont(Font font) {
textArea.setFont(font);
}
private void createAction() {
clearAction = new DockingAction("Clear Display", getName()) {
@Override

View File

@ -15,7 +15,6 @@
*/
package ghidra.app.plugin.debug;
import java.awt.Font;
import java.util.Date;
import ghidra.app.DeveloperPluginPackage;
@ -47,28 +46,18 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
private Program currentProgram;
private DomainEventComponentProvider provider;
private String padString;
/**
* Constructor
*/
public DomainEventDisplayPlugin(PluginTool tool) {
super(tool);
String dateStr = new Date() + ": ";
padString = dateStr.replaceAll(".", " ");
provider = new DomainEventComponentProvider(tool, getName());
// Note: this plugin in the 'Developer' category and as such does not need help
// Note: this plugin in the 'Developer' category and as such does not need help
HelpService helpService = Help.getHelpService();
helpService.excludeFromHelp(provider);
}
/**
* Put event processing code here.
*/
@Override
public void processEvent(PluginEvent event) {
if (event instanceof ProgramActivatedPluginEvent) {
@ -83,10 +72,6 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
}
}
/**
* Tells a plugin that it is no longer needed. The plugin should remove
* itself from anything that it is registered to and release any resources.
*/
@Override
public void dispose() {
if (currentProgram != null) {
@ -94,9 +79,6 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
}
}
/**
* This is the callback method for DomainObjectChangedEvents.
*/
@Override
public void domainObjectChanged(DomainObjectChangedEvent ev) {
if (tool != null && provider.isVisible()) {
@ -104,24 +86,6 @@ public class DomainEventDisplayPlugin extends Plugin implements DomainObjectList
}
}
/**
* Get the font for the text area; font property will show up on the
* plugin property sheet.
*/
public Font getFont() {
return provider.getFont();
}
/**
* Set the font for the text area; font property will show up on the
* plugin property sheet.
*/
public void setFont(Font font) {
provider.setFont(font);
tool.setConfigChanged(true);
}
/**
* Display the change event.
*/

View File

@ -27,6 +27,7 @@ import javax.swing.*;
import docking.ComponentProvider;
import docking.Tool;
import generic.theme.GColor;
import generic.theme.Gui;
import generic.util.WindowUtilities;
import generic.util.image.ImageUtils;
import ghidra.app.DeveloperPluginPackage;
@ -110,6 +111,8 @@ public class WindowLocationPlugin extends Plugin {
private class WindowLocationPanel extends JPanel {
private static final String FONT_ID = "font.plugin.window.location";
private MouseListener mousy = new MouseListener();
WindowLocationPanel() {
@ -188,9 +191,8 @@ public class WindowLocationPlugin extends Plugin {
}
private void paintWindows(Graphics2D g2d, AffineTransform xform) {
Font f = g2d.getFont();
Font biggerFont = f.deriveFont(40f);
g2d.setFont(biggerFont);
Font f = Gui.getFont(FONT_ID);
g2d.setFont(f);
g2d.setColor(FG_COLOR_WINDOW_TEXT);
Window[] windows = Window.getWindows();
@ -423,10 +425,7 @@ public class WindowLocationPlugin extends Plugin {
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((window == null) ? 0 : window.hashCode());
return result;
return Objects.hash(window);
}
@Override

View File

@ -65,10 +65,12 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
* @param fieldOptions the Options for field specific properties.
*/
protected AbstractVariableFieldFactory(String name, FieldFormatModel model,
ListingHighlightProvider highlightProvider, Options displayOptions, Options fieldOptions) {
ListingHighlightProvider highlightProvider, Options displayOptions,
Options fieldOptions) {
super(name, model, highlightProvider, displayOptions, fieldOptions);
}
@Override
protected void initDisplayOptions(Options displayOptions) {
// display options for local variables handled by FieldFactory base class
@ -110,8 +112,7 @@ public abstract class AbstractVariableFieldFactory extends FieldFactory {
super.displayOptionsChanged(options, optionName, oldValue, newValue);
}
@SuppressWarnings("deprecation")
// we know
@SuppressWarnings("deprecation") // ignore getFontMetrics() deprecation warning
private void setMetrics(Font newFont, ParameterFieldOptions paramFieldOptions) {
paramFieldOptions.defaultMetrics = Toolkit.getDefaultToolkit().getFontMetrics(newFont);
for (int i = 0; i < paramFieldOptions.fontMetrics.length; i++) {

View File

@ -29,7 +29,6 @@ import ghidra.framework.options.ToolOptions;
import ghidra.program.model.listing.Data;
import ghidra.program.util.ProgramLocation;
import ghidra.util.HelpLocation;
import ghidra.util.SystemUtilities;
import ghidra.util.classfinder.ExtensionPoint;
/**
@ -66,8 +65,8 @@ public abstract class FieldFactory implements ExtensionPoint {
* @param fieldOptions the Options for field specific properties.
*/
protected FieldFactory(String name, FieldFormatModel model,
ListingHighlightProvider highlightProvider,
Options displayOptions, Options fieldOptions) {
ListingHighlightProvider highlightProvider, Options displayOptions,
Options fieldOptions) {
this.name = name;
this.model = model;
this.hlProvider = highlightProvider;
@ -135,7 +134,7 @@ public abstract class FieldFactory implements ExtensionPoint {
public void displayOptionsChanged(Options options, String optionName, Object oldValue,
Object newValue) {
if (optionName.equals(FONT_OPTION_NAME)) {
baseFont = SystemUtilities.adjustForFontSizeOverride((Font) newValue);
baseFont = (Font) newValue;
setMetrics(baseFont);
}
else if (optionName.equals(styleOptionName)) {
@ -225,7 +224,7 @@ public abstract class FieldFactory implements ExtensionPoint {
/**
* Returns true if this given field represents the given location
* @param listingField the field
* @param location the location
* @param location the location
* @return true if this given field represents the given location
*/
public boolean supportsLocation(ListingField listingField, ProgramLocation location) {

View File

@ -40,7 +40,6 @@ import generic.theme.GThemeDefaults.Colors.Palette;
import ghidra.GhidraOptions;
import ghidra.app.util.viewer.field.ListingColors;
import ghidra.app.util.viewer.field.ListingColors.*;
import ghidra.util.SystemUtilities;
/**
* Class for displaying and manipulating field colors and fonts.
@ -133,13 +132,13 @@ public class OptionsGui extends JPanel {
/**
* Constructor
*
*
* @param font the base font for the fields.
* @param listener the listener to be notified when options change.
*/
public OptionsGui(Font font, PropertyChangeListener listener) {
propertyChangeListener = listener;
setBaseFont(SystemUtilities.adjustForFontSizeOverride(font));
setBaseFont(font);
genLayouts();
buildPanel();
fieldPanel.setBackgroundColor(BACKGROUND.getColor());
@ -217,7 +216,7 @@ public class OptionsGui extends JPanel {
/**
* callback for when the selected display field changes.
*
*
* @param index the index in the JList of the selected field.
*/
private void setSelectedIndex(int index) {
@ -735,7 +734,7 @@ public class OptionsGui extends JPanel {
/**
* This listener will be notified when changes are made that need to be applied.
*
*
* @param listener The listener to be notified.
*/
void setOptionsPropertyChangeListener(PropertyChangeListener listener) {
@ -774,9 +773,9 @@ public class OptionsGui extends JPanel {
setSelectedIndex(selectedIndex);
}
//==================================================================================================
//==================================================================================================
// Inner Classes
//==================================================================================================
//==================================================================================================
/**
* Simple layoutModel to be used for the preview panel.
@ -850,7 +849,7 @@ public class OptionsGui extends JPanel {
/**
* Constructor
*
*
* @param size the number of fields in the layout
*/
LayoutBuilder(int size) {

View File

@ -21,9 +21,8 @@ import java.util.LinkedList;
import javax.swing.JTextPane;
import javax.swing.text.*;
import generic.theme.GColor;
import generic.theme.*;
import generic.theme.GThemeDefaults.Ids.Fonts;
import generic.theme.Gui;
import ghidra.framework.options.*;
import ghidra.framework.plugintool.PluginTool;
import ghidra.util.Msg;
@ -31,9 +30,9 @@ import ghidra.util.SystemUtilities;
import ghidra.util.exception.AssertException;
import ghidra.util.task.SwingUpdateManager;
/**
/**
* A generic text pane that is used as a console to which text can be written.
*
*
* There is not test for this class, but it is indirectly tested by FrontEndGuiTest.
*/
public class ConsoleTextPane extends JTextPane implements OptionsChangeListener {
@ -52,8 +51,8 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
/** % of characters to delete when truncation is necessary */
private static double DEFAULT_TRUNCATION_FACTOR = .10;
private static SimpleAttributeSet outputAttributeSet;
private static SimpleAttributeSet errorAttributeSet;
private static SimpleAttributeSet outputAttributes;
private static SimpleAttributeSet errorAttributes;
// don't update more than once per second if lots of messages are being written
private SwingUpdateManager updateManager = new SwingUpdateManager(100, 1000, () -> doUpdate());
@ -99,7 +98,7 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
}
//==================================================================================================
// Non-interface Methods
//==================================================================================================
//==================================================================================================
private void initOptions(Options options) {
options.registerOption(MAXIMUM_CHARACTERS_OPTION_NAME, DEFAULT_MAXIMUM_CHARS, null,
@ -192,10 +191,10 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
private AttributeSet getAttributeSetByName(String attributeSetName) {
if (OUTPUT_ATTRIBUTE_VALUE.equals(attributeSetName)) {
return outputAttributeSet;
return outputAttributes;
}
else if (ERROR_ATTRIBUTE_VALUE.equals(attributeSetName)) {
return errorAttributeSet;
return errorAttributes;
}
else {
// we found an attribute type that we do not know about
@ -208,23 +207,12 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
}
private void createAttributes(Font font) {
outputAttributeSet = new SimpleAttributeSet();
outputAttributeSet.addAttribute(CUSTOM_ATTRIBUTE_KEY, OUTPUT_ATTRIBUTE_VALUE);
outputAttributeSet.addAttribute(StyleConstants.FontFamily, font.getFamily());
outputAttributeSet.addAttribute(StyleConstants.FontSize, font.getSize());
outputAttributeSet.addAttribute(StyleConstants.Italic, font.isItalic());
outputAttributeSet.addAttribute(StyleConstants.Bold, font.isBold());
outputAttributeSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.consoletextpane"));
errorAttributeSet = new SimpleAttributeSet();
errorAttributeSet.addAttribute(CUSTOM_ATTRIBUTE_KEY, ERROR_ATTRIBUTE_VALUE);
errorAttributeSet.addAttribute(StyleConstants.FontFamily, font.getFamily());
errorAttributeSet.addAttribute(StyleConstants.FontSize, font.getSize());
errorAttributeSet.addAttribute(StyleConstants.Italic, font.isItalic());
errorAttributeSet.addAttribute(StyleConstants.Bold, font.isBold());
errorAttributeSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.error.consoletextpane"));
outputAttributes = new GAttributes(font, new GColor("color.fg.consoletextpane"));
outputAttributes.addAttribute(CUSTOM_ATTRIBUTE_KEY, OUTPUT_ATTRIBUTE_VALUE);
errorAttributes = new GAttributes(font, new GColor("color.fg.error.consoletextpane"));
errorAttributes.addAttribute(CUSTOM_ATTRIBUTE_KEY, ERROR_ATTRIBUTE_VALUE);
}
private void doUpdate() {
@ -316,7 +304,7 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
}
AttributeSet getAttributes() {
return outputAttributeSet;
return outputAttributes;
}
}
@ -327,7 +315,7 @@ public class ConsoleTextPane extends JTextPane implements OptionsChangeListener
@Override
AttributeSet getAttributes() {
return errorAttributeSet;
return errorAttributes;
}
}

View File

@ -29,6 +29,7 @@ import docking.widgets.*;
import docking.widgets.label.*;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.Gui;
import generic.util.WindowUtilities;
import ghidra.framework.Application;
import ghidra.framework.ApplicationProperties;
@ -44,16 +45,19 @@ class InfoPanel extends JPanel {
private final static int MARGIN = 10;
private final static String SPLASH_FILENAME = "splash.txt";
private final static String CLOUD_REV_FILENAME = "images/cloudbarReversed.jpg";
private final static String GHIDRA_FILENAME = "images/GHIDRA_Splash.png";
private final static String CLOUD_FILENAME = "images/cloudbar.jpg";
private static final String FONT_ID = "font.splash.infopanel";
private String version;
private String marking;
private String distributionInfo;
private Color bgColor; // background color for all panels
private int imageWidth;
private final static String SPLASH_FILENAME = "splash.txt";
private final static String CLOUD_REV_FILENAME = "images/cloudbarReversed.jpg";
private final static String GHIDRA_FILENAME = "images/GHIDRA_Splash.png";
private final static String CLOUD_FILENAME = "images/cloudbar.jpg";
InfoPanel() {
getAboutInfo();
@ -170,9 +174,7 @@ class InfoPanel extends JPanel {
private Component buildVersionLabel() {
MultiLineLabel versionLabel = new MultiLineLabel(version, 0, 3, MultiLineLabel.CENTER);
Font font = versionLabel.getFont();
font = font.deriveFont(14f).deriveFont(Font.BOLD);
versionLabel.setFont(font);
Gui.registerFont(versionLabel, FONT_ID);
versionLabel.setForeground(new GColor("color.fg.infopanel.version"));
return versionLabel;
}

View File

@ -38,6 +38,7 @@ import docking.widgets.dialogs.MultiLineMessageDialog;
import docking.widgets.label.GLabel;
import docking.widgets.list.GListCellRenderer;
import generic.theme.GIcon;
import generic.theme.Gui;
import ghidra.app.services.ProgramManager;
import ghidra.app.util.*;
import ghidra.app.util.bin.ByteProvider;
@ -240,8 +241,7 @@ public class ImporterDialog extends DialogComponentProvider {
validateFormInput();
});
Font font = languageButton.getFont();
languageButton.setFont(font.deriveFont(Font.BOLD));
Gui.registerFont(languageButton, Font.BOLD);
JPanel panel = new JPanel(new BorderLayout());
panel.add(languageTextField, BorderLayout.CENTER);

View File

@ -26,6 +26,7 @@ import javax.swing.border.Border;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GDLabel;
import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.program.model.lang.*;
import ghidra.program.util.DefaultLanguageService;
import ghidra.util.table.*;
@ -67,7 +68,7 @@ public class NewLanguagePanel extends JPanel {
tableFilterPanel = new GhidraTableFilterPanel<>(table, tableModel);
descriptionLabel = new GDLabel(DEFAULT_DESCRIPTION_TEXT);
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.ITALIC));
Gui.registerFont(descriptionLabel, Font.ITALIC);
recommendedCheckbox = new GCheckBox("Show Only Recommended Language/Compiler Specs");
recommendedCheckbox.addItemListener(e -> {
@ -211,7 +212,6 @@ public class NewLanguagePanel extends JPanel {
LanguageCompilerSpecPair selectedLcsPair = getSelectedLcsPair();
if (selectedLcsPair == null) {
descriptionLabel.setText(DEFAULT_DESCRIPTION_TEXT);
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.ITALIC));
}
else {
try {
@ -220,7 +220,6 @@ public class NewLanguagePanel extends JPanel {
catch (LanguageNotFoundException e) {
descriptionLabel.setText("<LanguageNotFound>");
}
descriptionLabel.setFont(descriptionLabel.getFont().deriveFont(Font.PLAIN));
}
// notifyListenersOfValidityChanged();
if (!listeners.isEmpty()) {

View File

@ -109,7 +109,7 @@ public class ProgramDiffDetails {
// FUTURE : Add checks to make sure programs are comparable.
// Throw exception if not comparable.
initDetails();
initAttributes();
textAttrSet = new SimpleAttributeSet();
}
private static String getIndentString(int indentCount) {
@ -121,11 +121,6 @@ public class ProgramDiffDetails {
return buf.toString();
}
private void initAttributes() {
textAttrSet = new SimpleAttributeSet();
textAttrSet.addAttribute(StyleConstants.FontSize, 12);
}
/**
* Gets a string indicating the types of differences for the code units at the indicated
* address. The string contains information from each program where there are differences.

View File

@ -15,8 +15,7 @@
*/
package ghidra.util.table.field;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import java.awt.Font;
import ghidra.app.plugin.core.disassembler.AddressTable;
import ghidra.docking.settings.Settings;
@ -34,9 +33,10 @@ public class AddressTableDataTableColumn
private final GColumnRenderer<String> monospacedRenderer =
new AbstractGColumnRenderer<String>() {
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(getFixedWidthFont());
protected Font getDefaultFont() {
return fixedWidthFont;
}
@Override

View File

@ -16,10 +16,9 @@
package ghidra.util.table.field;
import java.awt.Component;
import java.awt.Font;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import docking.widgets.table.GTableCellRenderingData;
import ghidra.docking.settings.FormatSettingsDefinition;
@ -29,14 +28,15 @@ import ghidra.util.StringFormat;
import ghidra.util.table.column.AbstractGColumnRenderer;
public class MonospacedByteRenderer extends AbstractGColumnRenderer<Byte[]> {
@Override
protected void configureFont(JTable table, TableModel model, int column) {
setFont(getFixedWidthFont());
protected Font getDefaultFont() {
return fixedWidthFont;
}
private String formatBytes(Byte[] bytes, Settings settings) {
boolean bigEndian = (EndianSettingsDefinition.DEF
.getChoice(settings) != EndianSettingsDefinition.LITTLE);
boolean bigEndian =
(EndianSettingsDefinition.DEF.getChoice(settings) != EndianSettingsDefinition.LITTLE);
int startIx = 0;
int endIx = bytes.length;

View File

@ -34,7 +34,8 @@ import ghidra.app.util.viewer.listingpanel.AddressSetDisplayListener;
import ghidra.framework.options.*;
import ghidra.framework.plugintool.ComponentProviderAdapter;
import ghidra.framework.plugintool.PluginTool;
import ghidra.util.*;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.classfinder.ClassSearcher;
import ghidra.util.task.SwingUpdateManager;
@ -60,13 +61,13 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
//@formatter:off
static final String FG = "byteviewer.color.fg";
static final String CURSOR = "byteviewer.color.cursor";
static final GColor SEPARATOR_COLOR = new GColor("color.fg.byteviewer.separator");
static final GColor SEPARATOR_COLOR = new GColor("color.fg.byteviewer.separator");
static final GColor CHANGED_VALUE_COLOR = new GColor("color.fg.byteviewer.changed");
static final GColor CURSOR_ACTIVE_COLOR = new GColor("color.cursor.byteviewer.focused.active");
static final GColor CURSOR_NON_ACTIVE_COLOR = new GColor("color.cursor.byteviewer.focused.not.active");
static final GColor CURSOR_NOT_FOCUSED_COLOR = new GColor("color.cursor.byteviewer.unfocused");
static final GColor CURRENT_LINE_COLOR = GhidraOptions.DEFAULT_CURSOR_LINE_COLOR;
//@formatter:on
@ -162,7 +163,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
/**
* Notification that an option changed.
*
*
* @param options options object containing the property that changed
* @param optionName name of option that changed
* @param oldValue old value of the option
@ -173,7 +174,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
Object newValue) {
if (options.getName().equals("ByteViewer")) {
if (optionName.equals(OPTION_FONT)) {
setFont(SystemUtilities.adjustForFontSizeOverride((Font) newValue));
setFont((Font) newValue);
}
}
else if (options.getName().equals(CATEGORY_BROWSER_FIELDS)) {
@ -460,7 +461,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
/**
* Set the status info on the tool.
*
*
* @param message non-html text to display
*/
void setStatusMessage(String message) {
@ -505,7 +506,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
/**
* Add the {@link AddressSetDisplayListener} to the byte viewer panel
*
*
* @param listener the listener to add
*/
public void addDisplayListener(AddressSetDisplayListener listener) {
@ -514,7 +515,7 @@ public abstract class ByteViewerComponentProvider extends ComponentProviderAdapt
/**
* Remove the {@link AddressSetDisplayListener} from the byte viewer panel
*
*
* @param listener the listener to remove
*/
public void removeDisplayListener(AddressSetDisplayListener listener) {

View File

@ -39,8 +39,7 @@ import docking.widgets.fieldpanel.Layout;
import docking.widgets.fieldpanel.field.Field;
import docking.widgets.fieldpanel.support.BackgroundColorModel;
import docking.widgets.label.GDLabel;
import generic.theme.GColor;
import generic.theme.GIcon;
import generic.theme.*;
import generic.theme.GThemeDefaults.Colors;
import generic.theme.GThemeDefaults.Colors.Tooltips;
import ghidra.app.plugin.core.codebrowser.MarkerServiceBackgroundColorModel;
@ -245,8 +244,7 @@ public class ListingGraphComponentPanel extends AbstractGraphComponentPanel {
tooltipTitleLabel.setHorizontalAlignment(SwingConstants.LEADING);
tooltipTitleLabel.setBackground(Tooltips.BACKGROUND);
tooltipTitleLabel.setOpaque(true);
Font labelFont = tooltipTitleLabel.getFont();
tooltipTitleLabel.setFont(labelFont.deriveFont(Font.BOLD));
Gui.registerFont(tooltipTitleLabel, Font.BOLD);
JPanel headerPanel = new JPanel(new BorderLayout());
headerPanel.add(tooltipTitleLabel);

View File

@ -15,11 +15,12 @@
*/
package ghidra.feature.fid.debug;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.*;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import javax.swing.*;
import javax.swing.table.TableColumn;
@ -63,8 +64,13 @@ public class FidSearchResultFrame extends JFrame implements FidQueryCloseListene
}
private void buildFrame() {
GTableCellRenderer renderer = new GTableCellRenderer();
renderer.setFont(renderer.getFixedWidthFont());
GTableCellRenderer renderer = new GTableCellRenderer() {
@Override
protected Font getDefaultFont() {
return fixedWidthFont;
}
};
int columnCount = table.getColumnCount();
for (int ii = 0; ii < columnCount; ++ii) {
Class<?> columnClass = table.getColumnClass(ii);
@ -314,7 +320,7 @@ public class FidSearchResultFrame extends JFrame implements FidQueryCloseListene
}
@Override
public void fidQueryClosed(FidQueryService service) {
public void fidQueryClosed(FidQueryService fqs) {
dispose();
}
}

View File

@ -133,10 +133,18 @@ icon.task.progress.hourglass.11 = hourglass24_11.png
// Fonts
font.splash.header.default = Serif-BOLD-35
font.splash.status = Serif-BOLD-12
font.table.header.number = arial-BOLD-12
font.input.hint = monospaced-PLAIN-10
font.splash.header.default = serif-bold-35
font.splash.status = serif-bold-12
// default table renderer uses the JLabel font, which is mapped to system.font.control
font.table.base = [font]system.font.control
font.table.header.number = arial-bold-12
font.input.hint = monospaced-plain-10
font.task.monitor.label.message = sansserif-plain-10
font.wizard.border.title = sansserif-plain-10
@ -144,7 +152,6 @@ font.input.hint = monospaced-PLAIN-10
[Dark Defaults]
color.fg.filterfield = color.palette.darkslategray
color.bg.highlight = #703401 // orangish

View File

@ -59,9 +59,9 @@
<tocdef id="Root" sortgroup="a" text="Welcome to Help">
<tocdef id="Theming" text="Theming" sortgroup="t" target="help/topics/Theming/ThemingOverview.html">
<tocdef id="Overview" sortgroup="1" text="Overview" target="help/topics/Theming/ThemingOverview.html"/>
<tocdef id="Editing Themes" sortgroup="2" text="Editing Themes" target="help/topics/Theming/ThemingUserDocs.html"/>
<tocdef id="Architecture" sortgroup="3" text="Architecture" target="help/topics/Theming/ThemingInternals.html"/>
<tocdef id="Developer Documentation" sortgroup="4" text="Developer's Guide" target="help/topics/Theming/ThemingDeveloperDocs.html"/>
<tocdef id="Editing Themes" sortgroup="2" text="User's Guide" target="help/topics/Theming/ThemingUserDocs.html"/>
<tocdef id="Developer Documentation" sortgroup="3" text="Developer's Guide" target="help/topics/Theming/ThemingDeveloperDocs.html"/>
<tocdef id="Architecture" sortgroup="4" text="Architecture" target="help/topics/Theming/ThemingInternals.html"/>
</tocdef>
</tocdef>
</tocroot>

View File

@ -13,6 +13,14 @@
plugins, actions, scripts, etc., that use colors, fonts, or icons. By following these guidelines,
developers can easily make use of Ghidra's theming capabilities.</P>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P><IMG border="0" src="help/shared/tip.png" alt="Tip">Most classes referenced in this document
live in the <CODE>generic.theme</CODE> package.
</P>
</BLOCKQUOTE>
</BLOCKQUOTE>
<H2>Theme Resource Types</H2>
<P>When developing application code for Ghidra such as plugins, actions, etc., developers often
@ -122,8 +130,58 @@
<BLOCKQUOTE>
<CODE>Gui.registerFont(myLabel, "font.xyz");</CODE>
</BLOCKQUOTE>
<H3>Font Usage in Tables, Lists and Custom Painting</H3>
<P>
Ghidra makes great use of tables and to a lesser extent, lists. Both tables and lists
use renderers to paint cell values.
</P>
<UL>
<LI>
Java - By default, Java will use the font of the table/list as the font used during rendering.
</LI>
<LI>
Ghidra Tables - Ghidra does <U>not</U> use the table's font for rendering by default. Instead,
the renderer is initialized with the fonts used by <CODE>JLabel</CODE>, with additional
fonts for bold and monospaced text.
</LI>
<LI>
Ghidra Lists - Ghidra does not currently use custom rendering for lists. Thus, list cell
rendering will make use of the list's font, which is Java's default behavior.
</LI>
</UL>
<P>
We point out this difference between Java and Ghidra here so that developers understand
that changing fonts used for tables differs from Java. Specifically, calling
<BLOCKQUOTE>
<BLOCKQUOTE>
<PRE>
<CODE>
table.setFont(newFont);
</CODE>
</PRE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<P>
will not affect the font used when rendering the table. To programmatically change the
fonts used for tables, you can set the font directly on each cell renderer. As with a
any custom fonts used, be sure to define theme properties file and register then with the
Gui class as outlined above.
</P>
<P>
The fonts used for any painting operations, including table and list cell rendering, as well
as any code that overrides <CODE>paint</CODE> will work correctly within the theming
environment as long as the fonts are derived from the default Look and Feel values or are
obtained from the <CODE>Gui</CODE> class. In other words, as long as the
fonts used in custom painting are not hard-coded, any changes to the fonts via the theming
API will appear on the next call to paint the UI.
</P>
</BLOCKQUOTE>
</BLOCKQUOTE>

View File

@ -26,7 +26,9 @@ import docking.action.DockingActionIf;
import docking.action.KeyBindingData;
import docking.tool.ToolConstants;
import docking.widgets.label.GIconLabel;
import generic.theme.GAttributes;
import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.util.HelpLocation;
import resources.Icons;
@ -43,7 +45,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
private KeyEntryTextField keyEntryField;
private JTextPane collisionPane;
private StyledDocument doc;
private SimpleAttributeSet textAttrSet;
private SimpleAttributeSet textAttrs;
private Color bgColor;
public KeyEntryDialog(Tool tool, DockingActionIf action) {
@ -172,10 +175,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
}
private void setUpAttributes() {
textAttrSet = new SimpleAttributeSet();
textAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
textAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
textAttrSet.addAttribute(StyleConstants.Foreground, Messages.NORMAL);
Font font = Gui.getFont("font.standard");
textAttrs = new GAttributes(font, Messages.NORMAL);
}
private void updateCollisionPane(KeyStroke ks) {
@ -194,7 +195,7 @@ public class KeyEntryDialog extends DialogComponentProvider {
String ksName = KeyBindingUtils.parseKeyStroke(ks);
String text = keyBindings.getActionsForKeyStrokeText(ksName);
try {
doc.insertString(0, text, textAttrSet);
doc.insertString(0, text, textAttrs);
collisionPane.setCaretPosition(0);
}
catch (BadLocationException e) {

View File

@ -26,6 +26,7 @@ import javax.swing.*;
import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GDLabel;
import generic.theme.Gui;
import ghidra.util.Swing;
/**
@ -133,7 +134,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
JPanel panel = new JPanel(new GridLayout(2, 1));
GDLabel styleLabel = new GDLabel("Styles");
styleLabel.setFont(getFont().deriveFont(1));
Gui.registerFont(styleLabel, Font.BOLD);
styleLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(styleLabel);
@ -150,7 +151,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
JPanel panel = new JPanel(new GridLayout(2, 1));
GDLabel sizeLabel = new GDLabel("Sizes");
sizeLabel.setFont(getFont().deriveFont(1));
Gui.registerFont(sizeLabel, Font.BOLD);
sizeLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(sizeLabel);
@ -168,7 +169,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
JPanel panel = new JPanel(new GridLayout(2, 1));
GDLabel fontLabel = new GDLabel("Fonts");
fontLabel.setFont(getFont().deriveFont(1));
Gui.registerFont(fontLabel, Font.BOLD);
fontLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(fontLabel);

View File

@ -25,22 +25,32 @@ import javax.swing.plaf.basic.BasicHTML;
import javax.swing.table.DefaultTableCellRenderer;
import docking.widgets.label.GDHtmlLabel;
import generic.theme.GColor;
import generic.theme.GColorUIResource;
import generic.theme.*;
import generic.theme.GThemeDefaults.Colors.Palette;
import generic.theme.GThemeDefaults.Colors.Tables;
import ghidra.util.Msg;
import util.CollectionUtils;
import utilities.util.reflection.ReflectionUtilities;
/**
* A common base class for list and table renderer objects, unifying the Ghidra look and feel.
* <p>
* It allows (but default-disables) HTML content, automatically paints alternating row
* background colors, and highlights the drop target in a drag-n-drop operation.
*
* It allows (but default-disables) HTML content, automatically paints alternating row background
* colors, and highlights the drop target in a drag-n-drop operation.
* <p>
* The preferred method to change the font used by this renderer is {@link #setBaseFontId(String)}.
* If you would like this renderer to use a monospaced font, then, as an alternative to creating a
* font ID, you can instead override {@link #getDefaultFont()} to return this
* class's {@link #fixedWidthFont}. Also, the fixed width font of this class is based on the
* default font set when calling {@link #setBaseFontId(String)}, so it stays up-to-date with theme
* changes.
*/
public abstract class AbstractGCellRenderer extends GDHtmlLabel {
private static final Color BACKGROUND_COLOR = new GColor("color.bg.table.row");
private static final Color ALT_BACKGROUND_COLOR = new GColor("color.bg.table.row.alt");
private static final String BASE_FONT_ID = "font.table.base";
/** Allows the user to disable alternating row colors on JLists and JTables */
private static final String DISABLE_ALTERNATING_ROW_COLORS_PROPERTY =
"disable.alternating.row.colors";
@ -61,6 +71,9 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
private boolean instanceAlternateRowColors = true;
public AbstractGCellRenderer() {
setBaseFontId(BASE_FONT_ID);
noFocusBorder = BorderFactory.createEmptyBorder(0, 5, 0, 5);
Border innerBorder = BorderFactory.createEmptyBorder(0, 4, 0, 4);
Border outerBorder = BorderFactory.createLineBorder(Palette.YELLOW, 1);
@ -114,34 +127,48 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
return getBackgroundColorForRow(row);
}
/**
* Sets this renderer's theme font id. This will be used to load the base font and to create
* the derived fonts, such as bold and fixed width.
* @param fontId the font id
* @see Gui#registerFont(Component, String)
*/
public void setBaseFontId(String fontId) {
Font f = Gui.getFont(fontId);
defaultFont = f;
fixedWidthFont = new Font("monospaced", f.getStyle(), f.getSize());
boldFont = f.deriveFont(Font.BOLD);
Gui.registerFont(this, fontId);
}
@Override
public void setFont(Font f) {
super.setFont(f);
defaultFont = f;
fixedWidthFont = new Font("monospaced", defaultFont.getStyle(), defaultFont.getSize());
boldFont = f.deriveFont(Font.BOLD);
}
protected void superSetFont(Font font) {
super.setFont(font);
}
//
// Due to the nature of how setFont() is typically used (external client setup vs internal
// rendering), we created setBaseFontId() to allow external clients to set the base font in
// a way that is consistent with theming. Ignore any request to use one of our existing
// fonts, as some clients may do that from the getTableCellRendererComponent() method.
//
if (defaultFont != null &&
!CollectionUtils.isOneOf(f, defaultFont, fixedWidthFont, boldFont)) {
// sets the font of this renderer to be bold until the next time that
// getTableCellRenderer() is called, as it resets the font to the default font on each pass
protected void setBold() {
super.setFont(boldFont);
String caller =
ReflectionUtilities.getClassNameOlderThan(getClass().getName(), "generic.theme");
Msg.debug(this, "Calling setFont() on the renderer is discouraged. " +
"To change the font, call setBaseFontId(). Called from " + caller);
}
}
/**
* Sets the row where DnD would perform drop operation.
* @param dropRow the drop row
* Sets the font of this renderer to be bold until the next time that getTableCellRenderer() is
* called, as it resets the font to the default font on each pass.
* @see #getDefaultFont()
*/
public void setDropRow(int dropRow) {
this.dropRow = dropRow;
}
protected Border getNoFocusBorder() {
return noFocusBorder;
protected void setBold() {
super.setFont(boldFont);
}
protected Font getDefaultFont() {
@ -156,6 +183,18 @@ public abstract class AbstractGCellRenderer extends GDHtmlLabel {
return boldFont;
}
/**
* Sets the row where DnD would perform drop operation.
* @param dropRow the drop row
*/
public void setDropRow(int dropRow) {
this.dropRow = dropRow;
}
protected Border getNoFocusBorder() {
return noFocusBorder;
}
protected Color getDefaultBackgroundColor() {
return BACKGROUND_COLOR;
}

View File

@ -72,7 +72,8 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
new DropDownWindowVisibilityListener<>();
private GDHtmlLabel previewLabel;
protected GList<T> list = new GList<>();
protected DropDownList list = new DropDownList();
private WeakSet<DropDownSelectionChoiceListener<T>> choiceListeners =
WeakDataStructureFactory.createSingleThreadAccessWeakSet();
private Collection<CellEditorListener> cellEditorListeners = new HashSet<>();
@ -82,7 +83,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
private WindowComponentListener parentWindowListener = new WindowComponentListener();
private T selectedValue;
private int cellHeight;
private int matchingWindowHeight = MIN_HEIGHT;
private Point lastLocation;
protected final DropDownTextFieldDataModel<T> dataModel;
@ -278,15 +278,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
private void initDataList() {
Font font = list.getFont();
FontMetrics fontMetrics = list.getFontMetrics(font);
int padding = 2; // top and bottom border height
int lineHeight = fontMetrics.getHeight() + padding;
int iconAndPaddingHeight = 16 + padding;
cellHeight = Math.max(lineHeight, iconAndPaddingHeight);
list.setFixedCellHeight(cellHeight);
list.setFixedCellWidth(MIN_WIDTH - 20); // add some fudge for scrollbars
list.setCellRenderer(dataModel.getListRenderer());
list.addKeyListener(keyListener);
@ -654,7 +645,7 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
* signalling to use the clicked item. When pressing Enter, they may have been typing and
* ignoring the list, so we have to do some validation.
*/
@SuppressWarnings("unchecked") // for the cast to T
@SuppressWarnings("unchecked") // the item better be our type
private void setTextFromListOnEnterPress() {
Object selectedItem = list.getSelectedValue();
if (selectedItem == null) {
@ -747,6 +738,30 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
// Inner Classes
//=================================================================================================
protected class DropDownList extends GList<T> {
@Override
public void setFont(Font f) {
super.setFont(f);
updateCellDimensions(f);
}
private void updateCellDimensions(Font font) {
if (font == null || list == null) {
return; // UI is initializing
}
FontMetrics fontMetrics = list.getFontMetrics(font);
int padding = 2; // top and bottom border height
int lineHeight = fontMetrics.getHeight() + padding;
int iconAndPaddingHeight = 16 + padding;
int cellHeight = Math.max(lineHeight, iconAndPaddingHeight);
list.setFixedCellHeight(cellHeight);
list.setFixedCellWidth(MIN_WIDTH - 20); // add some fudge for scrollbars
}
}
private class HideWindowFocusListener extends FocusAdapter {
@Override
public void focusLost(FocusEvent event) {

View File

@ -15,7 +15,8 @@
*/
package docking.widgets.dialogs;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
@ -26,6 +27,7 @@ import docking.DockingUtils;
import docking.widgets.label.GDLabel;
import docking.widgets.label.GLabel;
import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.framework.OperatingSystem;
import ghidra.framework.Platform;
@ -34,6 +36,8 @@ public class MultiLineInputDialog extends DialogComponentProvider {
private static final KeyStroke SUBMIT_KEYSTROKE =
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, DockingUtils.CONTROL_KEY_MODIFIER_MASK);
private static final String FONT_ID = "font.input.hint";
private boolean isCanceled;
private JTextArea inputTextArea;
@ -84,10 +88,7 @@ public class MultiLineInputDialog extends DialogComponentProvider {
}
JLabel hintLabel = new GLabel("(" + metaKeyText + "-Enter to accept)");
hintLabel.setHorizontalAlignment(SwingConstants.CENTER);
Font font = hintLabel.getFont();
Font smallerFont = font.deriveFont(12F);
Font smallItalicFont = smallerFont.deriveFont(Font.ITALIC);
hintLabel.setFont(smallItalicFont);
Gui.registerFont(hintLabel, FONT_ID);
hintLabel.setForeground(Messages.HINT);
dataPanel.add(messageLabel, BorderLayout.NORTH);

View File

@ -49,39 +49,54 @@ class DirectoryList extends GList<File> implements GhidraFileChooserDirectoryMod
/**
* Create a new DirectoryList instance.
*
*
* @param chooser the {@link GhidraFileChooser} this instance is nested in
* @param model the {@link DirectoryListModel}
* @param font the parent component's font, used to calculate row height in the list once
*/
DirectoryList(GhidraFileChooser chooser, DirectoryListModel model, Font font) {
DirectoryList(GhidraFileChooser chooser, DirectoryListModel model) {
super(model);
this.chooser = chooser;
this.model = model;
build(font);
build();
}
private void build(Font font) {
@Override
public void setFont(Font font) {
super.setFont(font);
updateCellDimensions(font);
}
private void updateCellDimensions(Font font) {
if (font == null) {
return; // UI is being updated
}
FileListCellRenderer cellRenderer = (FileListCellRenderer) getCellRenderer();
if (cellRenderer == null) {
return; // initializing
}
// Enable the list to calculate the width of the cells on its own, but manually specify the
// height to ensure some padding between rows.
//
// Use 1/3 of the line height of the font to ensure visually consistent padding between
// rows. (Historically, 5px was used as the padding between the default 12pt (15px line
// height) rows, so 15px line height/5px padding equals .333 ratio.)
FontMetrics metrics = cellRenderer.getFontMetrics(font);
setFixedCellHeight(Math.max(metrics.getHeight(), DEFAULT_ICON_SIZE) +
Math.max(metrics.getHeight() / 3, MIN_HEIGHT_PADDING));
setFixedCellWidth(-1);
}
private void build() {
setLayoutOrientation(JList.VERTICAL_WRAP);
FileListCellRenderer cellRenderer = new FileListCellRenderer(chooser);
setCellRenderer(cellRenderer);
// Enable the list to calculate the width of the cells on its own, but manually
// specify the height to ensure some padding between rows.
// We need the parent component's Font instead of using our
// own #getFont() because we are not a child of the parent yet and
// the font may be set to something other than the default.
// Use 1/3 of the line height of the font to ensure visually consistent
// padding between rows. (historically, 5px was used as the padding
// between the default 12pt (15px lineht) rows, so 15px lineht/5px padding
// equals .333 ratio.)
FontMetrics metrics = cellRenderer.getFontMetrics(font);
setFixedCellHeight(
Math.max(metrics.getHeight(), DEFAULT_ICON_SIZE) +
Math.max(metrics.getHeight() / 3, MIN_HEIGHT_PADDING));
setFixedCellWidth(-1);
updateCellDimensions(getFont());
addMouseListener(new GMouseListenerAdapter() {
@Override

View File

@ -558,7 +558,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
private JScrollPane buildDirectoryList() {
directoryListModel = new DirectoryListModel();
directoryList = new DirectoryList(this, directoryListModel, rootPanel.getFont());
directoryList = new DirectoryList(this, directoryListModel);
directoryList.setName("LIST");
directoryList.setBackground(BACKGROUND_COLOR);

View File

@ -51,18 +51,17 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
private static final Color BG_DRAG = new GColor("color.bg.table.row.drag");
/*
* The map uses thread local variables to ensure that rendering and background model
* The map uses thread local variables to ensure that rendering and background model
* manipulation are thread safe.
*/
private static Map<Integer, ThreadLocal<DecimalFormat>> decimalFormatCache =
new HashMap<>();
private static Map<Integer, ThreadLocal<DecimalFormat>> decimalFormatCache = new HashMap<>();
static {
int n = FloatingPointPrecisionSettingsDefinition.MAX_PRECISION;
for (int i = 0; i <= n; i++) {
int precision = i;
ThreadLocal<DecimalFormat> localFormatter = ThreadLocal.withInitial(
() -> new DecimalFormat(createDecimalFormat(precision)));
ThreadLocal<DecimalFormat> localFormatter =
ThreadLocal.withInitial(() -> new DecimalFormat(createDecimalFormat(precision)));
decimalFormatCache.put(precision, localFormatter);
}
}
@ -84,7 +83,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
/**
* Constructs a new GTableCellRenderer using the specified font.
*
*
* @param f the font to use when rendering text in the table cells
*/
public GTableCellRenderer(Font f) {
@ -94,7 +93,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
/**
* Return the cell renderer text
*
*
* @param value Cell object value
* @return A string interpretation of value; generated by calling value.toString()
*/
@ -149,7 +148,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
* Provide basic cell rendering -- setting foreground and background colors, font, text,
* alignment, drop color, and border. Additional data that may be of use to the renderer is
* passed through the {@link docking.widgets.table.GTableCellRenderingData} object.
*
*
* @param data Context data used in the rendering of a data cell.
* @return The component used for drawing the table cell.
*/
@ -158,7 +157,6 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
Object value = data.getValue();
JTable table = data.getTable();
int row = data.getRowViewIndex();
int column = data.getColumnViewIndex();
boolean isSelected = data.isSelected();
boolean hasFocus = data.hasFocus();
Settings settings = data.getColumnSettings();
@ -173,7 +171,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
}
TableModel model = table.getModel();
configureFont(table, model, column);
setFont(getDefaultFont());
if (isSelected) {
setForeground(table.getSelectionForeground());
@ -199,8 +197,14 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
setForeground(table.getForeground());
}
protected void configureFont(JTable table, TableModel model, int column) {
setFont(defaultFont);
/**
* Override to change the font that will be used each time the renderer is initialized inside
* of {@link #getTableCellRendererComponent(GTableCellRenderingData)}
* @return the font
*/
@Override
protected Font getDefaultFont() {
return defaultFont;
}
protected int getRadix(Settings settings) {
@ -217,7 +221,7 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
/**
* Format a Number per the Settings parameters.
*
*
* @param value the number to format
* @param settings settings controlling the display of the Number parameter
* @return a formatted representation of the Number value

View File

@ -67,7 +67,7 @@ public class HintTextField extends JTextField {
/**
* Constructor
*
*
* @param hint the hint text
* @param required true, if the field should be marked as required
* @param verifier input verifier, or null if none needed
@ -78,7 +78,6 @@ public class HintTextField extends JTextField {
this.verifier = verifier;
addListeners();
setFont(getFont().deriveFont(Font.PLAIN));
validateField();
}
@ -143,7 +142,7 @@ public class HintTextField extends JTextField {
/**
* Sets whether the field is required or not. If so, it will be rendered
* differently to indicate that to the user.
*
*
* @param required true if required, false otherwise
*/
public void setRequired(boolean required) {
@ -161,7 +160,7 @@ public class HintTextField extends JTextField {
/**
* Returns true if the field contains valid input.
*
*
* @return true if valid, false otherwise
*/
public boolean isFieldValid() {
@ -179,7 +178,7 @@ public class HintTextField extends JTextField {
}
/**
* Checks the validity of the field and sets the appropriate
* Checks the validity of the field and sets the appropriate
* field attributes.
*/
private void validateField() {

View File

@ -28,6 +28,7 @@ import docking.ReusableDialogComponentProvider;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDLabel;
import generic.theme.GThemeDefaults.Colors.Messages;
import generic.theme.Gui;
import ghidra.util.*;
import help.Help;
import help.HelpService;
@ -47,6 +48,8 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
private final static String INIT_TITLE = "<< untitled >>";
private static final String FONT_ID = "font.wizard.border.title";
private PanelManager panelMgr;
private WizardPanel currWizPanel;
private JButton backButton;
@ -91,7 +94,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
}
/**
*
*
* @see docking.wizard.WizardPanelListener#validityChanged()
*/
@Override
@ -108,7 +111,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
return getStatusText();
}
/**
/**
* @see docking.wizard.WizardPanelListener#setStatusMessage(String)
*/
@Override
@ -220,8 +223,7 @@ public class WizardManager extends ReusableDialogComponentProvider implements Wi
titleLabel = (wizardIcon == null ? new GDLabel(INIT_TITLE)
: new GDLabel(INIT_TITLE, wizardIcon, SwingConstants.TRAILING));
EmptyBorderButton helpButton =
new EmptyBorderButton(Icons.INFO_ICON);
EmptyBorderButton helpButton = new EmptyBorderButton(Icons.INFO_ICON);
helpButton.setToolTipText("Help (F1)");
helpButton.addActionListener(
e -> DockingWindowManager.getHelpService().showHelp(rootPanel, false, rootPanel));
@ -438,7 +440,7 @@ if (!visitedMap.containsKey(currWizPanel)) {
return; // nothing to do
}
// this will have no effect if we are not showing, but the above call will handle that
// this will have no effect if we are not showing, but the above call will handle that
// case
defaultFocusComponent.requestFocusInWindow();
}
@ -465,14 +467,12 @@ if (!visitedMap.containsKey(currWizPanel)) {
if (scrollPane.getVerticalScrollBar().isShowing()) {
TitledBorder titledBorder =
new TitledBorder(BorderFactory.createEmptyBorder(), "(scroll for more options)");
Font font = titledBorder.getTitleFont();
if (font == null) {
// workaround for bug on Java 7
font = titleLabel.getFont();
}
titledBorder.setTitleFont(font.deriveFont(10f));
Gui.addThemeListener(e -> {
if (e.isFontChanged(FONT_ID)) {
titledBorder.setTitleFont(Gui.getFont(FONT_ID));
}
});
titledBorder.setTitleFont(Gui.getFont(FONT_ID));
titledBorder.setTitleColor(Messages.NORMAL);
titledBorder.setTitlePosition(TitledBorder.BOTTOM);
titledBorder.setTitleJustification(TitledBorder.TRAILING);

View File

@ -15,20 +15,14 @@
*/
package ghidra.docking.util;
import java.awt.Font;
import java.awt.Taskbar;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import javax.swing.*;
import javax.swing.LookAndFeel;
import javax.swing.plaf.ComponentUI;
import docking.framework.ApplicationInformationDisplayFactory;
import generic.theme.LafType;
import generic.theme.ThemeManager;
import ghidra.framework.preferences.Preferences;
import ghidra.util.SystemUtilities;
/**
* A utility class to manage LookAndFeel (LaF) settings.
@ -40,38 +34,12 @@ public class LookAndFeelUtils {
}
/**
* Loads settings from {@link Preferences}.
* This method does nothing. This is not handled by the theming system in the look and feel
* manager.
*/
@Deprecated(since = "11.1", forRemoval = true)
public static void installGlobalOverrides() {
//
// Users can change this via the SystemUtilities.FONT_SIZE_OVERRIDE_PROPERTY_NAME
// system property.
//
Integer fontOverride = SystemUtilities.getFontSizeOverrideValue();
if (fontOverride != null) {
setGlobalFontSizeOverride(fontOverride);
}
}
/** Allows you to globally set the font size (don't use this method!) */
private static void setGlobalFontSizeOverride(int fontSize) {
UIDefaults defaults = UIManager.getDefaults();
Set<Entry<Object, Object>> set = defaults.entrySet();
Iterator<Entry<Object, Object>> iterator = set.iterator();
while (iterator.hasNext()) {
Entry<Object, Object> entry = iterator.next();
Object key = entry.getKey();
if (key.toString().toLowerCase().indexOf("font") != -1) {
Font currentFont = defaults.getFont(key);
if (currentFont != null) {
Font newFont = currentFont.deriveFont((float) fontSize);
UIManager.put(key, newFont);
}
}
}
}
public static void performPlatformSpecificFixups() {

View File

@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils;
import docking.widgets.EmptyBorderButton;
import docking.widgets.OptionDialog;
import docking.widgets.label.GDHtmlLabel;
import generic.theme.Gui;
import ghidra.util.Swing;
import ghidra.util.datastruct.WeakDataStructureFactory;
import ghidra.util.datastruct.WeakSet;
@ -43,6 +44,8 @@ import resources.Icons;
*/
public class TaskMonitorComponent extends JPanel implements TaskMonitor {
private static final String MESSAGE_FONT_ID = "font.task.monitor.label.message";
private WeakSet<CancelledListener> listeners =
WeakDataStructureFactory.createCopyOnReadWeakSet();
@ -458,7 +461,7 @@ public class TaskMonitorComponent extends JPanel implements TaskMonitor {
// don't care
}
};
messageLabel.setFont(messageLabel.getFont().deriveFont((float) 10.0));
Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
Dimension d = messageLabel.getPreferredSize();
d.width = 180;
messageLabel.setPreferredSize(d);

View File

@ -35,7 +35,7 @@ public class ReflectionUtilitiesTest {
@Test
public void testGetClassNameAfter_NoClasses() {
String caller = ReflectionUtilities.getClassNameOlderThan();
String caller = ReflectionUtilities.getClassNameOlderThan(new String[0]);
assertThat(caller, is(equalTo(ReflectionUtilitiesTest.class.getName())));
}

View File

@ -23,12 +23,13 @@ color.visualgraph.view.satellite.edge.focused = color.palette.green
color.visualgraph.view.satellite.edge.selected = color.palette.lime
color.visualgraph.view.satellite.edge.hovered = color.palette.lime
color.graphdisplay.vertex.default = color.palette.green
color.graphdisplay.edge.default = color.palette.green
color.graphdisplay.vertex.selected = color.palette.blue
color.graphdisplay.edge.selected = color.palette.blue
font.visualgraph.view.label.message = SansSerif-PLAIN-22 // bigger for legibility in the graph
icon.graph.satellite = network-wireless-16.png
icon.graph.satellite.large = network-wireless.png
icon.graph.layout.default = color_swatch.png

View File

@ -27,6 +27,7 @@ import docking.widgets.label.GDLabel;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.ScalingControl;
import generic.theme.Gui;
import ghidra.graph.VisualGraph;
import ghidra.graph.viewer.event.mouse.VertexTooltipProvider;
import ghidra.graph.viewer.event.mouse.VisualGraphMousePlugin;
@ -38,18 +39,18 @@ import ghidra.graph.viewer.vertex.VertexFocusListener;
* A view object, where 'view' is used in the sense of the Model-View-Controller (MVC) pattern.
* This class will contain all UI widgets need to display and interact with a graph.
*
* <p><b><u>Implementation Note:</u></b>
* <p><b><u>Implementation Note:</u></b>
* <ol>
* <li>The graph of this component can be null, changing to non-null values over the
* lifetime of this view. This allows this view to be installed in a UI component, with the
* contents changing as needed.
* <li>The graph of this component can be null, changing to non-null values over the
* lifetime of this view. This allows this view to be installed in a UI component, with the
* contents changing as needed.
* </li>
* <li>
* When the graph is {@link #setGraph(VisualGraph) set}, the view portion of the class is
* recreated.
* </li>
* <li>
* At any given point in time there may not be a {@link #graphComponent}. This means that
* At any given point in time there may not be a {@link #graphComponent}. This means that
* this class must maintain settings state that it will apply when the component is created.
* This state is atypical and makes this class a bit harder to understand.
* </li>
@ -60,14 +61,16 @@ import ghidra.graph.viewer.vertex.VertexFocusListener;
* @param <G> the graph type
*/
//@formatter:off
public class VisualGraphView<V extends VisualVertex,
E extends VisualEdge<V>,
public class VisualGraphView<V extends VisualVertex,
E extends VisualEdge<V>,
G extends VisualGraph<V, E>> {
//@formatter:on
//@formatter:on
private static final float ZOOM_OUT_AMOUNT = .9f;
private static final float ZOOM_IN_AMOUNT = 1.1f;
private static final String MESSAGE_FONT_ID = "font.visualgraph.view.label.message";
private JPanel viewPanel;
private JPanel viewContentPanel;
@ -76,7 +79,7 @@ public class VisualGraphView<V extends VisualVertex,
* As graph data is updated, we set and clear the contents of this panel as needed. This
* allows the client to initialize the satellite window once, with updates controlled by
* this class.
*
*
* Note: this panel will be empty when docked and when the viewer is not yet built
*/
private JPanel undockedSatelliteContentPanel;
@ -99,7 +102,7 @@ public class VisualGraphView<V extends VisualVertex,
private Optional<GraphSatelliteListener> clientSatelliteListener = Optional.empty();
// this internal listener is the way we manage keeping our state in sync with the
// this internal listener is the way we manage keeping our state in sync with the
// graph component, as well as how we notify the client listener
private GraphSatelliteListener internalSatelliteListener = (docked, visible) -> {
@ -190,10 +193,10 @@ public class VisualGraphView<V extends VisualVertex,
}
/**
* Sets a listener that allows clients to be notified of vertex double-clicks. Normal
* Sets a listener that allows clients to be notified of vertex double-clicks. Normal
* mouse processing is handled by the {@link VisualGraphMousePlugin} class. This is a
* convenience method so that clients do not have to deal with the mouse plugin.
*
*
* @param l the listener
*/
public void setVertexClickListener(VertexClickListener<V, E> l) {
@ -290,9 +293,9 @@ public class VisualGraphView<V extends VisualVertex,
}
/**
* Returns the primary viewer of the graph (as opposed to the satellite viewer). The
* Returns the primary viewer of the graph (as opposed to the satellite viewer). The
* viewer returned is responsible for maintaining view information for a given graph.
*
*
* @return the primary viewer
*/
public GraphViewer<V, E> getPrimaryGraphViewer() {
@ -308,7 +311,7 @@ public class VisualGraphView<V extends VisualVertex,
/**
* Sets the perspective for this view
*
*
* @param newPerspective the new perspective
*/
public void setGraphPerspective(GraphPerspectiveInfo<V, E> newPerspective) {
@ -350,8 +353,7 @@ public class VisualGraphView<V extends VisualVertex,
viewContentPanel.removeAll();
viewContentPanel.paintImmediately(viewContentPanel.getBounds());
JLabel messageLabel = new GDLabel(errorMessage);
Font font = messageLabel.getFont();
messageLabel.setFont(font.deriveFont(22f)); // make a bit bigger for readability
Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
messageLabel.setHorizontalAlignment(SwingConstants.CENTER);
messageLabel.setFocusable(true); // we have to have something focusable in our provider
viewContentPanel.add(messageLabel, BorderLayout.NORTH);
@ -362,8 +364,8 @@ public class VisualGraphView<V extends VisualVertex,
/**
* Sets a message to be painted on the viewer. This is useful to show a text message to the
* user. Passing null will clear the message.
*
* @param message the status message
*
* @param message the status message
*/
public void setStatusMessage(String message) {
if (graphComponent != null) {
@ -377,10 +379,10 @@ public class VisualGraphView<V extends VisualVertex,
/**
* Returns whether the satellite intended to be visible. If this component is built, then
* a result of true means that the satellite is showing. If the component is not yet
* built, then a result of true means that the satellite will be made visible when the
* a result of true means that the satellite is showing. If the component is not yet
* built, then a result of true means that the satellite will be made visible when the
* component is built.
*
*
* @return true if visible
*/
public boolean isSatelliteVisible() {
@ -421,10 +423,10 @@ public class VisualGraphView<V extends VisualVertex,
/**
* Returns whether the satellite intended to be docked. If this component is built, then
* a result of true means that the satellite is docked. If the component is not yet
* built, then a result of true means that the satellite will be made docked when the
* a result of true means that the satellite is docked. If the component is not yet
* built, then a result of true means that the satellite will be made docked when the
* component is built.
*
*
* @return true if visible
*/
public boolean isSatelliteDocked() {
@ -517,8 +519,8 @@ public class VisualGraphView<V extends VisualVertex,
}
public Point translatePointFromVertexToViewSpace(V v, Point p) {
return GraphViewerUtils.translatePointFromVertexRelativeSpaceToViewSpace(
getPrimaryGraphViewer(), v, p);
return GraphViewerUtils
.translatePointFromVertexRelativeSpaceToViewSpace(getPrimaryGraphViewer(), v, p);
}
public Rectangle translateRectangleFromVertexToViewSpace(V v, Rectangle r) {
@ -577,7 +579,7 @@ public class VisualGraphView<V extends VisualVertex,
}
/**
* Effectively clears this display. This method is not called dispose, as that implies
* Effectively clears this display. This method is not called dispose, as that implies
* the end of an object's lifecycle. This object can be re-used after this method is
* called.
*/

View File

@ -34,7 +34,8 @@ color.fg.tree.selected = [color]system.color.fg.selected.view
// Fonts
font.standard = [font]system.font.control
font.monospaced = monospaced-PLAIN-12
font.standard.bold = font.standard[bold]
font.monospaced = monospaced-plain-12
//

View File

@ -298,6 +298,11 @@ public class ApplicationThemeManager extends ThemeManager {
lookAndFeelManager.registerFont(component, fontId);
}
@Override
public void registerFont(Component component, String fontId, int fontStyle) {
lookAndFeelManager.registerFont(component, fontId, fontStyle);
}
private void installFlatLookAndFeels() {
UIManager.installLookAndFeel(LafType.FLAT_LIGHT.getName(), FlatLightLaf.class.getName());
UIManager.installLookAndFeel(LafType.FLAT_DARK.getName(), FlatDarkLaf.class.getName());

View File

@ -68,7 +68,7 @@ public class FontModifier {
}
/**
* Sets the font stle modifier. This can be called multiple times to bold and italicize.
* Sets the font style modifier. This can be called multiple times to bold and italicize.
* @param newStyle the style to use for the font.
*/
public void addStyleModifier(int newStyle) {

View File

@ -0,0 +1,57 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package generic.theme;
import java.awt.Font;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import ghidra.util.HTMLUtilities;
/**
* A drop-in replacement for clients using {@link SimpleAttributeSet}s. This class will apply a
* default set of font attributes based on the given font and optional color.
*/
public class GAttributes extends SimpleAttributeSet {
public GAttributes(Font f) {
this(f, null);
}
public GAttributes(Font f, GColor c) {
addAttribute(StyleConstants.FontFamily, f.getFamily());
addAttribute(StyleConstants.FontSize, f.getSize());
addAttribute(StyleConstants.Bold, f.isBold());
addAttribute(StyleConstants.Italic, f.isItalic());
if (c != null) {
addAttribute(StyleConstants.Foreground, c);
}
}
/**
* A convenience method to style the given text in HTML using the font and color attributes
* defined in this attribute set. The text will be HTML escaped.
*
* @param content the content
* @return the styled content
* @see HTMLUtilities#styleText(SimpleAttributeSet, String)
*/
public String toStyledHtml(String content) {
return HTMLUtilities.styleText(this, content);
}
}

View File

@ -17,8 +17,9 @@ package generic.theme;
import java.awt.*;
import javax.swing.Icon;
import javax.swing.LookAndFeel;
import javax.swing.*;
import ghidra.util.Msg;
/**
* Provides a static set of methods for globally managing application themes and their values.
@ -36,6 +37,8 @@ import javax.swing.LookAndFeel;
*
*/
public class Gui {
private static final String FONT_SUFFIX = ".font";
// Start with an StubThemeManager so that simple tests can operate without having
// to initialize the theme system. Applications and integration tests will
// called ThemeManager.initialize() which will replace this with a fully initialized version.
@ -146,6 +149,9 @@ public class Gui {
/**
* Binds the component to the font identified by the given font id. Whenever the font for
* the font id changes, the component will updated with the new font.
* <p>
* Calling this method will trigger a call to {@link JComponent#setFont(Font)}.
*
* @param component the component to set/update the font
* @param fontId the id of the font to register with the given component
*/
@ -153,6 +159,37 @@ public class Gui {
themeManager.registerFont(component, fontId);
}
/**
* Registers the given component with the given font style. This method allows clients to not
* define a font id in the theme system, but instead to signal that they want the default font
* for the given component, modified with the given style. As the underlying font is changed,
* the client will be updated with that new font with the given style applied.
* <P>
* Most clients should <b>not</b> be using this method. Instead, use
* {@link #registerFont(JComponent, int)}.
* <P>
* The downside of using this method is that the end user cannot modify the style of the font.
* By using the standard theming mechanism for registering fonts, the end user has full control.
*
* @param component the component to set/update the font
* @param fontStyle the font style, one of Font.BOLD, Font.ITALIC,
*/
public static void registerFont(JComponent component, int fontStyle) {
if (fontStyle == Font.PLAIN) {
Msg.warn(Gui.class,
"Gui.registerFont(Component, int) may only be used for a non-plain font style. " +
"Use registerFont(Component, String) instead.");
return;
}
String id = component.getUIClassID(); // e.g., ButtonUI
String name = id.substring(0, id.length() - 2); // strip off "UI"
String fontId = FontValue.LAF_ID_PREFIX + name + FONT_SUFFIX; // e.g., laf.font.Button.font
themeManager.registerFont(component, fontId, fontStyle);
}
/**
* Returns true if the active theme is using dark defaults
* @return true if the active theme is using dark defaults

View File

@ -575,6 +575,21 @@ public abstract class ThemeManager {
// do nothing
}
/**
* Binds the component to the font identified by the given font id. Whenever the font for
* the font id changes, the component will updated with the new font.
* <p>
* This method is fairly niche and should not be called by most clients. Instead, call
* {@link #registerFont(Component, String)}.
*
* @param component the component to set/update the font
* @param fontId the id of the font to register with the given component
* @param fontStyle the font style
*/
public void registerFont(Component component, String fontId, int fontStyle) {
// do nothing
}
/**
* Returns true if the current theme use dark default values.
* @return true if the current theme use dark default values.

View File

@ -28,7 +28,8 @@ import ghidra.util.datastruct.WeakSet;
* for the font id, this class will update the component's font to the new value.
*/
public class ComponentFontRegistry {
private WeakSet<Component> components = WeakDataStructureFactory.createCopyOnReadWeakSet();
private WeakSet<StyledComponent> components =
WeakDataStructureFactory.createCopyOnReadWeakSet();
private String fontId;
/**
@ -45,8 +46,18 @@ public class ComponentFontRegistry {
* @param component the component to add
*/
public void addComponent(Component component) {
component.setFont(Gui.getFont(fontId));
components.add(component);
addComponent(component, Font.PLAIN);
}
/**
* Allows clients to update the default font being used for a component to use the given style.
* @param component the component
* @param fontStyle the font style (e.g., {@link Font#BOLD})
*/
public void addComponent(Component component, int fontStyle) {
StyledComponent sc = new StyledComponent(component, fontStyle);
sc.setFont(Gui.getFont(fontId));
components.add(sc);
}
/**
@ -54,10 +65,26 @@ public class ComponentFontRegistry {
*/
public void updateComponentFonts() {
Font font = Gui.getFont(fontId);
for (Component component : components) {
for (StyledComponent c : components) {
c.setFont(font);
}
}
private record StyledComponent(Component component, int fontStyle) {
void setFont(Font font) {
Font existingFont = component.getFont();
if (!Objects.equals(existingFont, font)) {
component.setFont(font);
Font styledFont = font;
int style = fontStyle();
if (style != Font.PLAIN) {
// Only style the font when it is not plain. Doing this means that clients cannot
// override a non-plain font to be plain. If clients need that behavior, they must
// create their own custom font id and register their component with Gui.
styledFont = font.deriveFont(style);
}
if (!Objects.equals(existingFont, styledFont)) {
component.setFont(styledFont);
}
}
}

View File

@ -30,6 +30,7 @@ import generic.theme.*;
import generic.util.action.*;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
import utilities.util.reflection.ReflectionUtilities;
/**
* Manages installing and updating a {@link LookAndFeel}
@ -38,6 +39,7 @@ public abstract class LookAndFeelManager {
private LafType laf;
private Map<String, ComponentFontRegistry> fontRegistryMap = new HashMap<>();
private Map<Component, String> componentToIdMap = new WeakHashMap<>();
protected ApplicationThemeManager themeManager;
protected Map<String, String> normalizedIdToLafIdMap;
@ -158,7 +160,7 @@ public abstract class LookAndFeelManager {
* Called when one or more fonts have changed.
* <p>
* This will update the Java {@link UIManager} and trigger a reload of the UIs.
*
*
* @param changedFontIds the set of Java Font ids that are affected by this change; these are
* the normalized ids
*/
@ -202,12 +204,49 @@ public abstract class LookAndFeelManager {
* @param fontId the id of the font to register with the given component
*/
public void registerFont(Component component, String fontId) {
checkForAlreadyRegistered(component, fontId);
componentToIdMap.put(component, fontId);
ComponentFontRegistry register =
fontRegistryMap.computeIfAbsent(fontId, id -> new ComponentFontRegistry(id));
register.addComponent(component);
}
/**
* Binds the component to the font identified by the given font id. Whenever the font for
* the font id changes, the component will be updated with the new font.
* <p>
* This method is fairly niche and should not be called by most clients. Instead, call
* {@link #registerFont(Component, String)}.
*
* @param component the component to set/update the font
* @param fontId the id of the font to register with the given component
* @param fontStyle the font style
*/
public void registerFont(Component component, String fontId, int fontStyle) {
checkForAlreadyRegistered(component, fontId);
componentToIdMap.put(component, fontId);
ComponentFontRegistry register =
fontRegistryMap.computeIfAbsent(fontId, id -> new ComponentFontRegistry(id));
register.addComponent(component, fontStyle);
}
private void checkForAlreadyRegistered(Component component, String newFontId) {
String existingFontId = componentToIdMap.get(component);
if (existingFontId != null) {
Msg.warn(this, """
Component has a Font ID registered more than once. \
Previously registered ID: '%s'. Newly registered ID: '%s'.
""".formatted(existingFontId, newFontId),
ReflectionUtilities.createJavaFilteredThrowable());
}
}
private Font toUiResource(Font font) {
if (!(font instanceof UIResource)) {
return new FontUIResource(font);
@ -292,8 +331,7 @@ public abstract class LookAndFeelManager {
return false;
}
protected void setKeyBinding(String existingKsText, String newKsText,
String[] prefixValues) {
protected void setKeyBinding(String existingKsText, String newKsText, String[] prefixValues) {
KeyStroke existingKs = KeyStroke.getKeyStroke(existingKsText);
KeyStroke newKs = KeyStroke.getKeyStroke(newKsText);

View File

@ -153,8 +153,8 @@ public class UiDefaultsMapper {
* the user changeable values for affecting the Java LookAndFeel colors, fonts, and icons.
* <p>
* The keys in the returned map have been normalized and all start with 'laf.'
*
*
*
*
* @return a map of changeable values that affect java LookAndFeel values
*/
public GThemeValueMap getNormalizedJavaDefaults() {
@ -184,7 +184,7 @@ public class UiDefaultsMapper {
* Returns a mapping of normalized LaF Ids so that when fonts and icons get changed using the
* normalized ids that are presented to the user, we know which LaF ids need to be updated in
* the UiDefaults so that the LookAndFeel will pick up and use the changes.
*
*
* @return a mapping of normalized LaF ids to original LaF ids.
*/
public Map<String, String> getNormalizedIdToLafIdMap() {
@ -281,7 +281,7 @@ public class UiDefaultsMapper {
/**
* This allows clients to hard-code a chosen color for a group
*
*
* @param group the system color id to assign the given color
* @param color the color to be assigned to the system color id
*/
@ -291,7 +291,7 @@ public class UiDefaultsMapper {
/**
* This allows clients to hard-code a chosen font for a group
*
*
* @param group the system font id to assign the given font
* @param font the font to be assigned to the system font id
*/
@ -693,7 +693,7 @@ public class UiDefaultsMapper {
* Groups allow us to use the same group id for many components that by default have the same
* value (Color or Font). This grouper allows us to specify the precedence to use when
* searching for the best group.
*
*
* @param <T> The theme value type (Color or Font)
*/
private abstract class ValueGrouper<T> {

View File

@ -22,9 +22,10 @@ import java.util.regex.Pattern;
import javax.swing.JLabel;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import javax.swing.text.*;
import generic.text.TextLayoutGraphics;
import generic.theme.GAttributes;
import ghidra.util.html.HtmlLineSplitter;
import utilities.util.reflection.ReflectionUtilities;
@ -343,6 +344,67 @@ public class HTMLUtilities {
return buffy.toString();
}
/**
* Escapes and wraps the given text in {@code SPAN} tag with font attributes specified in the
* given attributes. Specifically, these attributes are used:
*
* <UL>
* <LI>{@link StyleConstants#Foreground} - {@link Color} object</LI>
* <LI>{@link StyleConstants#FontFamily} - font name</LI>
* <LI>{@link StyleConstants#FontSize} - size in pixels</LI>
* <LI>{@link StyleConstants#Italic} - true if italic</LI>
* <LI>{@link StyleConstants#Bold} - true if bold</LI>
* </UL>
* <P>
* See {@link GAttributes} for a convenient way to create the correct attributes for a font and
* color.
*
* @param attributes the attributes
* @param text the content to style
* @return the styled content
* @see GAttributes
*/
public static String styleText(SimpleAttributeSet attributes, String text) {
// StyleConstants.Foreground color: #00FF00;
// StyleConstants.FontFamily font-family: "Tahoma";
// StyleConstants.FontSize font-size: 40px;
// StyleConstants.Italic font-style: italic;
// StyleConstants.Bold font-weight: bold;
String family = attributes.getAttribute(StyleConstants.FontFamily).toString();
String size = attributes.getAttribute(StyleConstants.FontSize).toString();
String style = "plain";
String weight = "plain";
Boolean isItalic = (Boolean) attributes.getAttribute(StyleConstants.Italic);
Boolean isBold = (Boolean) attributes.getAttribute(StyleConstants.Bold);
if (Boolean.TRUE.equals(isItalic)) {
style = "italic";
}
if (Boolean.TRUE.equals(isBold)) {
weight = "bold";
}
// color is optional and defaults to the containing component's color
String color = "";
Object colorAttribute = attributes.getAttribute(StyleConstants.Foreground);
if (colorAttribute instanceof Color fgColor) {
String hexColor = HTMLUtilities.toHexString(fgColor);
color = "color: % s;".formatted(hexColor);
}
String escaped = escapeHTML(text);
//@formatter:off
return """
<SPAN STYLE=\"%s font-family: '%s'; font-size: %spx; font-style: %s; font-weight: %s;\">\
%s\
</SPAN>
""".formatted(color, family, size, style, weight, escaped);
//@formatter:on
}
/**
* Returns the given text wrapped in {@link #LINK_PLACEHOLDER_OPEN} and close tags.
* If <code>foo</code> is passed for the HTML text, with a content value of <code>123456</code>, then
@ -510,7 +572,7 @@ public class HTMLUtilities {
/**
* See {@link #friendlyEncodeHTML(String)}
*
*
* @param text string to be encoded
* @param skipLeadingWhitespace true signals to ignore any leading whitespace characters.
* This is useful when line wrapping to force wrapped lines to the left
@ -593,8 +655,7 @@ public class HTMLUtilities {
* Calling this twice will result in text being double-escaped, which will not display correctly.
* <p>
* See also <code>StringEscapeUtils#escapeHtml3(String)</code> if you need quote-safe html encoding.
* <p>
*
*
* @param text plain-text that might have some characters that should NOT be interpreted as HTML
* @param makeSpacesNonBreaking true to convert spaces into {@value #HTML_SPACE}
* @return string with any html characters replaced with equivalents
@ -634,7 +695,7 @@ public class HTMLUtilities {
/**
* Escapes any HTML special characters in the specified text.
*
*
* @param text plain-text that might have some characters that should NOT be interpreted as HTML
* @return string with any html characters replaced with equivalents
* @see #escapeHTML(String, boolean)
@ -647,7 +708,7 @@ public class HTMLUtilities {
* Tests a unicode code point (i.e., 32 bit character) to see if it needs to be escaped before
* being added to a HTML document because it is non-printable or a non-standard control
* character
*
*
* @param codePoint character to test
* @return boolean true if character should be escaped
*/

View File

@ -84,8 +84,12 @@ icon.plugin.manager.default = plasma.png
font.help.about = font.monospaced
font.keybindings.status = sansserif-plain-11
font.task.viewer = sansserif-bold-36
font.user.agreement = sansserif-plain-16
font.task.progress.label.message = sansserif-plain-12
font.user.agreement = sansserif-italic-22
font.panel.details = font.standard
font.panel.details.monospaced = font.monospaced[bold]
font.pluginpanel.name = sansserif-plain-18

View File

@ -15,7 +15,8 @@
*/
package ghidra.framework.main;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Insets;
import java.io.InputStream;
import javax.swing.*;
@ -57,11 +58,10 @@ public class UserAgreementDialog extends DialogComponentProvider {
}
private JComponent buildWorkPanel() {
Font font = Gui.getFont(FONT_ID);
JPanel panel = new JPanel(new BorderLayout());
JLabel label = new GDLabel("Ghidra User Agreement", SwingConstants.CENTER);
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
label.setFont(font.deriveFont(Font.ITALIC, 22f));
Gui.registerFont(label, FONT_ID);
panel.add(label, BorderLayout.NORTH);
panel.setBorder(BorderFactory.createEmptyBorder(10, 40, 40, 40));
JEditorPane editorPane = new JEditorPane();

View File

@ -23,6 +23,7 @@ import java.util.List;
import javax.swing.*;
import docking.widgets.label.GDLabel;
import generic.theme.Gui;
import ghidra.framework.client.RepositoryAdapter;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.remote.User;
@ -33,9 +34,9 @@ import ghidra.framework.remote.User;
*/
public class ViewProjectAccessPanel extends ProjectAccessPanel {
/**
/**
* Construct a new panel.
*
*
* @param repository handle to the repository adapter
* @param tool the plugin tool
* @throws IOException if there's an error processing repository information
@ -47,13 +48,13 @@ public class ViewProjectAccessPanel extends ProjectAccessPanel {
/**
* Constructs a new panel.
*
*
* @param knownUsers names of the users that are known to the remote server
* @param currentUser the current user
* @param allUsers all users known to the repository
* @param repositoryName the name of the repository
* @param anonymousServerAccessAllowed true if the server allows anonymous access
* @param anonymousAccessEnabled true if the repository allows anonymous access
* @param anonymousAccessEnabled true if the repository allows anonymous access
* (ignored if anonymousServerAccessAllowed is false)
* @param tool the current tool
*/
@ -66,7 +67,7 @@ public class ViewProjectAccessPanel extends ProjectAccessPanel {
}
/**
* Creates the main gui panel, containing the known users, button, and user access
* Creates the main gui panel, containing the known users, button, and user access
* panels.
*/
@Override
@ -82,9 +83,7 @@ public class ViewProjectAccessPanel extends ProjectAccessPanel {
if (anonymousServerAccessAllowed && origAnonymousAccessEnabled) {
JLabel anonymousAccessLabel = new GDLabel("Anonymous Read-Only Access Enabled");
anonymousAccessLabel.setBorder(BorderFactory.createEmptyBorder(5, 2, 0, 0));
Font f = anonymousAccessLabel.getFont().deriveFont(Font.ITALIC);
anonymousAccessLabel.setFont(f);
Gui.registerFont(anonymousAccessLabel, Font.ITALIC);
mainPanel.add(anonymousAccessLabel, BorderLayout.SOUTH);
}

View File

@ -17,79 +17,57 @@ package ghidra.framework.plugintool.dialog;
import static ghidra.util.HTMLUtilities.*;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import docking.widgets.label.GDHtmlLabel;
import generic.theme.GColor;
import ghidra.util.HTMLUtilities;
import generic.theme.*;
/**
* Abstract class that defines a panel for displaying name/value pairs with html-formatting.
*/
public abstract class AbstractDetailsPanel extends JPanel {
protected static final String FONT_DEFAULT = "font.panel.details";
protected static final String FONT_MONOSPACED = "font.panel.details.monospaced";
private static final int MIN_WIDTH = 700;
protected static final int LEFT_COLUMN_WIDTH = 150;
protected static final int RIGHT_MARGIN = 30;
// Font attributes for the title of each row.
protected static SimpleAttributeSet titleAttrSet;
protected static GAttributes titleAttrs;
protected JLabel textLabel;
protected JScrollPane sp;
private ThemeListener themeListener = e -> {
if (e.isFontChanged(FONT_DEFAULT) || e.isFontChanged(FONT_MONOSPACED)) {
updateFieldAttributes();
}
};
protected AbstractDetailsPanel() {
createFieldAttributes();
Gui.addThemeListener(themeListener);
}
private void updateFieldAttributes() {
createFieldAttributes();
refresh();
repaint();
}
/**
* Sets attributes for the different pieces of information being displayed in this
* Sets attributes for the different pieces of information being displayed in this
* panel.
*/
protected abstract void createFieldAttributes();
/**
* Returns a new {@link SimpleAttributeSet} with all attributes set by the caller.
*
* @param fontFamily the font to use
* @param fontSize the font size
* @param bold if true, render text bold
* @param color the foreground text color
* @return a new attribute set
*/
protected SimpleAttributeSet createAttributeSet(String fontFamily, int fontSize, boolean bold,
Color color) {
SimpleAttributeSet attrSet = new SimpleAttributeSet();
attrSet.addAttribute(StyleConstants.FontFamily, fontFamily);
attrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(fontSize));
attrSet.addAttribute(StyleConstants.Bold, bold);
attrSet.addAttribute(StyleConstants.Foreground, color);
return attrSet;
}
/**
* Returns a new {@link SimpleAttributeSet} with the following default attributes set:
* <ul>
* <li>FontFamily: "Tahoma"</li>
* <li>FontSize: 11</li>
* <li>Bold: True</li>
* </ul>
*
* @param color the foreground text color
* @return a new attribute set
*/
protected SimpleAttributeSet createAttributeSet(Color color) {
SimpleAttributeSet attrSet = new SimpleAttributeSet();
attrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
attrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
attrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
attrSet.addAttribute(StyleConstants.Foreground, color);
return attrSet;
}
protected abstract void refresh();
/**
* Clears the text in the details pane.
@ -127,27 +105,26 @@ public abstract class AbstractDetailsPanel extends JPanel {
/**
* Inserts an html-formatted string into the given buffer. This is meant to be used
* for inserting the name of each row in the description text.
*
*
* @param buffer the string buffer to add to
* @param rowName the name of the row to add
*/
protected void insertRowTitle(StringBuilder buffer, String rowName) {
buffer.append("<TR>");
buffer.append("<TD VALIGN=\"TOP\">");
insertHTMLLine(buffer, rowName + ":", titleAttrSet);
insertHTMLLine(buffer, rowName + ":", titleAttrs);
buffer.append("</TD>");
}
/**
* Inserts an html-formatted string into the given buffer. This is meant to be used
* for inserting the value of each row in the description text.
*
*
* @param buffer the string buffer to add to
* @param value the text to add
* @param attributes the structure containing formatting information
* @param attributes the structure containing formatting information
*/
protected void insertRowValue(StringBuilder buffer, String value,
SimpleAttributeSet attributes) {
protected void insertRowValue(StringBuilder buffer, String value, GAttributes attributes) {
buffer.append("<TD VALIGN=\"TOP\" WIDTH=\"80%\">");
insertHTMLLine(buffer, value, attributes);
buffer.append("</TD>");
@ -161,33 +138,13 @@ public abstract class AbstractDetailsPanel extends JPanel {
* @param string the string to add
* @param attributes the formatting instructions
*/
protected void insertHTMLString(StringBuilder buffer, String string,
SimpleAttributeSet attributes) {
protected void insertHTMLString(StringBuilder buffer, String string, GAttributes attributes) {
if (string == null) {
return;
}
buffer.append("<FONT COLOR=\"");
Color foregroundColor = (Color) attributes.getAttribute(StyleConstants.Foreground);
buffer.append(HTMLUtilities.toHexString(foregroundColor));
buffer.append("\" FACE=\"");
buffer.append(attributes.getAttribute(StyleConstants.FontFamily).toString());
buffer.append("\">");
Boolean isBold = (Boolean) attributes.getAttribute(StyleConstants.Bold);
isBold = (isBold == null) ? Boolean.FALSE : isBold;
String text = HTMLUtilities.escapeHTML(string);
if (isBold) {
text = HTMLUtilities.bold(text);
}
buffer.append(text);
buffer.append("</FONT>");
buffer.append(attributes.toStyledHtml(string));
}
/**
@ -196,8 +153,7 @@ public abstract class AbstractDetailsPanel extends JPanel {
* @param string the string to insert
* @param attributes the attributes to apply
*/
protected void insertHTMLLine(StringBuilder buffer, String string,
SimpleAttributeSet attributes) {
protected void insertHTMLLine(StringBuilder buffer, String string, GAttributes attributes) {
if (string == null) {
return;
}

View File

@ -15,17 +15,16 @@
*/
package ghidra.framework.plugintool.dialog;
import java.awt.Font;
import java.awt.Point;
import java.util.*;
import javax.swing.KeyStroke;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import docking.action.DockingActionIf;
import docking.action.MenuData;
import docking.actions.KeyBindingUtils;
import generic.theme.GColor;
import generic.theme.*;
import ghidra.framework.plugintool.PluginConfigurationModel;
import ghidra.framework.plugintool.PluginTool;
import ghidra.framework.plugintool.util.PluginDescription;
@ -37,29 +36,52 @@ import ghidra.util.HTMLUtilities;
*/
class PluginDetailsPanel extends AbstractDetailsPanel {
private SimpleAttributeSet nameAttrSet;
private SimpleAttributeSet depNameAttrSet;
private SimpleAttributeSet descrAttrSet;
private SimpleAttributeSet categoriesAttrSet;
private SimpleAttributeSet classAttrSet;
private SimpleAttributeSet locAttrSet;
private SimpleAttributeSet developerAttrSet;
private SimpleAttributeSet dependencyAttrSet;
private SimpleAttributeSet noValueAttrSet;
private static final GColor NO_VALUE_COLOR = new GColor("color.fg.pluginpanel.details.novalue");
private static final GColor DEPENDENCY_COLOR =
new GColor("color.fg.pluginpanel.details.dependency");
private static final GColor LOCATION_COLOR = new GColor("color.fg.pluginpanel.details.loc");
private static final GColor DEVELOPER_COLOR =
new GColor("color.fg.pluginpanel.details.developer");
private static final GColor CLASS_COLOR = new GColor("color.fg.pluginpanel.details.class");
private static final GColor CATEGORIES_COLOR =
new GColor("color.fg.pluginpanel.details.category");
private static final GColor TITLE_COLOR = new GColor("color.fg.pluginpanel.details.title");
private static final GColor DESCRIPTION_COLOR =
new GColor("color.fg.pluginpanel.details.description");
private static final GColor NAME_NO_DEPENDENTS_COLOR =
new GColor("color.fg.pluginpanel.details.name.no.dependents");
private static final GColor NAME_DEPENDENTS_COLOR =
new GColor("color.fg.pluginpanel.details.name.has.dependents");
private GAttributes nameAttrs;
private GAttributes dependenciesNameAttrs;
private GAttributes descriptionAttrs;
private GAttributes categoriesAttrs;
private GAttributes classAttrs;
private GAttributes locationAttrs;
private GAttributes developerAttrs;
private GAttributes dependencyAttrs;
private GAttributes noValueAttrs;
private final PluginConfigurationModel model;
private PluginTool tool;
private PluginDescription currentDescriptor;
PluginDetailsPanel(PluginTool tool, PluginConfigurationModel model) {
super();
this.tool = tool;
this.model = model;
createFieldAttributes();
createMainPanel();
}
@Override
protected void refresh() {
setPluginDescription(currentDescriptor);
}
void setPluginDescription(PluginDescription descriptor) {
this.currentDescriptor = descriptor;
textLabel.setText("");
if (descriptor == null) {
return;
@ -74,43 +96,43 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
insertRowTitle(buffer, "Name");
insertRowValue(buffer, descriptor.getName(),
!dependencies.isEmpty() ? depNameAttrSet : nameAttrSet);
!dependencies.isEmpty() ? dependenciesNameAttrs : nameAttrs);
insertRowTitle(buffer, "Description");
insertRowValue(buffer, descriptor.getDescription(), descrAttrSet);
insertRowValue(buffer, descriptor.getDescription(), descriptionAttrs);
insertRowTitle(buffer, "Status");
insertRowValue(buffer, descriptor.getStatus().getDescription(),
(descriptor.getStatus() == PluginStatus.RELEASED) ? titleAttrSet : developerAttrSet);
(descriptor.getStatus() == PluginStatus.RELEASED) ? titleAttrs : developerAttrs);
insertRowTitle(buffer, "Package");
insertRowValue(buffer, descriptor.getPluginPackage().getName(), categoriesAttrSet);
insertRowValue(buffer, descriptor.getPluginPackage().getName(), categoriesAttrs);
insertRowTitle(buffer, "Category");
insertRowValue(buffer, descriptor.getCategory(), categoriesAttrSet);
insertRowValue(buffer, descriptor.getCategory(), categoriesAttrs);
insertRowTitle(buffer, "Plugin Class");
insertRowValue(buffer, descriptor.getPluginClass().getName(), classAttrSet);
insertRowValue(buffer, descriptor.getPluginClass().getName(), classAttrs);
insertRowTitle(buffer, "Class Location");
insertRowValue(buffer, descriptor.getSourceLocation(), locAttrSet);
insertRowValue(buffer, descriptor.getSourceLocation(), locationAttrs);
insertRowTitle(buffer, "Used By");
buffer.append("<TD VALIGN=\"TOP\">");
if (dependencies.isEmpty()) {
insertHTMLLine(buffer, "None", noValueAttrSet);
insertHTMLLine(buffer, "None", noValueAttrs);
}
else {
for (int i = 0; i < dependencies.size(); i++) {
insertHTMLString(buffer, dependencies.get(i).getPluginClass().getName(),
dependencyAttrSet);
dependencyAttrs);
if (i < dependencies.size() - 1) {
buffer.append(HTMLUtilities.BR);
}
}
insertHTMLLine(buffer, "", titleAttrSet); // add a newline
insertHTMLLine(buffer, "", titleAttrs); // add a newline
}
buffer.append("</TD>");
buffer.append("</TR>");
@ -121,16 +143,16 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
List<Class<?>> servicesRequired = descriptor.getServicesRequired();
if (servicesRequired.isEmpty()) {
insertHTMLLine(buffer, "None", noValueAttrSet);
insertHTMLLine(buffer, "None", noValueAttrs);
}
else {
for (int i = 0; i < servicesRequired.size(); i++) {
insertHTMLString(buffer, servicesRequired.get(i).getName(), dependencyAttrSet);
insertHTMLString(buffer, servicesRequired.get(i).getName(), dependencyAttrs);
if (i < servicesRequired.size() - 1) {
buffer.append(HTMLUtilities.BR);
}
}
insertHTMLLine(buffer, "", titleAttrSet); // add a newline
insertHTMLLine(buffer, "", titleAttrs); // add a newline
}
buffer.append("</TD>");
buffer.append("</TR>");
@ -158,7 +180,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
buffer.append("<TR>");
buffer.append("<TD VALIGN=\"TOP\">");
insertHTMLLine(buffer, "Loaded Actions:", titleAttrSet);
insertHTMLLine(buffer, "Loaded Actions:", titleAttrs);
buffer.append("</TD>");
Set<DockingActionIf> actions = Collections.emptySet();
@ -169,7 +191,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
if (actions.isEmpty()) {
buffer.append("<TD VALIGN=\"TOP\">");
insertHTMLLine(buffer, "No actions for plugin", noValueAttrSet);
insertHTMLLine(buffer, "No actions for plugin", noValueAttrs);
buffer.append("</TD>");
buffer.append("</TR>");
return;
@ -182,7 +204,7 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
for (DockingActionIf dockableAction : actions) {
buffer.append("<TR><TD WIDTH=\"200\">");
insertHTMLString(buffer, dockableAction.getName(), locAttrSet);
insertHTMLString(buffer, dockableAction.getName(), locationAttrs);
buffer.append("</TD>");
buffer.append("<TD WIDTH=\"300\">");
@ -190,17 +212,17 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
String[] menuPath = menuBarData == null ? null : menuBarData.getMenuPath();
String menuPathString = createStringForMenuPath(menuPath);
if (menuPathString != null) {
insertHTMLString(buffer, menuPathString, locAttrSet);
insertHTMLString(buffer, menuPathString, locationAttrs);
}
else {
MenuData popupMenuData = dockableAction.getPopupMenuData();
String[] popupPath = popupMenuData == null ? null : popupMenuData.getMenuPath();
if (popupPath != null) {
insertHTMLString(buffer, "(in a context popup menu)", noValueAttrSet);
insertHTMLString(buffer, "(in a context popup menu)", noValueAttrs);
}
else {
insertHTMLString(buffer, "Not in a menu", noValueAttrSet);
insertHTMLString(buffer, "Not in a menu", noValueAttrs);
}
}
@ -210,10 +232,10 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
KeyStroke keyBinding = dockableAction.getKeyBinding();
if (keyBinding != null) {
String keyStrokeString = KeyBindingUtils.parseKeyStroke(keyBinding);
insertHTMLString(buffer, keyStrokeString, locAttrSet);
insertHTMLString(buffer, keyStrokeString, locationAttrs);
}
else {
insertHTMLString(buffer, "No keybinding", noValueAttrSet);
insertHTMLString(buffer, "No keybinding", noValueAttrs);
}
buffer.append("</TD></TR>");
@ -242,74 +264,19 @@ class PluginDetailsPanel extends AbstractDetailsPanel {
@Override
protected void createFieldAttributes() {
titleAttrSet = new SimpleAttributeSet();
titleAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
titleAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
titleAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
titleAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.title"));
Font font = Gui.getFont(FONT_DEFAULT);
titleAttrs = new GAttributes(font, TITLE_COLOR);
nameAttrs = new GAttributes(font, NAME_NO_DEPENDENTS_COLOR);
dependenciesNameAttrs = new GAttributes(font, NAME_DEPENDENTS_COLOR);
descriptionAttrs = new GAttributes(font, DESCRIPTION_COLOR);
categoriesAttrs = new GAttributes(font, CATEGORIES_COLOR);
locationAttrs = new GAttributes(font, LOCATION_COLOR);
developerAttrs = new GAttributes(font, DEVELOPER_COLOR);
nameAttrSet = new SimpleAttributeSet();
nameAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
nameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
nameAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
nameAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.name.no.dependents"));
Font fontMonospaced = Gui.getFont(FONT_MONOSPACED);
classAttrs = new GAttributes(fontMonospaced, CLASS_COLOR);
dependencyAttrs = new GAttributes(fontMonospaced, DEPENDENCY_COLOR);
depNameAttrSet = new SimpleAttributeSet();
depNameAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
depNameAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
depNameAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
depNameAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.name.has.dependents"));
descrAttrSet = new SimpleAttributeSet();
descrAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
descrAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
descrAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
descrAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.description"));
categoriesAttrSet = new SimpleAttributeSet();
categoriesAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
categoriesAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
categoriesAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
categoriesAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.category"));
classAttrSet = new SimpleAttributeSet();
classAttrSet.addAttribute(StyleConstants.FontFamily, "monospaced");
classAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
classAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
classAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.class"));
locAttrSet = new SimpleAttributeSet();
locAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
locAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
locAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
locAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.loc"));
developerAttrSet = new SimpleAttributeSet();
developerAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
developerAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
developerAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
developerAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.developer"));
dependencyAttrSet = new SimpleAttributeSet();
dependencyAttrSet.addAttribute(StyleConstants.FontFamily, "monospaced");
dependencyAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
dependencyAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
dependencyAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.dependency"));
noValueAttrSet = new SimpleAttributeSet();
noValueAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
noValueAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
noValueAttrSet.addAttribute(StyleConstants.Italic, Boolean.TRUE);
noValueAttrSet.addAttribute(StyleConstants.Foreground,
new GColor("color.fg.pluginpanel.details.novalue"));
noValueAttrs = new GAttributes(font, NO_VALUE_COLOR);
}
}

View File

@ -15,11 +15,14 @@
*/
package ghidra.framework.plugintool.dialog;
import static ghidra.framework.plugintool.dialog.PluginInstallerTableModel.*;
import java.awt.*;
import java.util.List;
import javax.swing.*;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import docking.DialogComponentProvider;
import docking.widgets.table.*;
@ -149,30 +152,23 @@ public class PluginInstallerDialog extends DialogComponentProvider {
tableFilterPanel = new GTableFilterPanel<>(table, tableModel);
JScrollPane sp = new JScrollPane(table);
pluginTablePanel.add(sp, BorderLayout.CENTER);
pluginTablePanel.add(tableFilterPanel, BorderLayout.SOUTH);
// Restrict the size of the first couple columns - the default size is
// way too large. This is annoying but our table column classes don't have a nice
// way to restrict column width.
TableColumn inst_col =
table.getColumnModel().getColumn(PluginInstallerTableModel.INSTALLED_COL);
inst_col.setMaxWidth(30);
TableColumn status_col =
table.getColumnModel().getColumn(PluginInstallerTableModel.STATUS_COL);
status_col.setMaxWidth(24);
TableColumnModel columnModel = table.getColumnModel();
TableColumn installedColumn = columnModel.getColumn(INSTALLED_COL);
installedColumn.setMaxWidth(30);
TableColumn statusColumn = columnModel.getColumn(STATUS_COL);
statusColumn.setMaxWidth(24);
tableModel.setTableSortState(
TableSortState.createDefaultSortState(PluginInstallerTableModel.NAME_COL));
tableModel.setTableSortState(TableSortState.createDefaultSortState(NAME_COL));
tableModel.refresh();
table.getColumnModel()
.getColumn(PluginInstallerTableModel.NAME_COL)
.setCellRenderer(new NameCellRenderer());
table.getColumnModel()
.getColumn(PluginInstallerTableModel.STATUS_COL)
.setCellRenderer(new StatusCellRenderer());
columnModel.getColumn(NAME_COL).setCellRenderer(new NameCellRenderer());
columnModel.getColumn(STATUS_COL).setCellRenderer(new StatusCellRenderer());
HelpService help = Help.getHelpService();
help.registerHelp(table, new HelpLocation(GenericHelpTopics.TOOL, "PluginDialog"));
@ -214,10 +210,10 @@ public class PluginInstallerDialog extends DialogComponentProvider {
renderer.setIcon((value instanceof Icon) ? (Icon) value : null);
String toolTipText = "";
if (value == PluginInstallerTableModel.EXPERIMENTAL_ICON) {
if (value == EXPERIMENTAL_ICON) {
toolTipText = "This plugin is usable, but not fully tested or documented";
}
else if (value == PluginInstallerTableModel.DEV_ICON) {
else if (value == DEV_ICON) {
toolTipText =
"This plugin is under development and not intended for general use.\n" +
"It could cause Ghidra to become unstable!";

View File

@ -176,7 +176,7 @@ public class PluginManagerComponent extends JPanel implements Scrollable {
labelPanel.setBackground(BG);
GLabel nameLabel = new GLabel(pluginPackage.getName());
nameLabel.setFont(nameLabel.getFont().deriveFont(18f));
Gui.registerFont(nameLabel, "font.pluginpanel.name");
nameLabel.setForeground(new GColor("color.fg.pluginpanel.name"));
labelPanel.add(nameLabel);

View File

@ -15,13 +15,11 @@
*/
package ghidra.framework.project.extensions;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import javax.swing.text.SimpleAttributeSet;
import docking.widgets.table.threaded.ThreadedTableModelListener;
import generic.theme.GColor;
import generic.theme.*;
import ghidra.framework.plugintool.dialog.AbstractDetailsPanel;
import ghidra.util.extensions.ExtensionDetails;
@ -33,27 +31,28 @@ import ghidra.util.extensions.ExtensionDetails;
*/
class ExtensionDetailsPanel extends AbstractDetailsPanel {
private static final Color FG_COLOR_AUTHOR =
private static final GColor FG_COLOR_AUTHOR =
new GColor("color.fg.extensionpanel.details.author");
private static final Color FG_COLOR_DATE = new GColor("color.fg.extensionpanel.details.date");
private static final Color FG_COLOR_DESCRIPTION =
private static final GColor FG_COLOR_DATE = new GColor("color.fg.extensionpanel.details.date");
private static final GColor FG_COLOR_DESCRIPTION =
new GColor("color.fg.extensionpanel.details.description");
private static final Color FG_COLOR_NAME = new GColor("color.fg.extensionpanel.details.name");
private static final Color FG_COLOR_PATH = new GColor("color.fg.extensionpanel.path");
private static final Color FG_COLOR_TITLE = new GColor("color.fg.extensionpanel.details.title");
private static final Color FG_COLOR_VERSION =
private static final GColor FG_COLOR_NAME = new GColor("color.fg.extensionpanel.details.name");
private static final GColor FG_COLOR_PATH = new GColor("color.fg.extensionpanel.path");
private static final GColor FG_COLOR_TITLE =
new GColor("color.fg.extensionpanel.details.title");
private static final GColor FG_COLOR_VERSION =
new GColor("color.fg.extensionpanel.details.version");
/** Attribute sets define the visual characteristics for each field */
private SimpleAttributeSet nameAttrSet;
private SimpleAttributeSet descrAttrSet;
private SimpleAttributeSet authorAttrSet;
private SimpleAttributeSet createdOnAttrSet;
private SimpleAttributeSet versionAttrSet;
private SimpleAttributeSet pathAttrSet;
private GAttributes nameAttrSet;
private GAttributes descrAttrSet;
private GAttributes authorAttrSet;
private GAttributes createdOnAttrSet;
private GAttributes versionAttrSet;
private GAttributes pathAttrSet;
private ExtensionDetails currentDetails;
ExtensionDetailsPanel(ExtensionTablePanel tablePanel) {
super();
createFieldAttributes();
createMainPanel();
@ -82,13 +81,19 @@ class ExtensionDetailsPanel extends AbstractDetailsPanel {
});
}
@Override
protected void refresh() {
setDescription(currentDetails);
}
/**
* Updates this panel with the given extension.
*
*
* @param details the extension to display
*/
public void setDescription(ExtensionDetails details) {
this.currentDetails = details;
clear();
if (details == null) {
return;
@ -134,12 +139,14 @@ class ExtensionDetailsPanel extends AbstractDetailsPanel {
@Override
protected void createFieldAttributes() {
titleAttrSet = createAttributeSet(FG_COLOR_TITLE);
nameAttrSet = createAttributeSet(FG_COLOR_NAME);
descrAttrSet = createAttributeSet(FG_COLOR_DESCRIPTION);
authorAttrSet = createAttributeSet(FG_COLOR_AUTHOR);
createdOnAttrSet = createAttributeSet(FG_COLOR_DATE);
versionAttrSet = createAttributeSet(FG_COLOR_VERSION);
pathAttrSet = createAttributeSet(FG_COLOR_PATH);
Font font = Gui.getFont(FONT_DEFAULT);
titleAttrs = new GAttributes(font, FG_COLOR_TITLE);
nameAttrSet = new GAttributes(font, FG_COLOR_NAME);
descrAttrSet = new GAttributes(font, FG_COLOR_DESCRIPTION);
authorAttrSet = new GAttributes(font, FG_COLOR_AUTHOR);
createdOnAttrSet = new GAttributes(font, FG_COLOR_DATE);
versionAttrSet = new GAttributes(font, FG_COLOR_VERSION);
pathAttrSet = new GAttributes(font, FG_COLOR_PATH);
}
}

View File

@ -25,6 +25,7 @@ import docking.util.AnimatedIcon;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.label.GIconLabel;
import generic.theme.Gui;
import ghidra.util.Msg;
import ghidra.util.SystemUtilities;
import ghidra.util.layout.VerticalLayout;
@ -36,6 +37,8 @@ import resources.ResourceManager;
public class GProgressBar extends JPanel {
private static final NumberFormat PERCENT_FORMAT = NumberFormat.getPercentInstance();
private static final String MESSAGE_FONT_ID = "font.task.progress.label.message";
private volatile long lastProgress = -1;
private volatile long progress;
private volatile long scaleFactor = 1;
@ -47,7 +50,6 @@ public class GProgressBar extends JPanel {
private volatile boolean paintProgressValue = true;
private boolean showingIcon = true;
private final float fontSize;
private JProgressBar progressBar;
private JLabel messageLabel;
private JLabel imageLabel;
@ -61,10 +63,9 @@ public class GProgressBar extends JPanel {
private CancelledListener cancelledListener;
public GProgressBar(CancelledListener cancelledListener, boolean includeTextField,
boolean includeCancelButton, boolean includeAnimatedIcon, float fontSize) {
boolean includeCancelButton, boolean includeAnimatedIcon) {
super(new BorderLayout(5, 1));
this.cancelledListener = cancelledListener;
this.fontSize = fontSize;
buildProgressPanel(includeTextField, includeCancelButton, includeAnimatedIcon);
@ -217,7 +218,7 @@ public class GProgressBar extends JPanel {
// don't care
}
};
messageLabel.setFont(messageLabel.getFont().deriveFont(fontSize));
Gui.registerFont(messageLabel, MESSAGE_FONT_ID);
Dimension d = messageLabel.getPreferredSize();
d.width = 180;
messageLabel.setPreferredSize(d);

View File

@ -31,7 +31,6 @@ public class ScheduledTaskPanel extends JPanel {
private ScheduledElementLayout layout;
public ScheduledTaskPanel(String labelText, int indention) {
super();
this.indention = indention;
setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
@ -44,7 +43,7 @@ public class ScheduledTaskPanel extends JPanel {
}
void addProgressBar() {
progressBar = new GProgressBar(null, true, true, false, 12);
progressBar = new GProgressBar(null, true, true, false);
progressBar.setBackgroundColor(Colors.BACKGROUND);
add(progressBar);
layout.clearPreferredSize();
@ -71,7 +70,7 @@ public class ScheduledTaskPanel extends JPanel {
//==================================================================================================
// Inner Classes
//==================================================================================================
//==================================================================================================
// This layout handles the scrolling based on the scrollOffset as set by the setHiddenViewAmount()
// It also optionally shows the scrollbar for the task or group.

View File

@ -15,8 +15,7 @@
*/
package ghidra.framework.task;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
@ -46,11 +45,11 @@ public class GProgressBarTest extends AbstractDockingTest {
cancelled = true;
}
};
progressBar = new GProgressBar(cancelledListener, true, true, true, 10.0f);
progressBar = new GProgressBar(cancelledListener, true, true, true);
}
@Test
public void testBasicProgress() {
public void testBasicProgress() {
progressBar.initialize(100);
assertEquals(0, progressBar.getProgress());
assertEquals(100, progressBar.getMax());
@ -62,7 +61,7 @@ public class GProgressBarTest extends AbstractDockingTest {
}
@Test
public void testLongValues() {
public void testLongValues() {
progressBar.initialize(0x400000000L);
progressBar.setProgress(10);
assertEquals(10, progressBar.getProgress());
@ -73,7 +72,7 @@ public class GProgressBarTest extends AbstractDockingTest {
}
@Test
public void testMessage() {
public void testMessage() {
progressBar.initialize(100);
progressBar.setMessage("Hey");
assertEquals("Hey", progressBar.getMessage());
@ -91,7 +90,7 @@ public class GProgressBarTest extends AbstractDockingTest {
}
@Test
public void testCancel() {
public void testCancel() {
progressBar.initialize(100);
progressBar.setProgress(50);
assertTrue(!cancelled);

View File

@ -100,7 +100,7 @@ public class SystemUtilities {
}
/**
* Clean the specified user name to eliminate any spaces or leading domain name
* Clean the specified user name to eliminate any spaces or leading domain name
* which may be present (e.g., "MyDomain\John Doe" becomes "JohnDoe").
* @param name user name string to be cleaned-up
* @return the clean user name
@ -127,8 +127,8 @@ public class SystemUtilities {
}
/**
* Get the user that is running the application. This name may be modified to
* eliminate any spaces or leading domain name which may be present in Java's
* Get the user that is running the application. This name may be modified to
* eliminate any spaces or leading domain name which may be present in Java's
* {@code user.name} system property (see {@link #getCleanUserName(String)}).
* @return the user name
*/
@ -173,20 +173,15 @@ public class SystemUtilities {
}
/**
* Checks to see if the font size override setting is enabled and adjusts
* the given font as necessary to match the override setting. If the setting
* is not enabled, then <code>font</code> is returned.
* No longer supported. Use the theming system for fonts
*
* @param font
* The current font to adjust, if necessary.
* @return a font object with the proper size.
* @param font the font
* @return the same font passed in
* @deprecated Use the theming system for fonts
*/
@Deprecated(since = "11.1", forRemoval = true)
public static Font adjustForFontSizeOverride(Font font) {
if (FONT_SIZE_OVERRIDE_VALUE == null) {
return font;
}
return font.deriveFont((float) FONT_SIZE_OVERRIDE_VALUE.intValue());
return font;
}
/**
@ -350,10 +345,10 @@ public class SystemUtilities {
}
/**
* Returns a file that contains the given class. If the class is in a jar file, then
* the jar file will be returned. If the file is in a .class file, then the directory
* Returns a file that contains the given class. If the class is in a jar file, then
* the jar file will be returned. If the file is in a .class file, then the directory
* containing the package root will be returned (i.e. the "bin" directory).
*
*
* @param classObject the class for which to get the location
* @return the containing location
*/

View File

@ -42,12 +42,12 @@ public class ReflectionUtilities {
}
/**
* Locates the field of the name <code>fieldName</code> on the given
* class. If the given class does not contain the field, then this
* method will recursively call up <code>containingClass</code>'s
* implementation tree looking for a parent implementation of the
* Locates the field of the name <code>fieldName</code> on the given
* class. If the given class does not contain the field, then this
* method will recursively call up <code>containingClass</code>'s
* implementation tree looking for a parent implementation of the
* requested field.
*
*
* @param fieldName The name of the field to locate.
* @param containingClass The class that contains the desired field.
* @return The Field object that matches the given name, or null if not
@ -73,12 +73,12 @@ public class ReflectionUtilities {
}
/**
* Locates the field of the name <code>fieldName</code> on the given
* class. If the given class does not contain the field, then this
* method will recursively call up <code>containingClass</code>'s
* implementation tree looking for a parent implementation of the
* Locates the field of the name <code>fieldName</code> on the given
* class. If the given class does not contain the field, then this
* method will recursively call up <code>containingClass</code>'s
* implementation tree looking for a parent implementation of the
* requested field.
*
*
* @param fieldName The name of the field to locate.
* @param containingClass The class that contains the desired field.
* @return The Field object that matches the given name, or null if not
@ -104,12 +104,12 @@ public class ReflectionUtilities {
}
/**
* Locates the method of the name <code>methodName</code> on the given
* class. If the given class does not contain the method, then this
* method will recursively call up <code>containingClass</code>'s
* implementation tree looking for a parent implementation of the
* Locates the method of the name <code>methodName</code> on the given
* class. If the given class does not contain the method, then this
* method will recursively call up <code>containingClass</code>'s
* implementation tree looking for a parent implementation of the
* requested method.
*
*
* @param methodName The name of the method to locate.
* @param containingClass The class that contains the desired method.
* @param parameterTypes The parameters of the desired method (may be null).
@ -158,7 +158,7 @@ public class ReflectionUtilities {
/**
* Get the first field specification contained within containingClass which has the type classType.
* This method is only really useful if it is known that only a single field of
* This method is only really useful if it is known that only a single field of
* classType exists within the containingClass hierarchy.
* @param classType the class
* @param containingClass the class that contains a field of the given type
@ -184,40 +184,52 @@ public class ReflectionUtilities {
/**
* Returns the class name of the entry in the stack that comes before all references to the
* given classes. This is useful for figuring out at runtime who is calling a particular
* method.
* method.
* <p>
* This method can take multiple classes, but you really only need to pass the oldest
* This method can take multiple classes, but you really only need to pass the oldest
* class of disinterest.
*
*
* @param classes the classes to ignore
* @return the desired class name
*/
public static String getClassNameOlderThan(Class<?>... classes) {
Throwable t = createThrowableWithStackOlderThan(classes);
StackTraceElement[] stackTrace = t.getStackTrace();
return stackTrace[0].getClassName();
}
/**
* Creates a throwable whose stack trace is based upon the current call stack, with any
* information coming before, and including, the given classes removed.
* <p>
* This method can take multiple classes, but you really only need to pass the oldest
* class of disinterest.
*
* @param classes the classes to ignore
* @return the new throwable
* Returns the class name of the entry in the stack that comes before all references to the
* given patterns. This is useful for figuring out at runtime who is calling a particular
* method.
*
* @param patterns the patterns to ignore
* @return the desired class name
*/
public static Throwable createThrowableWithStackOlderThan(Class<?>... classes) {
public static String getClassNameOlderThan(String... patterns) {
Throwable t = createThrowableWithStackOlderThan(patterns);
StackTraceElement[] stackTrace = t.getStackTrace();
return stackTrace[0].getClassName();
}
List<String> toFind =
Arrays.stream(classes).map(c -> c.getName()).collect(Collectors.toList());
/**
* Creates a throwable whose stack trace is based upon the current call stack, with any
* information coming before, and including, the given patterns removed.
*
* @param patterns the strings to ignore (e.g., class or package names)
* @return the new throwable
* @see #createThrowableWithStackOlderThan(Class...)
*/
public static Throwable createThrowableWithStackOlderThan(String... patterns) {
return createThrowableWithStackOlderThan(List.of(patterns));
}
if (toFind.isEmpty()) {
// Always ignore our class. We get this for free if the client passes in any
// classes.
toFind.add(0, ReflectionUtilities.class.getName());
private static Throwable createThrowableWithStackOlderThan(List<String> patterns) {
if (patterns.isEmpty()) {
// always ignore our class. We get this for free if the client passes in any classes
patterns = new ArrayList<>();
patterns.add(0, ReflectionUtilities.class.getName());
}
Throwable t = new Throwable();
@ -227,7 +239,7 @@ public class ReflectionUtilities {
StackTraceElement element = trace[i];
String className = element.getClassName();
int nameIndex = toFind.indexOf(className);
int nameIndex = patterns.indexOf(className);
if (nameIndex != -1) {
lastIgnoreIndex = i;
}
@ -242,13 +254,13 @@ public class ReflectionUtilities {
if (lastIgnoreIndex == -1) {
Msg.error(ReflectionUtilities.class,
"Change call to ReflectionUtils. Did not find the " +
"following classes in the call stack: " + Arrays.toString(classes));
"following patterns in the call stack: " + patterns);
}
if (lastIgnoreIndex == trace.length - 1) {
Msg.error(ReflectionUtilities.class,
"Change call to ReflectionUtils. Call stack only contains the classes to ignore: " +
Arrays.toString(classes));
"Change call to ReflectionUtils. Call stack contains only ignored patterns: " +
patterns);
}
int startIndex = lastIgnoreIndex + 1;
@ -258,11 +270,27 @@ public class ReflectionUtilities {
}
/**
* Finds the first occurrence of the given pattern and then stops filtering when it finds
* Creates a throwable whose stack trace is based upon the current call stack, with any
* information coming before, and including, the given classes removed.
* <p>
* This method can take multiple classes, but you really only need to pass the oldest
* class of disinterest.
*
* @param classes the classes to ignore
* @return the new throwable
*/
public static Throwable createThrowableWithStackOlderThan(Class<?>... classes) {
List<String> patterns =
Arrays.stream(classes).map(c -> c.getName()).collect(Collectors.toList());
return createThrowableWithStackOlderThan(patterns);
}
/**
* Finds the first occurrence of the given pattern and then stops filtering when it finds
* something that is not that pattern
*
*
* @param trace the trace to update
* @param pattern the non-regex patterns used to perform a
* @param pattern the non-regex patterns used to perform a
* {@link String#contains(CharSequence)} on each {@link StackTraceElement} line
* @return the updated trace
*/
@ -296,12 +324,12 @@ public class ReflectionUtilities {
}
/**
* Uses the given <code>patterns</code> to remove elements from the given stack trace.
* Uses the given <code>patterns</code> to remove elements from the given stack trace.
* The current implementation will simply perform a <code>toString()</code> on each element and
* then check to see if that string contains any of the <code>patterns</code>.
*
*
* @param trace the trace to filter
* @param patterns the non-regex patterns used to perform a
* @param patterns the non-regex patterns used to perform a
* {@link String#contains(CharSequence)} on each {@link StackTraceElement}
* line.
* @return the filtered trace
@ -325,15 +353,15 @@ public class ReflectionUtilities {
/**
* A convenience method to create a throwable, filtering any lines that contain the given
* non-regex patterns. This can be useful for emitting diagnostic stack traces.
*
* @param patterns the non-regex patterns used to perform a
*
* @param patterns the non-regex patterns used to perform a
* {@link String#contains(CharSequence)} on each {@link StackTraceElement}
* line.
* @return the new throwable
*/
public static Throwable createFilteredThrowable(String... patterns) {
Throwable t = createThrowableWithStackOlderThan();
Throwable t = createThrowableWithStackOlderThan(new ArrayList<>());
StackTraceElement[] trace = t.getStackTrace();
StackTraceElement[] filtered = filterStackTrace(trace, patterns);
t.setStackTrace(filtered);
@ -341,40 +369,39 @@ public class ReflectionUtilities {
}
/**
* A convenience method to create a throwable, filtering boiler-plate Java-related
* lines (e.g., AWT, Swing, Security, etc).
* A convenience method to create a throwable, filtering boiler-plate Java-related
* lines (e.g., AWT, Swing, Security, etc).
* This can be useful for emitting diagnostic stack traces with reduced noise.
*
*
* @return the new throwable
*/
public static Throwable createJavaFilteredThrowable() {
Throwable t = createThrowableWithStackOlderThan();
Throwable t = createThrowableWithStackOlderThan(List.of());
return filterJavaThrowable(t);
}
/**
* A convenience method to create a throwable, filtering boiler-plate Java-related
* lines (e.g., AWT, Swing, Security, etc).
* This can be useful for emitting diagnostic stack traces with reduced noise.
*
* A convenience method to create a throwable, filtering boiler-plate Java-related
* lines (e.g., AWT, Swing, Security, etc).
* This can be useful for emitting diagnostic stack traces with reduced noise.
*
* <p>This method differs from {@link #createJavaFilteredThrowable()} in that this method
* returns a String, which is useful when printing log messages without having to directly
* print the stack trace.
*
*
* @return the new throwable
*/
public static String createJavaFilteredThrowableString() {
Throwable t = createThrowableWithStackOlderThan();
Throwable t = createThrowableWithStackOlderThan(List.of());
Throwable filtered = filterJavaThrowable(t);
return stackTraceToString(filtered);
}
/**
* A convenience method to take a throwable, filter boiler-plate Java-related
* lines (e.g., AWT, Swing, Security, etc).
* A convenience method to take a throwable, filter boiler-plate Java-related
* lines (e.g., AWT, Swing, Security, etc).
* This can be useful for emitting diagnostic stack traces with reduced noise.
*
*
* @param t the throwable to filter
* @return the throwable
*/
@ -418,15 +445,15 @@ public class ReflectionUtilities {
}
/**
* Returns an ordered set of interfaces and classes that are shared amongst the items in
* Returns an ordered set of interfaces and classes that are shared amongst the items in
* the list.
* <p>
* The order of the items is as they are first encountered, favoring interfaces before
* The order of the items is as they are first encountered, favoring interfaces before
* classes. Further, interface hierarchies are examined before concrete parent extensions.
* <p>
* If the given items have no parents in common, then the result will be a list with
* only <code>Object.class</code>.
*
*
* @param list the items to examine
* @return the set of items
*/
@ -461,15 +488,15 @@ public class ReflectionUtilities {
}
/**
* Returns an ordered set of parent interfaces and classes that are shared
* Returns an ordered set of parent interfaces and classes that are shared
* amongst the items in the list.
* <p>
* The order of the items is as they are first encountered, favoring interfaces before
* The order of the items is as they are first encountered, favoring interfaces before
* classes. Further, interface hierarchies are examined before concrete parent extensions.
* <p>
* If the given items have no parents in common, then the result will be a list with
* only <code>Object.class</code>.
*
*
* @param list the items to examine
* @return the set of items
*/
@ -494,9 +521,9 @@ public class ReflectionUtilities {
}
/**
* Turns the given {@link Throwable} into a String version of its
* Turns the given {@link Throwable} into a String version of its
* {@link Throwable#printStackTrace()} method.
*
*
* @param t the throwable
* @return the string
*/
@ -505,9 +532,9 @@ public class ReflectionUtilities {
}
/**
* Turns the given {@link Throwable} into a String version of its
* Turns the given {@link Throwable} into a String version of its
* {@link Throwable#printStackTrace()} method.
*
*
* @param message the preferred message to use. If null, the throwable message will be used
* @param t the throwable
* @return the string
@ -543,11 +570,11 @@ public class ReflectionUtilities {
/**
* Returns an order set of all interfaces implemented and classes extended for the entire
* type structure of the given class.
* type structure of the given class.
* <p>
* If <code>Object.class</code> is passed to this method, then it will be returned in the
* If <code>Object.class</code> is passed to this method, then it will be returned in the
* result of this method.
*
*
* @param c the class to introspect
* @return the set of parents
*/
@ -581,7 +608,7 @@ public class ReflectionUtilities {
/**
* Returns the type arguments for the given base class and extension.
*
*
* <p>Caveat: this lookup will only work if the given child class is a concrete class that
* has its type arguments specified. For example, these cases will work:
* <pre>
@ -592,17 +619,17 @@ public class ReflectionUtilities {
*
* // class definition
* public class MyList implements List&lt;String&gt; {
* </pre>
*
* </pre>
*
* Whereas this case will not work:
* <pre>
* // local variable with the type specified
* List&lt;String&gt; myList = new ArrayList&lt;String&gt;();
* </pre>
*
*
* <p>Note: a null entry in the result list will exist for any type that was unrecoverable
*
*
*
*
* @param <T> the type of the base and child class
* @param baseClass the base class
* @param childClass the child class
@ -618,7 +645,7 @@ public class ReflectionUtilities {
Type baseClassAsType =
walkClassHierarchyAndResolveTypes(baseClass, resolvedTypesDictionary, childClass);
// try to resolve type arguments defined by 'baseClass' to the raw runtime class
// try to resolve type arguments defined by 'baseClass' to the raw runtime class
Type[] baseClassDeclaredTypeArguments = getDeclaredTypeArguments(baseClassAsType);
return resolveBaseClassTypeArguments(resolvedTypesDictionary,
baseClassDeclaredTypeArguments);

View File

@ -33,7 +33,6 @@ import resources.ResourceManager;
public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
public RepositoryCustomScreenShots() {
super();
}
@Test
@ -127,8 +126,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
int y = p.y - radius;
g.fillOval(x, y, radius * 2, 2 * radius);
Font f = g.getFont().deriveFont(12f);
g.setFont(f);
FontMetrics metrics = g.getFontMetrics();
int height = metrics.getHeight();
g.setColor(Palette.BLACK);
@ -154,8 +151,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
BasicStroke stroke = new BasicStroke(1);
g.setStroke(stroke);
Font f = g.getFont().deriveFont(12f);
g.setFont(f);
FontMetrics metrics = g.getFontMetrics();
int margin = 5;
int height = metrics.getHeight() * text.length + 2 * margin;
@ -189,8 +184,6 @@ public class RepositoryCustomScreenShots extends GhidraScreenShotGenerator {
Graphics2D g = ((BufferedImage) image).createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Font f = g.getFont().deriveFont(12f);
g.setFont(f);
FontMetrics metrics = g.getFontMetrics();
// int margin = 5;
int height = metrics.getHeight() * text.length;