Merge remote-tracking branch

'origin/dev747368_GT-2698_hostile_html_whack_a_mole_UI_stuff'

Conflicts:
	Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/AnalysisPanel.java
This commit is contained in:
ghidravore 2019-05-02 14:24:21 -04:00
commit 45222ad4d3
423 changed files with 6234 additions and 5902 deletions

View file

@ -22,6 +22,8 @@ import java.util.List;
import javax.swing.*;
import docking.action.DockingActionIf;
import docking.widgets.label.GIconLabel;
import docking.widgets.label.GLabel;
import resources.ResourceManager;
/**
@ -98,17 +100,14 @@ public class ActionDialog extends DialogComponentProvider {
JPanel innerPanel = new JPanel(new BorderLayout());
JPanel labelPanel = new JPanel(new GridLayout(0, 1));
labelPanel.add(new JLabel("Multiple actions have been mapped to " + keystrokeName));
labelPanel.add(new JLabel("Actions that can be enabled at the same"));
labelPanel.add(new JLabel("time should be mapped to different keys"));
labelPanel.add(new GLabel("Multiple actions have been mapped to " + keystrokeName));
labelPanel.add(new GLabel("Actions that can be enabled at the same"));
labelPanel.add(new GLabel("time should be mapped to different keys"));
innerPanel.setBorder(BorderFactory.createTitledBorder("Actions"));
ImageIcon image = ResourceManager.loadImage("images/warning.png");
JLabel cautionLabel = new JLabel(image);
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel.add(cautionLabel);
panel.add(new GIconLabel(ResourceManager.loadImage("images/warning.png")));
panel.add(labelPanel);
listModel = new DefaultListModel<>();

View file

@ -31,6 +31,7 @@ import docking.action.DockingActionIf;
import docking.event.mouse.GMouseListenerAdapter;
import docking.menu.DockingToolbarButton;
import docking.util.*;
import docking.widgets.label.GDHtmlLabel;
import ghidra.generic.function.Callback;
import ghidra.util.*;
import ghidra.util.exception.AssertException;
@ -889,7 +890,7 @@ public class DialogComponentProvider
private JPanel buildStatusPanel() {
JPanel panel = new JPanel(new BorderLayout());
statusLabel = new JLabel(" ");
statusLabel = new GDHtmlLabel(" ");
statusLabel.setName("statusLabel");
statusLabel.setHorizontalAlignment(SwingConstants.CENTER);
statusLabel.setForeground(Color.blue);

View file

@ -21,11 +21,13 @@ import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import docking.menu.DockingMenuItemUI;
import docking.widgets.GComponent;
public class DockingMenuItem extends JMenuItem {
public class DockingMenuItem extends JMenuItem implements GComponent {
public DockingMenuItem() {
setUI(DockingMenuItemUI.createUI(this));
setHTMLRenderingEnabled(false);
}
@Override

View file

@ -79,7 +79,7 @@ public interface DockingTool {
/**
* Set the status information
* @param text string to be displayed in the Status display area
* @param text non-html string to be displayed in the Status display area
*/
public void setStatusInfo(String text);

View file

@ -20,15 +20,79 @@ import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicSeparatorUI;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.undo.UndoableEdit;
import docking.widgets.button.GRadioButton;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.checkbox.GHtmlCheckBox;
import docking.widgets.combobox.GComboBox;
import docking.widgets.combobox.GhidraComboBox;
import docking.widgets.label.*;
import docking.widgets.list.GList;
import docking.widgets.list.GListCellRenderer;
import docking.widgets.table.GTableCellRenderer;
import docking.widgets.tree.support.GTreeRenderer;
import ghidra.docking.util.DockingWindowsLookAndFeelUtils;
import ghidra.util.HTMLUtilities;
import resources.ResourceManager;
/**
* <h1>Notes about how to use HTML safely:</h1>
* Java's built-in HTML rendering in UI components is very useful, but can also introduce security
* issues when a hostile actor is providing the text strings that are being rendered.
* <p>
* Before using a native Java UI component, search for a corresponding 'G'hidra component, and
* if possible choose the non-HTML version of that component (if available).
* <p>
* For instance, instead of using {@link JLabel}, use either {@link GLabel} or {@link GHtmlLabel}
* (and their variants).
* <p>
* (native JLabel, JCheckbox, etc, usage is actually disallowed in the Ghidra project)
* <p>
* When using a UI component that is HTML enabled, care must be used when constructing the text
* that is being rendered.
* <p>
* During string-building or concatenation, appending a non-literal string value (ie.
* {@code "Hello " + getFoo();} ), the non-literal string value should be escaped using
* {@link HTMLUtilities#escapeHTML(String)} (ie. {@code "Hello " + HTMLUtilities.escapeHTML(getFoo());}.
* <p>
* Of course, there are exceptions to every rule, and if the string value can be definitely be
* traced to its source and there are no user-supplied origins, the HTML escaping can be skipped.
* <p>
* Note: just using a UI component that is HTML enabled does not mean that it will treat its
* text as HTML text. If you need to HTML escape any values that are being fed to the component, you
* need to force the HTML mode 'on' by pre-pending a "&lt;HTML&gt;" at the beginning of the string.
* If you fail to do this, the escaped substrings will look wrong because any '&lt;' and '&gt;' chars
* (and others) in the substring will be mangled when rendered in plain-text mode.
* <p>
* When working with plain text, try to avoid allowing a user supplied string being the first
* value of text that could be fed to a UI component. This will prevent the possibly hostile
* string from having a leading HTML start tag.
* (ie. when displaying an error to the user about a bad file, don't put the filename
* value at the start of the string, but instead put a quote or some other delimiter to prevent
* html mode).
* <p>
* <h1>Recommended Ghidra UI Components:</h1>
* <p>
* <table border=1>
* <tr><th>Native Component</th><th>Recommended Component</th></tr>
* <tr><td>{@link JLabel}</td><td>{@link GLabel}<br>{@link GDLabel}<br>{@link GHtmlLabel}<br>{@link GDHtmlLabel}<br>{@link GIconLabel}</td></tr>
* <tr><td>{@link JCheckBox}</td><td>{@link GCheckBox}<br>{@link GHtmlCheckBox}</td></tr>
* <tr><td>{@link JComboBox}</td><td>{@link GComboBox}<br>{@link GhidraComboBox}</td></tr>
* <tr><td>{@link JList}</td><td>{@link GList}</td></tr>
* <tr><td>{@link ListCellRenderer}<br>{@link DefaultListCellRenderer}</td><td>{@link GListCellRenderer}</td></tr>
* <tr><td>{@link TableCellRenderer}</td><td>{@link GTableCellRenderer}</td></tr>
* <tr><td>{@link TreeCellRenderer}<br>{@link DefaultTreeCellRenderer}</td><td>{@link GTreeRenderer}<br>{@link DnDTreeCellRenderer}</td></tr>
* <tr><td>{@link JRadioButton}</td><td>{@link GRadioButton}</td></tr>
* <tr><td>{@link JButton}</td><td>???tbd???</td></tr>
* </table>
*/
public class DockingUtils {
private static final int ICON_SIZE = 16;
/** System dependent mask for the Ctrl key */

View file

@ -24,6 +24,8 @@ import java.net.UnknownHostException;
import javax.swing.*;
import docking.widgets.ScrollableTextArea;
import docking.widgets.label.GHtmlLabel;
import docking.widgets.label.GIconLabel;
import generic.util.WindowUtilities;
import ghidra.framework.Application;
import ghidra.util.HTMLUtilities;
@ -48,7 +50,6 @@ public class ErrLogDialog extends DialogComponentProvider {
private ErrorDetailsPanel detailsPanel;
private JButton detailsButton;
private JButton sendButton;
private JLabel messageLabel;
private JPanel mainPanel;
private static ErrorReporter errorReporter;
@ -128,13 +129,11 @@ public class ErrLogDialog extends DialogComponentProvider {
private void buildMainPanel(String message, String details, boolean isException) {
messageLabel = new JLabel(HTMLUtilities.toHTML(message));
JLabel iconLabel =
new JLabel(UIManager.getIcon("OptionPane.errorIcon"), SwingConstants.RIGHT);
JPanel introPanel = new JPanel(new BorderLayout(10, 10));
introPanel.add(iconLabel, BorderLayout.WEST);
introPanel.add(messageLabel, BorderLayout.CENTER);
introPanel.add(
new GIconLabel(UIManager.getIcon("OptionPane.errorIcon"), SwingConstants.RIGHT),
BorderLayout.WEST);
introPanel.add(new GHtmlLabel(HTMLUtilities.toHTML(message)), BorderLayout.CENTER);
mainPanel = new JPanel(new BorderLayout(10, 20));
mainPanel.add(introPanel, BorderLayout.NORTH);
@ -143,8 +142,7 @@ public class ErrLogDialog extends DialogComponentProvider {
sendButton.addActionListener(e -> sendDetails());
detailsPanel = new ErrorDetailsPanel();
String text = isShowingDetails ? CLOSE : DETAIL;
detailsButton = new JButton(text);
detailsButton = new JButton(isShowingDetails ? CLOSE : DETAIL);
detailsButton.addActionListener(e -> {
String label = detailsButton.getText();
showDetails(label.equals(DETAIL));

View file

@ -28,6 +28,7 @@ import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.TreePath;
import docking.widgets.label.GHtmlLabel;
import docking.widgets.tree.*;
import docking.widgets.tree.support.GTreeDragNDropHandler;
import ghidra.util.*;
@ -171,7 +172,7 @@ public class ErrLogExpandableDialog extends DialogComponentProvider {
msgPanel.setLayout(new BorderLayout(16, 16));
msgPanel.setBorder(new EmptyBorder(16, 16, 16, 16));
{
JLabel msgText = new JLabel(getHTML(msg, report)) {
JLabel msgText = new GHtmlLabel(getHTML(msg, report)) {
@Override
public Dimension getPreferredSize() {
// when rendering HTML the label can expand larger than the screen;

View file

@ -27,6 +27,7 @@ import org.jdesktop.animation.timing.interpolation.PropertySetter;
import docking.action.DockingActionIf;
import docking.widgets.VariableHeightPanel;
import docking.widgets.label.GDLabel;
// TODO: should this be put into generic?
public class GenericHeader extends JPanel {
@ -342,7 +343,7 @@ public class GenericHeader extends JPanel {
TitlePanel() {
super(new BorderLayout());
setFocusable(false);
titleLabel = new JLabel();
titleLabel = new GDLabel();
titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 0));
titleLabel.setForeground(Color.BLACK);
titleLabel.setFocusable(false);

View file

@ -30,6 +30,7 @@ import org.jdesktop.animation.timing.Animator;
import docking.util.AnimationUtils;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDLabel;
import generic.util.WindowUtilities;
import ghidra.util.HTMLUtilities;
import ghidra.util.SystemUtilities;
@ -83,7 +84,7 @@ public class StatusBar extends JPanel {
JPanel eastPanel = createEastPanel(statusAreaPanel);
add(eastPanel, BorderLayout.EAST);
statusLabel = new JLabel(" ");
statusLabel = new GDLabel(" ");
statusLabel.setOpaque(true);
statusLabel.setName("Tool Status");

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,26 +15,24 @@
*/
package docking;
import javax.swing.Icon;
import docking.widgets.label.GIconLabel;
import ghidra.framework.OperatingSystem;
import ghidra.framework.Platform;
import javax.swing.Icon;
import javax.swing.JLabel;
import resources.ResourceManager;
/**
* A class to handle the space requirements on the status bar that vary for different OSes. For
* example, the Mac requires extra space on the status bar, due to the drag icon the Mac uses.
*/
public class StatusBarSpacer extends JLabel {
private static Icon EMPTY_ICON = ResourceManager.loadImage("images/EmptyIcon.gif");
public StatusBarSpacer() {
if ( Platform.CURRENT_PLATFORM.getOperatingSystem() == OperatingSystem.MAC_OS_X ) {
setIcon( EMPTY_ICON );
}
}
public class StatusBarSpacer extends GIconLabel {
private static Icon EMPTY_ICON = ResourceManager.loadImage("images/EmptyIcon.gif");
public StatusBarSpacer() {
super(
Platform.CURRENT_PLATFORM.getOperatingSystem() == OperatingSystem.MAC_OS_X ? EMPTY_ICON
: (Icon) null);
}
}

View file

@ -23,6 +23,7 @@ import javax.swing.*;
import javax.swing.text.*;
import docking.*;
import docking.widgets.label.GIconLabel;
import ghidra.util.HelpLocation;
import ghidra.util.ReservedKeyBindings;
import resources.ResourceManager;
@ -65,8 +66,7 @@ public class KeyEntryDialog extends DialogComponentProvider {
defaultPanel = new JPanel(new BorderLayout());
defaultPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5));
Icon icon = ResourceManager.loadImage("images/information.png");
JLabel imageLabel = new JLabel(icon);
JLabel imageLabel = new GIconLabel(ResourceManager.loadImage("images/information.png"));
bgColor = imageLabel.getBackground();
JTextPane pane = new JTextPane();
pane.setBorder(BorderFactory.createEmptyBorder(0, 5, 2, 5));
@ -75,8 +75,8 @@ public class KeyEntryDialog extends DialogComponentProvider {
StyledDocument document = pane.getStyledDocument();
try {
document.insertString(0, "To add or change a key binding, type any key combination.\n"
+ "To remove a key binding, press <Enter> or <Backspace>.", null);
document.insertString(0, "To add or change a key binding, type any key combination.\n" +
"To remove a key binding, press <Enter> or <Backspace>.", null);
}
catch (BadLocationException e1) {
// shouldn't be possible
@ -204,7 +204,7 @@ public class KeyEntryDialog extends DialogComponentProvider {
return Collections.emptyList();
}
List<DockingActionIf> list = multiAction.getActions();
Map<String, DockingActionIf> nameMap = new HashMap<String, DockingActionIf>(list.size());
Map<String, DockingActionIf> nameMap = new HashMap<>(list.size());
// the list may have multiple matches for a single owner, which we do not want (see
// DummyKeyBindingsOptionsAction)
@ -215,7 +215,7 @@ public class KeyEntryDialog extends DialogComponentProvider {
}
}
return new ArrayList<DockingActionIf>(nameMap.values());
return new ArrayList<>(nameMap.values());
}
/**

View file

@ -21,6 +21,8 @@ import java.util.List;
import javax.swing.*;
import docking.widgets.label.GIconLabel;
import docking.widgets.label.GLabel;
import ghidra.framework.Application;
import ghidra.framework.PluggableServiceRegistry;
import ghidra.util.HelpLocation;
@ -35,20 +37,20 @@ public class ApplicationInformationDisplayFactory {
}
public static String createSplashScreenTitle() {
ApplicationInformationDisplayFactory factory =
PluggableServiceRegistry.getPluggableService(ApplicationInformationDisplayFactory.class);
ApplicationInformationDisplayFactory factory = PluggableServiceRegistry.getPluggableService(
ApplicationInformationDisplayFactory.class);
return factory.doCreateSplashScreenTitle();
}
public static String createAboutTitle() {
ApplicationInformationDisplayFactory factory =
PluggableServiceRegistry.getPluggableService(ApplicationInformationDisplayFactory.class);
ApplicationInformationDisplayFactory factory = PluggableServiceRegistry.getPluggableService(
ApplicationInformationDisplayFactory.class);
return factory.doCreateAboutTitle();
}
public static List<Image> getWindowIcons() {
ApplicationInformationDisplayFactory factory =
PluggableServiceRegistry.getPluggableService(ApplicationInformationDisplayFactory.class);
ApplicationInformationDisplayFactory factory = PluggableServiceRegistry.getPluggableService(
ApplicationInformationDisplayFactory.class);
return factory.doGetWindowIcons();
}
@ -69,8 +71,8 @@ public class ApplicationInformationDisplayFactory {
}
public static ImageIcon getHomeIcon() {
ApplicationInformationDisplayFactory factory = PluggableServiceRegistry
.getPluggableService(ApplicationInformationDisplayFactory.class);
ApplicationInformationDisplayFactory factory = PluggableServiceRegistry.getPluggableService(
ApplicationInformationDisplayFactory.class);
return factory.doGetHomeIcon();
}
@ -81,20 +83,20 @@ public class ApplicationInformationDisplayFactory {
}
public static JComponent createSplashScreenComponent() {
ApplicationInformationDisplayFactory factory =
PluggableServiceRegistry.getPluggableService(ApplicationInformationDisplayFactory.class);
ApplicationInformationDisplayFactory factory = PluggableServiceRegistry.getPluggableService(
ApplicationInformationDisplayFactory.class);
return factory.doCreateSplashScreenComponent();
}
public static JComponent createAboutComponent() {
ApplicationInformationDisplayFactory factory =
PluggableServiceRegistry.getPluggableService(ApplicationInformationDisplayFactory.class);
ApplicationInformationDisplayFactory factory = PluggableServiceRegistry.getPluggableService(
ApplicationInformationDisplayFactory.class);
return factory.doCreateAboutComponent();
}
public static HelpLocation createHelpLocation() {
ApplicationInformationDisplayFactory factory =
PluggableServiceRegistry.getPluggableService(ApplicationInformationDisplayFactory.class);
ApplicationInformationDisplayFactory factory = PluggableServiceRegistry.getPluggableService(
ApplicationInformationDisplayFactory.class);
return factory.doCreateHelpLocation();
}
@ -117,8 +119,7 @@ public class ApplicationInformationDisplayFactory {
panel.setBackground(background);
JLabel nameLabel = new JLabel();
nameLabel.setText(Application.getName());
JLabel nameLabel = new GLabel(Application.getName());
nameLabel.setForeground(new Color(155, 155, 155));
Font newFont = new Font("Garamond", Font.BOLD, 35);
nameLabel.setFont(newFont);
@ -128,7 +129,7 @@ public class ApplicationInformationDisplayFactory {
final JPanel imagePanel = new JPanel(new BorderLayout());
imagePanel.setBackground(background);
JLabel imageLabel = new JLabel(icon);
JLabel imageLabel = new GIconLabel(icon);
imageLabel.setVerticalAlignment(SwingConstants.CENTER);
imageLabel.setHorizontalAlignment(SwingConstants.CENTER);
imagePanel.add(imageLabel);
@ -143,7 +144,7 @@ public class ApplicationInformationDisplayFactory {
}
protected List<Image> doGetWindowIcons() {
List<Image> list = new ArrayList<Image>();
List<Image> list = new ArrayList<>();
list.add(ResourceManager.loadImage("images/www_128.png").getImage());
list.add(ResourceManager.loadImage("images/www_16.png").getImage());
return list;

View file

@ -23,6 +23,8 @@ import javax.swing.*;
import javax.swing.border.BevelBorder;
import docking.*;
import docking.widgets.label.GDLabel;
import docking.widgets.label.GLabel;
import generic.util.WindowUtilities;
import ghidra.framework.Application;
import ghidra.util.Msg;
@ -313,7 +315,7 @@ public class SplashScreen extends JWindow {
titlePanel.setLayout(new BorderLayout());
JLabel titleLabel =
new JLabel(ApplicationInformationDisplayFactory.createSplashScreenTitle());
new GLabel(ApplicationInformationDisplayFactory.createSplashScreenTitle());
Font font = titleLabel.getFont();
font = new Font(font.getName(), Font.BOLD, 11);
titleLabel.setFont(font);
@ -328,7 +330,7 @@ public class SplashScreen extends JWindow {
private Component createStatusComponent() {
Font f = new Font("serif", Font.BOLD, 12);
statusLabel = new JLabel(" Loading...");
statusLabel = new GDLabel(" Loading...");
statusLabel.setFont(f);
statusLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 2, 10));

View file

@ -27,6 +27,7 @@ import javax.swing.event.*;
import docking.*;
import docking.action.*;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDHtmlLabel;
import ghidra.util.SystemUtilities;
import resources.ResourceManager;
@ -415,7 +416,7 @@ public class MultipleActionDockingToolbarButton extends EmptyBorderButton {
private final int EMTPY_SEPARATOR_HEIGHT = 10;
private final int TEXT_SEPARATOR_HEIGHT = 32;
private JLabel renderer = new JLabel();
private JLabel renderer = new GDHtmlLabel();
private int separatorHeight = EMTPY_SEPARATOR_HEIGHT;

View file

@ -27,6 +27,8 @@ import javax.swing.text.*;
import com.toedter.calendar.JCalendar;
import docking.widgets.label.GDLabel;
import docking.widgets.label.GLabel;
import ghidra.util.layout.HorizontalLayout;
/**
@ -34,7 +36,7 @@ import ghidra.util.layout.HorizontalLayout;
*/
class Clock extends JPanel implements CaretListener {
private JLabel dateLabel = new JLabel("Apr 18, 2006");
private JLabel dateLabel = new GDLabel("Apr 18, 2006");
private JTextField hoursField;
private JTextField minutesField;
private JTextField secondsField;
@ -132,9 +134,9 @@ class Clock extends JPanel implements CaretListener {
add(dateLabel);
add(hoursField);
add(new JLabel(":"));
add(new GLabel(":"));
add(minutesField);
add(new JLabel(":"));
add(new GLabel(":"));
add(secondsField);
formatter = new SimpleDateFormat("HH:mm:ss MMM dd, yyyy");

View file

@ -26,6 +26,7 @@ import javax.swing.event.ChangeListener;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.widgets.label.GDHtmlLabel;
/**
* Color editor that uses the JColorChooser.
@ -37,7 +38,7 @@ public class ColorEditor extends PropertyEditorSupport {
private static GhidraColorChooser colorChooser;
private JLabel previewLabel = new JLabel();
private JLabel previewLabel = new GDHtmlLabel();
private Color color;
private Color lastUserSelectedColor;
@ -123,8 +124,8 @@ public class ColorEditor extends PropertyEditorSupport {
colorString = DARK_COLOR;
}
previewLabel.setText("<HTML><CENTER><I><FONT SIZE=2 COLOR=" + colorString +
">click</FONT></I></CENTER>");
previewLabel.setText(
"<HTML><CENTER><I><FONT SIZE=2 COLOR=" + colorString + ">click</FONT></I></CENTER>");
previewLabel.setBackground(color);
}

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,10 +15,6 @@
*/
package docking.options.editor;
import ghidra.framework.options.EditorState;
import ghidra.util.HTMLUtilities;
import ghidra.util.layout.PairLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
@ -28,60 +23,63 @@ import java.awt.event.MouseEvent;
import javax.swing.*;
import docking.ToolTipManager;
import docking.widgets.label.GDLabel;
import ghidra.framework.options.EditorState;
import ghidra.util.HTMLUtilities;
import ghidra.util.layout.PairLayout;
public class DefaultOptionComponent extends GenericOptionsComponent {
private JLabel label;
private Component component;
private JLabel label;
private Component component;
public DefaultOptionComponent( EditorState editorState ) {
super( editorState );
setLayout( new PairLayout(0, 6, 40) );
this.component = editorState.getEditorComponent();
public DefaultOptionComponent(EditorState editorState) {
super(editorState);
setLayout(new PairLayout(0, 6, 40));
this.component = editorState.getEditorComponent();
label = new JLabel(editorState.getTitle(), SwingConstants.RIGHT);
label = new GDLabel(editorState.getTitle(), SwingConstants.RIGHT);
if (component instanceof AbstractButton) {
label.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
if (!component.isEnabled()) {
return;
}
AbstractButton button = (AbstractButton) component;
button.setSelected(!button.isSelected());
}
});
}
setSize(getPreferredSize());
if (component instanceof AbstractButton) {
label.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
if (!component.isEnabled()) {
return;
}
AbstractButton button = (AbstractButton)component;
button.setSelected(!button.isSelected());
}
});
}
setSize(getPreferredSize());
String description = editorState.getDescription();
if (description != null) {
String htmlDescription = HTMLUtilities.toWrappedHTML(description);
ToolTipManager.setToolTipText(label, htmlDescription);
if (component instanceof JComponent) {
ToolTipManager.setToolTipText((JComponent) component, htmlDescription);
}
}
add(label);
add(component);
}
String description = editorState.getDescription();
if (description != null) {
String htmlDescription = HTMLUtilities.toWrappedHTML( description );
ToolTipManager.setToolTipText(label, htmlDescription);
if (component instanceof JComponent) {
ToolTipManager.setToolTipText((JComponent)component, htmlDescription);
}
}
add(label);
add(component);
}
@Override
public void setEnabled(boolean enabled) {
label.setEnabled(enabled);
component.setEnabled(enabled);
}
@Override
public void setEnabled(boolean enabled) {
label.setEnabled(enabled);
component.setEnabled(enabled);
}
@Override
protected void setAlignmentPreferredSize(Dimension dimension) {
label.setPreferredSize(dimension);
}
@Override
protected void setAlignmentPreferredSize( Dimension dimension ) {
label.setPreferredSize( dimension );
}
@Override // overridden to get the size based upon this class's two components
protected Dimension getPreferredAlignmentSize() {
Dimension dimension = label.getPreferredSize();
int maxHeight = Math.max( dimension.height, component.getPreferredSize().height );
return new Dimension( dimension.width, maxHeight );
}
@Override // overridden to get the size based upon this class's two components
protected Dimension getPreferredAlignmentSize() {
Dimension dimension = label.getPreferredSize();
int maxHeight = Math.max(dimension.height, component.getPreferredSize().height);
return new Dimension(dimension.width, maxHeight);
}
}

View file

@ -27,6 +27,8 @@ import javax.swing.*;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GDLabel;
/**
* This Bean FontEditor displays a String with the current selected font name,
@ -34,26 +36,22 @@ import docking.DockingWindowManager;
*/
public class FontPropertyEditor extends PropertyEditorSupport {
private Font font;
// private JLabel previewLabel = new JLabel();
private JButton previewButton = new JButton();
// private JLabel previewLabel = new GDLabel();
private final static String SAMPLE_STRING = "ABCabc \u00a9\u00ab\u00a7\u0429\u05d1\u062c\u4eb9";
private JButton previewButton = new JButton(SAMPLE_STRING);
/**
* The default constructor.
*
*/
public FontPropertyEditor() {
previewButton.setText(SAMPLE_STRING);
previewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// show the editor to get the user value
showDialog();
previewButton.addActionListener(e -> {
// show the editor to get the user value
showDialog();
// now set the new value
previewButton.setFont(font);
}
// now set the new value
previewButton.setFont(font);
});
// previewLabel.addMouseListener( new MouseAdapter() {
@ -134,7 +132,7 @@ public class FontPropertyEditor extends PropertyEditorSupport {
sizeAndStylePanel.add(BorderLayout.CENTER, stylePanel);
topPanel.add(BorderLayout.CENTER, sizeAndStylePanel);
fontStringLabel = new JLabel(FontPropertyEditor.SAMPLE_STRING);
fontStringLabel = new GDLabel(FontPropertyEditor.SAMPLE_STRING);
fontStringLabel.setPreferredSize(new Dimension(350, 50));
fontStringLabel.setHorizontalAlignment(SwingConstants.CENTER);
fontStringLabel.setFont(font);
@ -142,21 +140,18 @@ public class FontPropertyEditor extends PropertyEditorSupport {
add(BorderLayout.NORTH, topPanel);
fontLabel = new JLabel();
fontLabel.setText("Fonts");
fontLabel = new GDLabel("Fonts");
Font newFont = getFont().deriveFont(1);
fontLabel.setFont(newFont);
fontLabel.setHorizontalAlignment(SwingConstants.CENTER);
fontPanel.add(fontLabel);
sizeLabel = new JLabel();
sizeLabel.setText("Sizes");
sizeLabel = new GDLabel("Sizes");
sizeLabel.setFont(newFont);
sizeLabel.setHorizontalAlignment(SwingConstants.CENTER);
sizePanel.add(sizeLabel);
styleLabel = new JLabel();
styleLabel.setText("Styles");
styleLabel = new GDLabel("Styles");
styleLabel.setFont(newFont);
styleLabel.setHorizontalAlignment(SwingConstants.CENTER);
stylePanel.add(styleLabel);
@ -164,27 +159,26 @@ public class FontPropertyEditor extends PropertyEditorSupport {
GraphicsEnvironment gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
String envfonts[] = gEnv.getAvailableFontFamilyNames();
List<FontWrapper> list = new ArrayList<FontWrapper>(envfonts.length);
List<FontWrapper> list = new ArrayList<>(envfonts.length);
for (String envfont : envfonts) {
list.add(new FontWrapper(envfont));
}
Collections.sort(list);
fonts = new JComboBox<>(list.toArray(new FontWrapper[envfonts.length]));
fonts = new GComboBox<>(list.toArray(new FontWrapper[envfonts.length]));
fonts.setMaximumRowCount(9);
FontWrapper fontWrapper = new FontWrapper(font.getName());
fontPanel.add(fonts);
fonts.setSelectedItem(fontWrapper);
sizes =
new JComboBox<>(
new String[] { "8", "10", "12", "14", "16", "18", "24", "28", "32" });
sizes = new GComboBox<>(
new String[] { "8", "10", "12", "14", "16", "18", "24", "28", "32" });
sizes.setMaximumRowCount(9);
sizePanel.add(sizes);
sizeChoice = font.getSize();
sizes.setSelectedItem("" + sizeChoice);
sizes.setMaximumRowCount(9);
styles = new JComboBox<>(new String[] { "PLAIN", "BOLD", "ITALIC", "BOLD & ITALIC" });
styles = new GComboBox<>(new String[] { "PLAIN", "BOLD", "ITALIC", "BOLD & ITALIC" });
styles.setMaximumRowCount(9);
stylePanel.add(styles);
styleChoice = font.getStyle();

View file

@ -31,11 +31,11 @@ import docking.help.Help;
import docking.help.HelpService;
import docking.widgets.MultiLineLabel;
import docking.widgets.OptionDialog;
import docking.widgets.label.GIconLabel;
import docking.widgets.tree.*;
import docking.widgets.tree.internal.DefaultGTreeDataTransformer;
import ghidra.framework.options.*;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.*;
import ghidra.util.bean.opteditor.OptionsVetoException;
import ghidra.util.layout.MiddleLayout;
import ghidra.util.task.SwingUpdateManager;
@ -138,7 +138,7 @@ public class OptionsPanel extends JPanel {
Options currentOptions = getSelectedOptions();
int userChoice = OptionDialog.showOptionDialog(viewPanel, "Restore Defaults?",
"<html>Restore <b>" + currentOptions.getName() +
"<html>Restore <b>" + HTMLUtilities.escapeHTML(currentOptions.getName()) +
"</b> to default option values <b>and erase current settings?</b>",
"Restore Defaults");
if (userChoice == OptionDialog.CANCEL_OPTION) {
@ -242,9 +242,6 @@ public class OptionsPanel extends JPanel {
JPanel panel = new JPanel(new MiddleLayout());
panel.setName("Default");
Icon icon = ResourceManager.loadImage("images/information.png");
JLabel imageLabel = new JLabel(icon);
MultiLineLabel label =
new MultiLineLabel("To change Options, select a Folder or Option Group from the\n" +
"Options Tree and change the Option settings.");
@ -255,7 +252,7 @@ public class OptionsPanel extends JPanel {
BoxLayout bl = new BoxLayout(labelPanel, BoxLayout.X_AXIS);
labelPanel.setLayout(bl);
labelPanel.add(Box.createHorizontalStrut(5));
labelPanel.add(imageLabel);
labelPanel.add(new GIconLabel(ResourceManager.loadImage("images/information.png")));
labelPanel.add(Box.createHorizontalStrut(5));
labelPanel.add(label);

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,8 +15,6 @@
*/
package docking.options.editor;
import ghidra.util.layout.VerticalLayout;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
@ -27,6 +24,10 @@ import javax.swing.*;
import javax.swing.border.*;
import javax.swing.colorchooser.AbstractColorChooserPanel;
import docking.widgets.label.GHtmlLabel;
import docking.widgets.label.GLabel;
import ghidra.util.layout.VerticalLayout;
public class SettableColorSwatchChooserPanel extends AbstractColorChooserPanel {
SwatchPanel swatchPanel;
RecentSwatchPanel recentSwatchPanel;
@ -129,7 +130,7 @@ public class SettableColorSwatchChooserPanel extends AbstractColorChooserPanel {
recentSwatchPanel.addMouseListener(recentSwatchListener);
recentSwatchPanel.setBorder(border);
JPanel recentLabelHolder = new JPanel(new BorderLayout());
JLabel l = new JLabel(recentStr);
JLabel l = new GHtmlLabel(recentStr);
l.setLabelFor(recentSwatchPanel);
recentLabelHolder.add(l, BorderLayout.NORTH);
gbc.weighty = 0.0;
@ -144,7 +145,7 @@ public class SettableColorSwatchChooserPanel extends AbstractColorChooserPanel {
historySwatchPanel.addMouseListener(historySwatchListener);
historySwatchPanel.setBorder(border);
JPanel historyLabelHolder = new JPanel(new BorderLayout());
JLabel historyLabel = new JLabel("History:");
JLabel historyLabel = new GLabel("History:");
historyLabel.setLabelFor(historySwatchPanel);
historyLabelHolder.add(historyLabel, BorderLayout.NORTH);
gbc.weighty = 0.0;
@ -251,10 +252,10 @@ class SwatchPanel extends JPanel {
int y = row * (swatchSize.height + gap.height);
g.fillRect(x, y, swatchSize.width, swatchSize.height);
g.setColor(Color.black);
g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1, y +
swatchSize.height - 1);
g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y +
swatchSize.height - 1);
g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1,
y + swatchSize.height - 1);
g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1,
y + swatchSize.height - 1);
}
}
}

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,38 +19,37 @@ import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import resources.ResourceManager;
import javax.swing.Icon;
import javax.swing.Timer;
public class AnimatedIcon implements Icon {
/** best guess at how many timer invocations may happen before paint gets called*/
private static final int MAGIC_TIMER_CALLS_WITHOUT_PAINT_CALL = 5;
private final List<Icon> iconList;
/** best guess at how many timer invocations may happen before paint gets called*/
private static final int MAGIC_TIMER_CALLS_WITHOUT_PAINT_CALL = 5;
private final List<? extends Icon> iconList;
private int currentIconIndex = 0;
private Component component;
private int height;
private int width;
private int skipFrames;
private int skipFrameCount = 0;
private Timer timer;
private int paintCounter = 0;
public AnimatedIcon(List<Icon> icons, int frameDelay, int framesToSkip) {
private Timer timer;
private int paintCounter = 0;
public AnimatedIcon(List<? extends Icon> icons, int frameDelay, int framesToSkip) {
this.iconList = icons;
this.skipFrames = framesToSkip;
timer = new Timer(frameDelay, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if ( --paintCounter <= 0 ) {
timer.stop();
return;
}
if (--paintCounter <= 0) {
timer.stop();
return;
}
if (skipFrameCount > 0) {
skipFrameCount--;
return;
@ -65,44 +63,33 @@ public class AnimatedIcon implements Icon {
}
}
});
for ( Icon icon : iconList ) {
for (Icon icon : iconList) {
width = Math.max(width, icon.getIconWidth());
height = Math.max(height, icon.getIconHeight());
}
}
@Override
public int getIconHeight() {
return height;
}
@Override
public int getIconWidth() {
return width;
}
private void restartAnimation() {
timer.start();
paintCounter = MAGIC_TIMER_CALLS_WITHOUT_PAINT_CALL;
timer.start();
paintCounter = MAGIC_TIMER_CALLS_WITHOUT_PAINT_CALL;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
restartAnimation();
iconList.get(currentIconIndex).paintIcon( c, g, x, y );
restartAnimation();
iconList.get(currentIconIndex).paintIcon(c, g, x, y);
component = c;
}
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
List<Icon> iconList = new ArrayList<Icon>();
iconList.add(ResourceManager.loadImage( "images/weather-clear.png" ));
iconList.add(ResourceManager.loadImage( "images/weather-few-clouds-reverse.png" ));
iconList.add(ResourceManager.loadImage( "images/weather-overcast.png" ));
iconList.add(ResourceManager.loadImage( "images/weather-showers.png" ));
iconList.add(ResourceManager.loadImage( "images/weather-few-clouds.png" ));
iconList.add(ResourceManager.loadImage( "images/weather-clear.png" ));
AnimatedIcon icon = new AnimatedIcon(iconList, 400, 0);
JLabel label = new JLabel(icon);
frame.getContentPane().add( label );
frame.setVisible( true );
}
}

View file

@ -17,9 +17,12 @@ package docking.widgets;
import java.awt.*;
import javax.swing.*;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.border.Border;
import docking.widgets.label.GDHtmlLabel;
/**
* A common base class for list and table renderer objects, unifying the Ghidra look and feel.
* <p>
@ -27,7 +30,7 @@ import javax.swing.border.Border;
* background colors, and highlights the drop target in a drag-n-drop operation.
*
*/
public abstract class AbstractGCellRenderer extends JLabel {
public abstract class AbstractGCellRenderer extends GDHtmlLabel {
private static final Color ALTERNATE_BACKGROUND_COLOR = new Color(237, 243, 254);
@ -46,9 +49,6 @@ public abstract class AbstractGCellRenderer extends JLabel {
return !Boolean.parseBoolean(disable);
}
// taken from BasicHTML.htmlDisable, which is private
protected static final String HTML_DISABLE_STRING = "html.disable";
protected final Border focusBorder;
protected final Border noFocusBorder;
protected Font defaultFont;
@ -73,17 +73,6 @@ public abstract class AbstractGCellRenderer extends JLabel {
setOpaque(true); // mimic the default table & list cell renderer
}
/**
* Enables and disables the rendering of HTML content in this renderer. If enabled, this
* renderer will interpret HTML content when the text this renderer is showing begins with
* <tt>&lt;html&gt;</tt>
*
* @param enable true to enable HTML rendering; false to disable it
*/
public void setHTMLRenderingEnabled(boolean enable) {
putClientProperty(HTML_DISABLE_STRING, !enable);
}
public void setShouldAlternateRowBackgroundColors(boolean alternate) {
this.instanceAlternateRowColors = alternate;
}
@ -170,15 +159,6 @@ public abstract class AbstractGCellRenderer extends JLabel {
return boldFont;
}
/**
* Return the cell renderer text
* @param value Cell object value
* @return A string interpretation of value; generated by calling value.toString()
*/
protected String getText(Object value) {
return value == null ? "" : value.toString();
}
protected static Color getBackgroundColorForRow(int row) {
if ((row & 1) == 1) {

View file

@ -15,11 +15,11 @@
*/
package docking.widgets;
import java.awt.Component;
import java.util.*;
import javax.swing.*;
import javax.swing.ListCellRenderer;
import docking.widgets.list.GListCellRenderer;
import ghidra.util.datastruct.CaseInsensitiveDuplicateStringComparator;
public class DefaultDropDownSelectionDataModel<T> implements DropDownTextFieldDataModel<T> {
@ -29,19 +29,21 @@ public class DefaultDropDownSelectionDataModel<T> implements DropDownTextFieldDa
private ObjectStringComparator comparator;
private DataToStringConverter<T> searchConverter;
private DataToStringConverter<T> descriptionConverter;
private ListCellRenderer<T> renderer = new TDropDownRenderer();
private ListCellRenderer<T> renderer =
GListCellRenderer.createDefaultCellTextRenderer(value -> searchConverter.getString(value));
public static DefaultDropDownSelectionDataModel<String> getStringModel(List<String> strings) {
return new DefaultDropDownSelectionDataModel<String>(strings,
return new DefaultDropDownSelectionDataModel<>(strings,
DataToStringConverter.stringDataToStringConverter);
}
public DefaultDropDownSelectionDataModel(List<T> data, DataToStringConverter<T> searchConverter) {
public DefaultDropDownSelectionDataModel(List<T> data,
DataToStringConverter<T> searchConverter) {
this(data, searchConverter, null);
}
public DefaultDropDownSelectionDataModel(List<T> data,
DataToStringConverter<T> searchConverter, DataToStringConverter<T> descriptionConverter) {
public DefaultDropDownSelectionDataModel(List<T> data, DataToStringConverter<T> searchConverter,
DataToStringConverter<T> descriptionConverter) {
this.data = data;
this.searchConverter = searchConverter;
this.descriptionConverter =
@ -136,23 +138,4 @@ public class DefaultDropDownSelectionDataModel<T> implements DropDownTextFieldDa
}
}
/**
* Renderer for data types. It uses delegation instead of inheritance, due typing issues
* (DefaultListCellRenderer is already typed on Object).
*/
private class TDropDownRenderer implements ListCellRenderer<T> {
private DefaultListCellRenderer delegate = new DefaultListCellRenderer();
@Override
public Component getListCellRendererComponent(JList<? extends T> list, T value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel label =
(JLabel) delegate.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
label.setText(searchConverter.getString(value));
return label;
}
}
}

View file

@ -26,6 +26,8 @@ import javax.swing.event.*;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.list.GList;
import generic.util.WindowUtilities;
import ghidra.util.StringUtilities;
import ghidra.util.SystemUtilities;
@ -56,7 +58,7 @@ import util.CollectionUtils;
*
* @param <T> The type of object that this model manipulates
*/
public class DropDownTextField<T> extends JTextField {
public class DropDownTextField<T> extends JTextField implements GComponent {
private static final int DEFAULT_MAX_UPDATE_DELAY = 2000;
private static final int MIN_HEIGHT = 300;
@ -68,8 +70,8 @@ public class DropDownTextField<T> extends JTextField {
private DropDownWindowVisibilityListener<T> windowVisibilityListener =
new DropDownWindowVisibilityListener<>();
private JLabel previewLabel;
protected JList<T> list = new JList<>();
private GDHtmlLabel previewLabel;
protected GList<T> list = new GList<>();
private WeakSet<DropDownSelectionChoiceListener<T>> choiceListeners =
WeakDataStructureFactory.createSingleThreadAccessWeakSet();
private Collection<CellEditorListener> cellEditorListeners = new HashSet<>();
@ -154,7 +156,7 @@ public class DropDownTextField<T> extends JTextField {
}
protected void setPreviewPaneAttributes() {
previewLabel = new JLabel();
previewLabel = new GDHtmlLabel();
previewLabel.setOpaque(true);
previewLabel.setBackground(TOOLTIP_WINDOW_BGCOLOR);
previewLabel.setVerticalAlignment(SwingConstants.TOP);

View file

@ -23,7 +23,9 @@ import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import docking.DialogComponentProvider;
import docking.widgets.button.GRadioButton;
import docking.widgets.combobox.GhidraComboBox;
import docking.widgets.label.GLabel;
public class FindDialog extends DialogComponentProvider {
@ -62,8 +64,8 @@ public class FindDialog extends DialogComponentProvider {
private JPanel buildMainPanel() {
ButtonGroup formatGroup = new ButtonGroup();
stringRadioButton = new JRadioButton("String", true);
regexRadioButton = new JRadioButton("Regular Expression", false);
stringRadioButton = new GRadioButton("String", true);
regexRadioButton = new GRadioButton("Regular Expression", false);
formatGroup.add(stringRadioButton);
formatGroup.add(regexRadioButton);
@ -97,7 +99,7 @@ public class FindDialog extends DialogComponentProvider {
}
});
JLabel findLabel = new JLabel("Find: ");
JLabel findLabel = new GLabel("Find: ");
// associate this label with a mnemonic key that activates the text field
findLabel.setDisplayedMnemonic(KeyEvent.VK_N);

View file

@ -0,0 +1,77 @@
/* ###
* 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 docking.widgets;
import javax.swing.JComponent;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.label.GLabel;
import ghidra.util.Msg;
import utilities.util.reflection.ReflectionUtilities;
public interface GComponent {
// taken from BasicHTML.htmlDisable, which is private
public static final String HTML_DISABLE_STRING = "html.disable";
/**
* Enables and disables the rendering of HTML content in this component. If enabled, this
* component will interpret HTML content when the text this component is showing begins with
* <tt>&lt;html&gt;</tt>
*
* @param enable true to enable HTML rendering; false to disable it
*/
public default void setHTMLRenderingEnabled(boolean enabled) {
setHTMLRenderingFlag((JComponent) this, enabled);
}
/**
* Returns the current HTML rendering 'enable-ment' of this component.
*
* @return boolean, true if HTML rendering is allowed
*/
public default boolean getHTMLRenderingEnabled() {
Object prop = ((JComponent) this).getClientProperty(HTML_DISABLE_STRING);
return prop == null || prop != Boolean.TRUE;
}
/**
* Helper function that logs a warning about a string text that looks like it has HTML text.
* <p>
* Use this when working with a string in a label that has already disabled HTML rendering.
* <p>
* @param text string to test for HTML and warn about
*/
public static void warnAboutHtmlText(String text) {
// #ifdef still_finding_html_labels_in_our_huge_codebase
if (StringUtils.startsWithIgnoreCase(text, "<html>")) {
Msg.warn(GLabel.class, "HTML text detected in non-HTML component: " + text,
ReflectionUtilities.createJavaFilteredThrowable());
}
// #endif
}
/**
* Sets the HTML rendering flag for the specified component.
*
* @param comp the thing
* @param enabled boolean, if true html rendering will be allowed
*/
public static void setHTMLRenderingFlag(JComponent comp, boolean enabled) {
comp.putClientProperty(HTML_DISABLE_STRING, enabled ? null : true);
}
}

View file

@ -25,6 +25,7 @@ import javax.swing.*;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.options.editor.ButtonPanelFactory;
import docking.widgets.label.GLabel;
import docking.widgets.table.AbstractGTableModel;
import docking.widgets.table.RowObjectTableModel;
@ -60,7 +61,7 @@ public class ListSelectionDialog<T> extends DialogComponentProvider {
this.data = data;
this.searchConverter = searchConverter;
this.descriptionConverter = descriptionConverter;
DefaultDropDownSelectionDataModel<T> model = new DefaultDropDownSelectionDataModel<T>(
DefaultDropDownSelectionDataModel<T> model = new DefaultDropDownSelectionDataModel<>(
new ArrayList<>(data), searchConverter, descriptionConverter) {
// overridden to return all data for an empty search; this lets the down-arrow
@ -112,7 +113,7 @@ public class ListSelectionDialog<T> extends DialogComponentProvider {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(40, 40, 30, 40));
field = new DropDownSelectionTextField<T>(model) {
field = new DropDownSelectionTextField<>(model) {
// overridden to return all data for an empty search; this lets the down-arrow
// show the full list
@ -128,7 +129,7 @@ public class ListSelectionDialog<T> extends DialogComponentProvider {
selectionListener = new SelectionListener<>();
field.addDropDownSelectionChoiceListener(selectionListener);
JLabel jLabel = new JLabel(label);
JLabel jLabel = new GLabel(label);
jLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 20));
panel.add(jLabel, BorderLayout.WEST);
panel.add(field, BorderLayout.CENTER);

View file

@ -29,7 +29,9 @@ import utilities.util.reflection.ReflectionUtilities;
*
* Class to render a String that has new line characters as a multiline
* label. Calculates the resizing and centering characteristics.
*
* <p>
* Not affected by HTML formatting.
* <p>
*/
public class MultiLineLabel extends JPanel {

View file

@ -24,7 +24,10 @@ import javax.swing.*;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.dialogs.*;
import docking.widgets.label.GHtmlLabel;
import docking.widgets.label.GIconLabel;
import ghidra.util.HTMLUtilities;
import ghidra.util.Msg;
import ghidra.util.exception.AssertException;
@ -262,11 +265,11 @@ public class OptionDialog extends DialogComponentProvider {
private JPanel buildRememberOptionChoicePanel(DialogRememberOption rememberOptionChoice) {
if (rememberOptionChoice == null) {
this.rememberOption = new DoNothingDialogRememberOption();
rememberOptionCheckBox = new JCheckBox(); // to prevent null checks, create dummy checkbox
rememberOptionCheckBox = new GCheckBox(); // to prevent null checks, create dummy checkbox
return null;
}
this.rememberOption = rememberOptionChoice;
rememberOptionCheckBox = new JCheckBox(rememberOptionChoice.getDescription());
rememberOptionCheckBox = new GCheckBox(rememberOptionChoice.getDescription());
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
@ -276,14 +279,10 @@ public class OptionDialog extends DialogComponentProvider {
private JPanel buildMessagePanel(String message, int messageType, Icon icon) {
JPanel panel = new JPanel(new BorderLayout());
JLabel iconLabel = new JLabel();
if (icon == null) {
icon = getIconForMessageType(messageType);
}
iconLabel.setIcon(icon);
JPanel textPanel = createTextPanel(message);
textPanel.setMaximumSize(textPanel.getPreferredSize());
panel.add(iconLabel, BorderLayout.WEST);
panel.add(new GIconLabel((icon == null) ? getIconForMessageType(messageType) : icon),
BorderLayout.WEST);
panel.add(textPanel, BorderLayout.CENTER);
return panel;
}
@ -364,7 +363,7 @@ public class OptionDialog extends DialogComponentProvider {
this.dialogMessage = message;
if (HTMLUtilities.isHTML(dialogMessage)) {
JLabel messageLabel = new JLabel(dialogMessage);
JLabel messageLabel = new GHtmlLabel(dialogMessage);
messageLabel.setName(MESSAGE_COMPONENT_NAME);
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,10 +15,6 @@
*/
package docking.widgets;
import ghidra.util.MessageType;
import ghidra.util.Msg;
import ghidra.util.layout.PairLayout;
import java.awt.Toolkit;
import java.awt.event.*;
import java.util.Arrays;
@ -27,6 +22,10 @@ import java.util.Arrays;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.widgets.label.GLabel;
import ghidra.util.MessageType;
import ghidra.util.Msg;
import ghidra.util.layout.PairLayout;
public class PasswordChangeDialog extends DialogComponentProvider {
@ -45,33 +44,34 @@ public class PasswordChangeDialog extends DialogComponentProvider {
wp.setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10));
if (serverName != null) {
wp.add(new JLabel(serverType + ":"));
wp.add(new JLabel(serverName));
wp.add(new GLabel(serverType + ":"));
wp.add(new GLabel(serverName));
}
if (userID != null) {
wp.add(new JLabel("User ID:"));
JLabel nameLabel = new JLabel(userID);
wp.add(new GLabel("User ID:"));
JLabel nameLabel = new GLabel(userID);
nameLabel.setName("NAME-COMPONENT");
wp.add(nameLabel);
}
wp.add(new JLabel("New Password:"));
wp.add(new GLabel("New Password:"));
passwordField1 = new JPasswordField(16);
passwordField1.setName("PASSWORD-ENTRY1-COMPONENT");
wp.add(passwordField1);
wp.add(new JLabel("Repeat Password:"));
wp.add(new GLabel("Repeat Password:"));
passwordField2 = new JPasswordField(16);
passwordField2.setName("PASSWORD-ENTRY2-COMPONENT");
passwordField2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
okCallback();
}
});
wp.add(passwordField2);
wp.add(new JLabel());
wp.add(new GLabel());
KeyListener keyListener = new KeyListener() {

View file

@ -21,6 +21,9 @@ import java.awt.event.*;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GLabel;
import ghidra.util.MessageType;
import ghidra.util.layout.PairLayout;
@ -56,14 +59,14 @@ public class PasswordDialog extends DialogComponentProvider {
int defaultChoice, boolean includeAnonymousOption) {
this(title, serverType, serverName, passPrompt, namePrompt, defaultUserID);
if (choicePrompt != null) {
workPanel.add(new JLabel(choicePrompt));
choiceCB = new JComboBox<>(choices);
workPanel.add(new GLabel(choicePrompt));
choiceCB = new GComboBox<>(choices);
choiceCB.setName("CHOICES-COMPONENT");
choiceCB.setSelectedIndex(defaultChoice);
workPanel.add(choiceCB);
}
if (includeAnonymousOption) {
anonymousAccess = new JCheckBox("Request Anonymous Access");
anonymousAccess = new GCheckBox("Request Anonymous Access");
anonymousAccess.setName("ANONYMOUS-COMPONENT");
anonymousAccess.addChangeListener(e -> {
boolean anonymousAccessRequested = anonymousAccess.isSelected();
@ -79,7 +82,7 @@ public class PasswordDialog extends DialogComponentProvider {
choiceCB.setEnabled(enableOtherFields);
}
});
workPanel.add(new JLabel(""));
workPanel.add(new GLabel(""));
workPanel.add(anonymousAccess);
}
}
@ -124,24 +127,24 @@ public class PasswordDialog extends DialogComponentProvider {
workPanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10));
if (serverName != null) {
workPanel.add(new JLabel(serverType + ":"));
workPanel.add(new JLabel(serverName));
workPanel.add(new GLabel(serverType + ":"));
workPanel.add(new GLabel(serverName));
}
if (namePrompt != null) {
workPanel.add(new JLabel(namePrompt));
workPanel.add(new GLabel(namePrompt));
nameField = new JTextField(defaultUserID, 16);
nameField.setName("NAME-ENTRY-COMPONENT");
workPanel.add(nameField);
}
else if (defaultUserID != null) {
workPanel.add(new JLabel("User ID:"));
JLabel nameLabel = new JLabel(defaultUserID);
workPanel.add(new GLabel("User ID:"));
JLabel nameLabel = new GLabel(defaultUserID);
nameLabel.setName("NAME-COMPONENT");
workPanel.add(nameLabel);
}
workPanel.add(new JLabel(passPrompt != null ? passPrompt : "Password:"));
workPanel.add(new GLabel(passPrompt != null ? passPrompt : "Password:"));
passwordField = new JPasswordField(16);
passwordField.setName("PASSWORD-ENTRY-COMPONENT");
workPanel.add(passwordField);

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,7 +19,8 @@ import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.Scrollable;
/**
* A panel that is scrollable and uses a VariableHeightLayoutManager that
@ -155,31 +155,6 @@ public class VariableHeightPanel extends JPanel implements Scrollable {
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 20;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = frame.getContentPane();
c.setLayout(new BorderLayout());
JPanel panel = new VariableHeightPanel(false, 10, 0);
JButton button = new JButton("Not Lined Up");
c.add(panel, BorderLayout.NORTH);
JPanel p = new JPanel();
p.setBorder(BorderFactory.createLineBorder(Color.RED));
p.setBackground(Color.RED);
c.add(p, BorderLayout.CENTER);
for (int i = 0; i < 20; i++) {
JLabel l = new JLabel("label " + i);
panel.add(l);
}
c.add(button, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
}
}
//==================================================================================================
@ -239,8 +214,8 @@ class VariableHeightLayoutManager implements LayoutManager {
width += d.width;
}
return new Dimension(width + insets.left + insets.right, height + insets.top +
insets.bottom);
return new Dimension(width + insets.left + insets.right,
height + insets.top + insets.bottom);
}
// This preferred size returns Dimension based upon the rows and columns of components that
@ -334,7 +309,8 @@ class VariableHeightLayoutManager implements LayoutManager {
}
// isolates the preferred size, which varies depending upon the type of layout we are mocking
private Dimension getPreferredDimensionForComponent(Component component, Dimension standardSize) {
private Dimension getPreferredDimensionForComponent(Component component,
Dimension standardSize) {
Dimension preferredDimension = component.getPreferredSize();

View file

@ -0,0 +1,118 @@
/* ###
* 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 docking.widgets.button;
import javax.swing.*;
import docking.widgets.GComponent;
/**
* A {@link JRadioButton} that disables HTML rendering.
*
*/
public class GRadioButton extends JRadioButton implements GComponent {
/**
* Creates a blank radio button with HTML rendering disabled.
*/
public GRadioButton() {
super();
init();
}
/**
* Creates a radio button with the specified icon, with HTML rendering disabled.
*
* @param icon image to display
*/
public GRadioButton(Icon icon) {
super(icon);
init();
}
/**
* Creates a radio button with properties taken from the specified Action, with HTML rendering
* disabled.
*
* @param a {@link Action}
*/
public GRadioButton(Action a) {
super(a);
init();
}
/**
* Creates a radio button with the specified icon and selected state, with HTML rendering
* disabled.
*
* @param icon image to display
* @param selected initial selection state, true means selected
*/
public GRadioButton(Icon icon, boolean selected) {
super(icon, selected);
init();
}
/**
* Creates a radio button with the specified text, with HTML rendering disabled.
*
* @param text string to be displayed by the label
*/
public GRadioButton(String text) {
super(text);
init();
}
/**
* Creates a radio button with the specified text and selected state, with HTML rendering
* disabled.
*
* @param text string to be displayed by the label
* @param selected initial selection state, true means selected
*/
public GRadioButton(String text, boolean selected) {
super(text, selected);
init();
}
/**
* Creates a radio button that has the specified text and icon, with HTML rendering disabled.
*
* @param text string to be displayed by the label
* @param icon image to display
*/
public GRadioButton(String text, Icon icon) {
super(text, icon);
init();
}
/**
* Creates a radio button that has the specified text, icon, and selected state, with
* HTML rendering disabled.
*
* @param text string to be displayed by the label
* @param icon image to display
* @param selected initial selection state, true means selected
*/
public GRadioButton(String text, Icon icon, boolean selected) {
super(text, icon, selected);
init();
}
private void init() {
setHTMLRenderingEnabled(false);
}
}

View file

@ -0,0 +1,151 @@
/* ###
* 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 docking.widgets.checkbox;
import javax.swing.*;
import docking.widgets.GComponent;
/**
* A {@link JCheckBox} that has HTML rendering disabled.
* <p>
* See also:
* <table border=1>
* <tr><th>Class</th><th>HTML rendering</th><th>Description</th></tr>
* <tr><td>{@link GCheckBox}</td><td>NO</td><td>HTML disabled JCheckBox</td></tr>
* <tr><td>{@link GHtmlCheckBox}</td><td>YES</td><td>HTML allowed JCheckBox</td></tr>
* </table>
*/
public class GCheckBox extends JCheckBox implements GComponent {
/**
* Creates a check box with no text or icon, with HTML rendering disabled.
* <p>
* See {@link JCheckBox#JCheckBox()}
* <p>
*/
public GCheckBox() {
super();
init();
}
/**
* Creates a check box with an icon, with HTML rendering disabled.
* <p>
* See {@link JCheckBox#JCheckBox(Icon)}
* <p>
*
* @param icon image to display
*/
public GCheckBox(Icon icon) {
super(icon);
init();
}
/**
* Creates a check box with an icon and initial selected state, with HTML rendering disabled.
* <p>
* See {@link JCheckBox#JCheckBox(Icon, boolean)}
* <p>
*
* @param icon image to display
* @param selected initial selection state, true means selected
*/
public GCheckBox(Icon icon, boolean selected) {
super(icon, selected);
init();
}
/**
* Creates a check box with the specified text, with HTML rendering disabled.
* <p>
* See {@link JCheckBox#JCheckBox(String)}
* <p>
*
* @param text text of the check box
*/
public GCheckBox(String text) {
super(text);
init();
}
/**
* Creates a check box where properties are taken from the
* Action supplied, with HTML rendering disabled.
* <p>
* See {@link JCheckBox#JCheckBox(Action)}
* <p>
*
* @param a {@code Action} used to specify the new check box
*/
public GCheckBox(Action a) {
super(a);
init();
}
/**
* Creates a check box with the specified text and initial selected state, with HTML
* rendering disabled.
*
* @param text text of the check box.
* @param selected initial selection state, true means selected
*/
public GCheckBox(String text, boolean selected) {
super(text, selected);
init();
}
/**
* Creates a check box with the specified text and icon, with HTML rendering disabled.
*
* @param text text of the check box
* @param icon image to display
*/
public GCheckBox(String text, Icon icon) {
super(text, icon);
init();
}
/**
* Creates a check box with the specified text and icon and initial selected state,
* with HTML rendering disabled.
*
* @param text text of the check box
* @param icon image to display
* @param selected initial selection state, true means selected
*/
public GCheckBox(String text, Icon icon, boolean selected) {
super(text, icon, selected);
init();
}
private void init() {
setHTMLRenderingEnabled(false);
}
/**
* See {@link JCheckBox#setText(String)}.
* <p>
* Overridden to warn about HTML text in non-HTML enabled checkbox.
*
* @param text string this label will display
*/
@Override
public void setText(String text) {
GComponent.warnAboutHtmlText(text);
super.setText(text);
}
}

View file

@ -0,0 +1,127 @@
/* ###
* 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 docking.widgets.checkbox;
import javax.swing.*;
import docking.widgets.GComponent;
/**
* A {@link JCheckBox} that allows HTML rendering.
* <p>
* See also:
* <table border=1>
* <tr><th>Class</th><th>HTML rendering</th><th>Description</th></tr>
* <tr><td>{@link GCheckBox}</td><td>NO</td><td>HTML disabled JCheckBox</td></tr>
* <tr><td>{@link GHtmlCheckBox}</td><td>YES</td><td>HTML allowed JCheckBox</td></tr>
* </table>
*/
public class GHtmlCheckBox extends JCheckBox implements GComponent {
/**
* Creates a check box with no text or icon, with HTML rendering allowed.
* <p>
* See {@link JCheckBox#JCheckBox()}
* <p>
*/
public GHtmlCheckBox() {
super();
}
/**
* Creates a check box with an icon, with HTML rendering allowed.
* <p>
* See {@link JCheckBox#JCheckBox(Icon)}
* <p>
*
* @param icon image to display
*/
public GHtmlCheckBox(Icon icon) {
super(icon);
}
/**
* Creates a check box with an icon and initial selected state, with HTML rendering allowed.
* <p>
* See {@link JCheckBox#JCheckBox(Icon, boolean)}
* <p>
*
* @param icon image to display
* @param selected initial selection state, true means selected
*/
public GHtmlCheckBox(Icon icon, boolean selected) {
super(icon, selected);
}
/**
* Creates a check box with the specified text, with HTML rendering allowed.
* <p>
* See {@link JCheckBox#JCheckBox(String)}
* <p>
*
* @param text text of the check box
*/
public GHtmlCheckBox(String text) {
super(text);
}
/**
* Creates a check box where properties are taken from the
* Action supplied, with HTML rendering allowed.
* <p>
* See {@link JCheckBox#JCheckBox(Action)}
* <p>
*
* @param a {@code Action} used to specify the new check box
*/
public GHtmlCheckBox(Action a) {
super(a);
}
/**
* Creates a check box with the specified text and initial selected state, with HTML
* rendering allowed.
*
* @param text text of the check box.
* @param selected initial selection state, true means selected
*/
public GHtmlCheckBox(String text, boolean selected) {
super(text, selected);
}
/**
* Creates a check box with the specified text and icon, with HTML rendering allowed.
*
* @param text text of the check box
* @param icon image to display
*/
public GHtmlCheckBox(String text, Icon icon) {
super(text, icon);
}
/**
* Creates a check box with the specified text and icon and initial selected state,
* with HTML rendering allowed.
*
* @param text text of the check box
* @param icon image to display
* @param selected initial selection state, true means selected
*/
public GHtmlCheckBox(String text, Icon icon, boolean selected) {
super(text, icon, selected);
}
}

View file

@ -0,0 +1,85 @@
/* ###
* 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 docking.widgets.combobox;
import java.util.Vector;
import javax.swing.*;
import docking.widgets.GComponent;
/**
* A {@link JComboBox} that disables HTML rendering.
*
* @param <E> the type of the elements of this combo box
*/
public class GComboBox<E> extends JComboBox<E> implements GComponent {
/**
* Creates an empty combobox with a default data model.
* <p>
* See {@link JComboBox#JComboBox()}
* <p>
*/
public GComboBox() {
super();
init();
}
/**
* Creates a combobox using the specified model.
* <p>
* See {@link JComboBox#JComboBox(ComboBoxModel)}
* <p>
* @param aModel the {@link ComboBoxModel} of generic type {@code E}
*/
public GComboBox(ComboBoxModel<E> aModel) {
super(aModel);
init();
}
/**
* Creates a combobox using the specified items.
* <p>
* See {@link JComboBox#JComboBox(Object[])}
* <p>
* @param items array of objects of generic type {@code E} to insert into the combo box
*/
public GComboBox(E[] items) {
super(items);
init();
}
/**
* Creates a combobox using the specified items.
* <p>
* See {@link JComboBox#JComboBox(Vector)}
* <p>
* @param items a vector containing objects of generic type {@code E} to insert into the combo box
*/
public GComboBox(Vector<E> items) {
super(items);
init();
}
private void init() {
setHTMLRenderingEnabled(false);
if (getRenderer() instanceof JComponent) {
GComponent.setHTMLRenderingFlag((JComponent) getRenderer(), false);
}
}
}

View file

@ -26,6 +26,8 @@ import javax.swing.event.DocumentListener;
import javax.swing.plaf.ComboBoxUI;
import javax.swing.text.*;
import docking.widgets.GComponent;
/**
* GhidraComboBox adds the following features:
*
@ -54,9 +56,9 @@ import javax.swing.text.*;
* focus) in that you end up changing the button's internal state(by calling
* setEnabled(true or false)) in the middle of the button press.
*/
public class GhidraComboBox<E> extends JComboBox<E> {
private ArrayList<ActionListener> listeners = new ArrayList<ActionListener>();
private ArrayList<DocumentListener> docListeners = new ArrayList<DocumentListener>();
public class GhidraComboBox<E> extends JComboBox<E> implements GComponent {
private ArrayList<ActionListener> listeners = new ArrayList<>();
private ArrayList<DocumentListener> docListeners = new ArrayList<>();
private boolean setSelectedFlag = false;
private boolean forwardEnter;
@ -67,6 +69,7 @@ public class GhidraComboBox<E> extends JComboBox<E> {
*/
public GhidraComboBox() {
super();
init();
}
/**
@ -75,6 +78,7 @@ public class GhidraComboBox<E> extends JComboBox<E> {
*/
public GhidraComboBox(ComboBoxModel<E> aModel) {
super(aModel);
init();
}
/**
@ -84,6 +88,7 @@ public class GhidraComboBox<E> extends JComboBox<E> {
*/
public GhidraComboBox(E[] items) {
super(items);
init();
}
/**
@ -93,6 +98,14 @@ public class GhidraComboBox<E> extends JComboBox<E> {
*/
public GhidraComboBox(Vector<E> items) {
super(items);
init();
}
private void init() {
setHTMLRenderingEnabled(false);
if (getRenderer() instanceof JComponent) {
GComponent.setHTMLRenderingFlag((JComponent) getRenderer(), false);
}
}
@Override

View file

@ -27,6 +27,9 @@ import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import docking.widgets.EmptyBorderButton;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.label.GDLabel;
import ghidra.util.HTMLUtilities;
import ghidra.util.exception.CancelledException;
import ghidra.util.layout.PairLayout;
@ -200,11 +203,11 @@ public class ConditionTestPanel extends JPanel {
private Component createSummaryPanel() {
JPanel panel = new JPanel(new GridLayout(1, 3, 20, 0));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
runsLabel = new JLabel("Tests: 0/" + conditionTestModel.getTestCount());
runsLabel = new GDLabel("Tests: 0/" + conditionTestModel.getTestCount());
panel.add(runsLabel);
errorsLabel = new JLabel("Errors: 0");
errorsLabel = new GDLabel("Errors: 0");
panel.add(errorsLabel);
warningsLabel = new JLabel("Warnings: 0");
warningsLabel = new GDLabel("Warnings: 0");
panel.add(warningsLabel);
return panel;
@ -267,7 +270,7 @@ public class ConditionTestPanel extends JPanel {
// Inner Classes
//==================================================================================================
private class ScrollableLabel extends JLabel implements Scrollable {
private class ScrollableLabel extends GDHtmlLabel implements Scrollable {
@Override
public Dimension getPreferredScrollableViewportSize() {
@ -363,10 +366,10 @@ public class ConditionTestPanel extends JPanel {
backgroundColor = getBackground();
selectedColor = Color.LIGHT_GRAY;
this.test = conditionTest;
checkbox = new JCheckBox();
checkbox = new GCheckBox();
checkbox.setSelected(true);
add(checkbox);
label = new JLabel(test.getName());
label = new GDLabel(test.getName());
add(label);
label.setToolTipText(test.getDescription());
checkbox.addChangeListener(e -> {
@ -404,7 +407,7 @@ public class ConditionTestPanel extends JPanel {
public TestStatusPanel(ConditionTester test) {
super(new BorderLayout());
this.test = test;
label = new JLabel();
label = new GDLabel();
label.setHorizontalAlignment(SwingConstants.LEFT);
add(label);
}

View file

@ -23,6 +23,7 @@ import javax.swing.event.DocumentListener;
import javax.swing.text.*;
import docking.DialogComponentProvider;
import docking.widgets.label.GLabel;
import ghidra.util.layout.PairLayout;
/**
@ -224,7 +225,7 @@ public class InputDialog extends DialogComponentProvider {
textFields[i] = new MyTextField(initialValues[i]);
textFields[i].addKeyListener(keyListener);
textFields[i].setName("input.dialog.text.field." + i);
panel.add(new JLabel(inputLabels[i], SwingConstants.RIGHT));
panel.add(new GLabel(inputLabels[i], SwingConstants.RIGHT));
panel.add(textFields[i]);
}
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

View file

@ -22,6 +22,8 @@ import javax.swing.*;
import docking.DialogComponentProvider;
import docking.widgets.combobox.GhidraComboBox;
import docking.widgets.label.GDLabel;
import docking.widgets.label.GHtmlLabel;
/**
* A dialog that has text fields to get user input.
@ -109,8 +111,7 @@ public class InputWithChoicesDialog extends DialogComponentProvider {
workPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// COMBO BOX PANEL
JLabel messageLabel = new JLabel();
messageLabel.setText(labelText);
JLabel messageLabel = new GHtmlLabel(labelText);
messageLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
combo = createComboBox(optionValues, initialValue);
@ -122,7 +123,7 @@ public class InputWithChoicesDialog extends DialogComponentProvider {
// ICON PANEL (if an icon has been supplied)
if (messageIcon != null) {
JLabel iconLabel = new JLabel();
JLabel iconLabel = new GDLabel();
iconLabel.setIcon(messageIcon);
iconLabel.setVerticalAlignment(SwingConstants.TOP);

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,9 +15,6 @@
*/
package docking.widgets.dialogs;
import ghidra.framework.OperatingSystem;
import ghidra.framework.Platform;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
@ -27,11 +23,15 @@ import javax.swing.*;
import docking.DialogComponentProvider;
import docking.DockingUtils;
import docking.widgets.label.GDLabel;
import docking.widgets.label.GLabel;
import ghidra.framework.OperatingSystem;
import ghidra.framework.Platform;
public class MultiLineInputDialog extends DialogComponentProvider {
private static final KeyStroke SUBMIT_KEYSTROKE = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
DockingUtils.CONTROL_KEY_MODIFIER_MASK);
private static final KeyStroke SUBMIT_KEYSTROKE =
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, DockingUtils.CONTROL_KEY_MODIFIER_MASK);
private boolean isCanceled;
private JTextArea inputTextArea;
@ -71,7 +71,7 @@ public class MultiLineInputDialog extends DialogComponentProvider {
}
inputTextArea.selectAll();
JLabel messageLabel = new JLabel();
JLabel messageLabel = new GDLabel();
messageLabel.setText(messageText);
messageLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
@ -80,7 +80,7 @@ public class MultiLineInputDialog extends DialogComponentProvider {
if (OS == OperatingSystem.MAC_OS_X) {
metaKeyText = "Command";
}
JLabel hintLabel = new JLabel("(" + metaKeyText + "-Enter to accept)");
JLabel hintLabel = new GLabel("(" + metaKeyText + "-Enter to accept)");
hintLabel.setHorizontalAlignment(SwingConstants.CENTER);
Font font = hintLabel.getFont();
Font smallerFont = font.deriveFont(12F);
@ -92,7 +92,7 @@ public class MultiLineInputDialog extends DialogComponentProvider {
dataPanel.add(new JScrollPane(inputTextArea), BorderLayout.CENTER);
dataPanel.add(hintLabel, BorderLayout.SOUTH);
JLabel iconLabel = new JLabel();
JLabel iconLabel = new GDLabel();
iconLabel.setIcon(icon);
iconLabel.setVerticalAlignment(SwingConstants.TOP);

View file

@ -25,6 +25,8 @@ import org.apache.commons.lang3.StringUtils;
import docking.*;
import docking.widgets.OptionDialog;
import docking.widgets.label.GIconLabel;
import docking.widgets.label.GLabel;
import ghidra.util.HTMLUtilities;
public class MultiLineMessageDialog extends DialogComponentProvider {
@ -87,7 +89,7 @@ public class MultiLineMessageDialog extends DialogComponentProvider {
workPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
if (!StringUtils.isBlank(shortMessage)) {
JLabel shortMessageLabel = new JLabel(shortMessage);
JLabel shortMessageLabel = new GLabel(shortMessage);
shortMessageLabel.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 10));
workPanel.add(shortMessageLabel, BorderLayout.NORTH);
}
@ -134,7 +136,7 @@ public class MultiLineMessageDialog extends DialogComponentProvider {
Icon icon = OptionDialog.getIconForMessageType(messageType);
if (icon != null) {
JLabel iconLabel = new JLabel(icon);
JLabel iconLabel = new GIconLabel(icon);
iconLabel.setBorder(BorderFactory.createEmptyBorder(1, 10, 1, 10));
workPanel.add(iconLabel, BorderLayout.WEST);
}

View file

@ -23,6 +23,7 @@ import javax.swing.*;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.widgets.label.GDLabel;
import docking.widgets.textfield.IntegerTextField;
/**
@ -268,7 +269,7 @@ public class NumberInputDialog extends DialogComponentProvider {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
label = new JLabel(prompt);
label = new GDLabel(prompt);
numberInputField = new IntegerTextField(12);
numberInputField.addChangeListener(e -> updateOKButtonEnablement());

View file

@ -25,6 +25,8 @@ import javax.swing.table.*;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.combobox.GComboBox;
import docking.widgets.table.DefaultSortedTableModel;
import docking.widgets.table.GTable;
import ghidra.docking.settings.*;
@ -223,15 +225,15 @@ public class SettingsDialog extends DialogComponentProvider {
}
private class SettingsEditor extends AbstractCellEditor implements TableCellEditor,
PopupMenuListener {
private class SettingsEditor extends AbstractCellEditor
implements TableCellEditor, PopupMenuListener {
final static int ENUM = 0;
final static int BOOLEAN = 1;
private int mode;
private JComboBox comboBox = new JComboBox();
private JCheckBox checkBox = new JCheckBox();
private GComboBox<String> comboBox = new GComboBox<>();
private GCheckBox checkBox = new GCheckBox();
private final Runnable editStopped = new Runnable() {
@Override
@ -254,7 +256,7 @@ public class SettingsDialog extends DialogComponentProvider {
case ENUM:
return getComboBoxEnum();
case BOOLEAN:
return new Boolean(checkBox.isSelected());
return Boolean.valueOf(checkBox.isSelected());
}
throw new AssertException();
}
@ -262,7 +264,7 @@ public class SettingsDialog extends DialogComponentProvider {
private StringChoices getComboBoxEnum() {
String[] items = new String[comboBox.getItemCount()];
for (int i = 0; i < items.length; i++) {
items[i] = (String) comboBox.getItemAt(i);
items[i] = comboBox.getItemAt(i);
}
StringChoices choices = new StringChoices(items);
choices.setSelectedValue(comboBox.getSelectedIndex());
@ -273,8 +275,8 @@ public class SettingsDialog extends DialogComponentProvider {
* @see javax.swing.table.TableCellEditor#getTableCellEditorComponent(javax.swing.JTable, java.lang.Object, boolean, int, int)
*/
@Override
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
int row, int column) {
if (value instanceof StringChoices) {
initComboBox((StringChoices) value);
return comboBox;
@ -283,8 +285,8 @@ public class SettingsDialog extends DialogComponentProvider {
initCheckBox((Boolean) value);
return checkBox;
}
throw new AssertException("SettingsEditor: " + value.getClass().getName() +
" not supported");
throw new AssertException(
"SettingsEditor: " + value.getClass().getName() + " not supported");
}
private void initCheckBox(Boolean b) {

View file

@ -27,6 +27,7 @@ import java.util.List;
import javax.swing.*;
import docking.event.mouse.GMouseListenerAdapter;
import docking.widgets.label.GDLabel;
import docking.widgets.list.GList;
import ghidra.util.exception.AssertException;
@ -121,7 +122,7 @@ class DirectoryList extends GList<File> implements GhidraFileChooserDirectoryMod
updateChooserForSelection();
});
listEditorLabel = new JLabel();
listEditorLabel = new GDLabel();
listEditorLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {

View file

@ -15,8 +15,6 @@
*/
package docking.widgets.filechooser;
import ghidra.util.exception.AssertException;
import java.awt.Component;
import java.io.File;
import java.util.*;
@ -24,8 +22,11 @@ import java.util.*;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import docking.widgets.DropDownTextFieldDataModel;
import docking.widgets.DropDownSelectionTextField;
import docking.widgets.DropDownTextFieldDataModel;
import docking.widgets.list.GListCellRenderer;
import ghidra.util.HTMLUtilities;
import ghidra.util.exception.AssertException;
/**
* A model that allows the {@link DropDownSelectionTextField} to work with File objects.
@ -93,7 +94,7 @@ public class FileDropDownSelectionDataModel implements DropDownTextFieldDataMode
if (files == null) {
return Collections.emptyList();
}
List<File> list = new ArrayList<File>();
List<File> list = new ArrayList<>();
for (File file : files) {
list.add(file);
}
@ -126,8 +127,8 @@ public class FileDropDownSelectionDataModel implements DropDownTextFieldDataMode
public String getDescription(File file) {
boolean isDir = file.isDirectory();
return "<html><table>" + "<tr><td>" + (isDir ? "Directory: " : "File: ") + "</td><td>" +
"<b>" + file.getName() + "</b>" + "</td></tr>" + "<tr><td>Size:</td><td>" +
(isDir ? "0" : file.length()) + " bytes" + "</td></tr>" +
"<b>" + HTMLUtilities.escapeHTML(file.getName()) + "</b>" + "</td></tr>" +
"<tr><td>Size:</td><td>" + (isDir ? "0" : file.length()) + " bytes" + "</td></tr>" +
"<tr><td>Last modified:</td><td>" +
GhidraFileChooser.format.format(new Date(file.lastModified())) + "</td></tr>" +
"</table>";
@ -155,30 +156,23 @@ public class FileDropDownSelectionDataModel implements DropDownTextFieldDataMode
}
}
/**
* Renderer for data types. It uses delegation instead of inheritance, due typing issues
* (DefaultListCellRenderer is already typed on Object).
*/
private class FileDropDownRenderer implements ListCellRenderer<File> {
private DefaultListCellRenderer delegate = new DefaultListCellRenderer();
private class FileDropDownRenderer extends GListCellRenderer<File> {
@Override
public Component getListCellRendererComponent(JList<? extends File> list, File value,
protected String getItemText(File file) {
return file.getName();
}
@Override
public Component getListCellRendererComponent(JList<? extends File> list, File file,
int index, boolean isSelected, boolean cellHasFocus) {
JLabel renderer =
(JLabel) delegate.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
super.getListCellRendererComponent(list, file, index, isSelected, cellHasFocus);
File file = value;
renderer.setText(file.getName());
setIcon(fileSystemView.getSystemIcon(file));
setVerticalAlignment(SwingConstants.TOP);
renderer.setIcon(fileSystemView.getSystemIcon(file));
renderer.setVerticalAlignment(SwingConstants.TOP);
return renderer;
return this;
}
}

View file

@ -15,9 +15,6 @@
*/
package docking.widgets.filechooser;
import ghidra.util.Msg;
import ghidra.util.filechooser.GhidraFileChooserModel;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
@ -26,6 +23,10 @@ import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.table.TableCellEditor;
import docking.widgets.label.GDLabel;
import ghidra.util.Msg;
import ghidra.util.filechooser.GhidraFileChooserModel;
class FileEditor extends AbstractCellEditor implements TableCellEditor {
private GhidraFileChooser chooser;
@ -43,7 +44,7 @@ class FileEditor extends AbstractCellEditor implements TableCellEditor {
this.directoryTable = table;
this.model = model;
iconLabel = new JLabel();
iconLabel = new GDLabel();
iconLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
@ -97,8 +98,9 @@ class FileEditor extends AbstractCellEditor implements TableCellEditor {
editor.add(nameField, BorderLayout.CENTER);
// match the spacing of non-editing cells
editor.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(0, 5, 0, 0), BorderFactory.createLineBorder(Color.GRAY)));
editor.setBorder(
BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0),
BorderFactory.createLineBorder(Color.GRAY)));
}
private void handleDoubleClick(Point p) {
@ -144,15 +146,14 @@ class FileEditor extends AbstractCellEditor implements TableCellEditor {
private File getNewFile() {
GhidraFileChooserModel fileChooserModel = chooser.getModel();
File newFile =
new GhidraFile(originalFile.getParentFile(), nameField.getText(),
fileChooserModel.getSeparator());
File newFile = new GhidraFile(originalFile.getParentFile(), nameField.getText(),
fileChooserModel.getSeparator());
if (fileChooserModel.renameFile(originalFile, newFile)) {
return newFile;
}
Msg.showError(this, chooser.getComponent(), "Rename Failed", "Unable to rename file: " +
originalFile);
Msg.showError(this, chooser.getComponent(), "Rename Failed",
"Unable to rename file: " + originalFile);
return null;
}
}

View file

@ -18,11 +18,12 @@ package docking.widgets.filechooser;
import java.awt.Component;
import java.io.File;
import javax.swing.*;
import javax.swing.JList;
import docking.widgets.list.GListCellRenderer;
import ghidra.util.filechooser.GhidraFileChooserModel;
class FileListCellRenderer extends DefaultListCellRenderer {
class FileListCellRenderer extends GListCellRenderer<File> {
private GhidraFileChooser chooser;
private GhidraFileChooserModel model;
@ -33,18 +34,18 @@ class FileListCellRenderer extends DefaultListCellRenderer {
}
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
protected String getItemText(File file) {
return chooser.getDisplayName(file);
}
@Override
public Component getListCellRendererComponent(JList<? extends File> list, File file, int index,
boolean isSelected, boolean cellHasFocus) {
File file = (File) value;
Component c = super.getListCellRendererComponent(list, chooser.getDisplayName(file), index,
isSelected, cellHasFocus);
if (c instanceof JLabel) {
((JLabel) c).setIcon(model.getIcon(file));
}
return c;
super.getListCellRendererComponent(list, file, index, isSelected, cellHasFocus);
setIcon(model.getIcon(file));
return this;
}
}

View file

@ -18,6 +18,8 @@ package docking.widgets.filechooser;
import javax.swing.*;
import docking.DialogComponentProvider;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GLabel;
import ghidra.framework.preferences.Preferences;
import ghidra.util.layout.PairLayout;
@ -47,10 +49,10 @@ class GFileChooserOptionsDialog extends DialogComponentProvider {
private JComponent buildComponent() {
JPanel panel = new JPanel(new PairLayout());
showDotFilesCheckBox = new JCheckBox();
showDotFilesCheckBox = new GCheckBox();
showDotFilesCheckBox.setSelected(true);
JLabel label = new JLabel("Show '.' files");
JLabel label = new GLabel("Show '.' files");
label.setToolTipText("When toggled on the file chooser will show files " +
"with names that begin with a '.' character");

View file

@ -32,6 +32,10 @@ import javax.swing.filechooser.FileSystemView;
import docking.*;
import docking.framework.DockingApplicationConfiguration;
import docking.widgets.*;
import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GDLabel;
import docking.widgets.label.GLabel;
import docking.widgets.list.GListCellRenderer;
import ghidra.GhidraApplicationLayout;
import ghidra.framework.*;
import ghidra.framework.preferences.Preferences;
@ -354,7 +358,7 @@ public class GhidraFileChooser extends DialogComponentProvider
}
private JPanel buildFileNamePanel() {
JLabel filenameLabel = new JLabel("File name:");
JLabel filenameLabel = new GDLabel("File name:");
FileDropDownSelectionDataModel model = new FileDropDownSelectionDataModel(this);
filenameTextField = new DropDownSelectionTextField<>(model);
filenameTextField.setMatchingWindowHeight(200);
@ -383,28 +387,10 @@ public class GhidraFileChooser extends DialogComponentProvider
filenameTextField.setName("filenameTextField");
JLabel filterLabel = new JLabel("Type:");
filterCombo = new JComboBox<>();
filterCombo.setRenderer(new DefaultListCellRenderer() {
private static final long serialVersionUID = 1L;
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
GhidraFileFilter filter = (GhidraFileFilter) value;
// we can have null filters in the case that the combo box has
// no selected item
if (filter != null) {
label.setText(filter.getDescription());
}
return label;
}
});
JLabel filterLabel = new GLabel("Type:");
filterCombo = new GComboBox<>();
filterCombo.setRenderer(GListCellRenderer.createDefaultCellTextRenderer(
gff -> gff != null ? gff.getDescription() : ""));
filterCombo.addItemListener(e -> rescanCurrentDirectory());
filterModel = (DefaultComboBoxModel<GhidraFileFilter>) filterCombo.getModel();

View file

@ -28,6 +28,7 @@ import javax.swing.event.DocumentListener;
import docking.dnd.DropTgtAdapter;
import docking.dnd.Droppable;
import docking.widgets.OptionDialog;
import docking.widgets.label.GLabel;
import ghidra.framework.preferences.Preferences;
import ghidra.util.filechooser.GhidraFileFilter;
@ -157,7 +158,7 @@ public class GhidraFileChooserPanel extends JPanel implements Droppable {
gbc.gridy = 0;
if (!createBorder && title != null) {
add(new JLabel(title), gbc);
add(new GLabel(title), gbc);
}
gbc.fill = GridBagConstraints.HORIZONTAL;

View file

@ -28,6 +28,7 @@ import org.jdesktop.animation.timing.TimingTargetAdapter;
import org.jdesktop.animation.timing.interpolation.PropertySetter;
import docking.util.AnimationUtils;
import docking.widgets.label.GIconLabel;
import ghidra.util.SystemUtilities;
import resources.Icons;
import resources.ResourceManager;
@ -36,7 +37,7 @@ import resources.ResourceManager;
* A label that displays an icon that, when clicked, will clear the contents of the
* associated filter.
*/
public class ClearFilterLabel extends JLabel {
public class ClearFilterLabel extends GIconLabel {
private Icon RAW_ICON = Icons.DELETE_ICON;
private Icon ICON = ResourceManager.getScaledIcon(RAW_ICON, 10, 10);

View file

@ -67,6 +67,14 @@ public class FilterOptions {
.sorted()
.map(c -> Character.toString(c))
.collect(Collectors.joining(""));
public static final String[] VALID_MULTITERM_DELIMITERS_ARRAY =
DELIMITER_NAME_MAP.keySet()
.stream()
.sorted()
.map(c -> Character.toString(c))
.collect(Collectors.toList())
.toArray(new String[DELIMITER_NAME_MAP.size()]);
// @formatter:on
public static final Character DEFAULT_DELIMITER = ',';

View file

@ -27,6 +27,11 @@ import javax.swing.border.EmptyBorder;
import docking.DialogComponentProvider;
import docking.DisabledComponentLayerFactory;
import docking.widgets.InlineComponentTitledPanel;
import docking.widgets.button.GRadioButton;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GIconLabel;
import docking.widgets.label.GLabel;
import docking.widgets.list.GListCellRenderer;
import ghidra.util.HelpLocation;
import ghidra.util.layout.*;
@ -144,10 +149,10 @@ public class FilterOptionsEditorDialog extends DialogComponentProvider {
setLayout(new PairLayout(2, 2));
setBorder(BorderFactory.createTitledBorder("Text Filter Strategy"));
ButtonGroup buttonGroup = new ButtonGroup();
JRadioButton startsWithButton = new JRadioButton("Starts With");
JRadioButton containsButton = new JRadioButton("Contains");
JRadioButton matchesExactlyButton = new JRadioButton("Matches Exactly");
JRadioButton regularExpressionButton = new JRadioButton("Regular Expression");
GRadioButton startsWithButton = new GRadioButton("Starts With");
GRadioButton containsButton = new GRadioButton("Contains");
GRadioButton matchesExactlyButton = new GRadioButton("Matches Exactly");
GRadioButton regularExpressionButton = new GRadioButton("Regular Expression");
startsWithButton.setToolTipText(
"The filter will match all entries that start with the entered filter text.");
@ -210,13 +215,13 @@ public class FilterOptionsEditorDialog extends DialogComponentProvider {
}
add(containsButton);
add(new JLabel(FilterOptions.getIcon(TextFilterStrategy.CONTAINS)));
add(new GIconLabel(FilterOptions.getIcon(TextFilterStrategy.CONTAINS)));
add(startsWithButton);
add(new JLabel(FilterOptions.getIcon(TextFilterStrategy.STARTS_WITH)));
add(new GIconLabel(FilterOptions.getIcon(TextFilterStrategy.STARTS_WITH)));
add(matchesExactlyButton);
add(new JLabel(FilterOptions.getIcon(TextFilterStrategy.MATCHES_EXACTLY)));
add(new GIconLabel(FilterOptions.getIcon(TextFilterStrategy.MATCHES_EXACTLY)));
add(regularExpressionButton);
add(new JLabel(FilterOptions.getIcon(TextFilterStrategy.REGULAR_EXPRESSION)));
add(new GIconLabel(FilterOptions.getIcon(TextFilterStrategy.REGULAR_EXPRESSION)));
}
}
@ -263,14 +268,14 @@ public class FilterOptionsEditorDialog extends DialogComponentProvider {
this.setLayout(new HorizontalLayout(6));
setBorder(BorderFactory.createEmptyBorder(10, 4, 0, 4));
caseSensitiveCheckbox = new JCheckBox("Case Sensitive");
caseSensitiveCheckbox = new GCheckBox("Case Sensitive");
caseSensitiveCheckbox.setToolTipText(
"Toggles whether the case of the filter text matters in the match. NOTE: does not apply to regular expressons.");
if (initialFilterOptions.isCaseSensitive()) {
caseSensitiveCheckbox.setSelected(true);
}
globbingCheckbox = new JCheckBox("Allow Globbing");
globbingCheckbox = new GCheckBox("Allow Globbing");
globbingCheckbox.setToolTipText(
"Toggles whether globbing chars (?*) are literal or wildcards");
if (initialFilterOptions.isGlobbingAllowed()) {
@ -305,7 +310,7 @@ public class FilterOptionsEditorDialog extends DialogComponentProvider {
this.setLayout(new HorizontalLayout(6));
setBorder(BorderFactory.createEmptyBorder(10, 4, 10, 4));
invertCheckbox = new JCheckBox("Invert Filter");
invertCheckbox = new GCheckBox("Invert Filter");
invertCheckbox.setToolTipText("<html>" +
"Inverts the match. For example, <i>contains</i> becomes <i>does not contain</i>.");
if (initialFilterOptions.isInverted()) {
@ -334,13 +339,11 @@ public class FilterOptionsEditorDialog extends DialogComponentProvider {
public MultiTermPanel() {
super(new JCheckBox("Enable Multi-Term Filtering"), BorderFactory.createEtchedBorder());
super(new GCheckBox("Enable Multi-Term Filtering", true),
BorderFactory.createEtchedBorder());
enableCheckbox = (JCheckBox) getTitleComponent();
enableCheckbox.setSelected(true);
enableCheckbox.addActionListener(e -> {
setOptionsEnabled(enableCheckbox.isSelected());
});
enableCheckbox.addActionListener(e -> setOptionsEnabled(enableCheckbox.isSelected()));
createPanel();
}
@ -403,22 +406,21 @@ public class FilterOptionsEditorDialog extends DialogComponentProvider {
* Creates the main panel for this dialog.
*/
private void createPanel() {
getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
JPanel outerPanel = new JPanel();
outerPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
JPanel optionsPanel = new JPanel();
optionsPanel.setLayout(new PairLayout());
// Delimiter Row
JLabel delimiterCharacterFieldName = new JLabel("Delimiter:");
JLabel delimiterCharacterFieldName = new GLabel("Delimiter:");
delimiterCharacterFieldName.setToolTipText(
"Set the character used to separate filter terms.");
delimiterCharacterCB =
new JComboBox<String>(FilterOptions.VALID_MULTITERM_DELIMITERS.split("(?!^)"));
delimiterCharacterCB = new GComboBox<>(FilterOptions.VALID_MULTITERM_DELIMITERS_ARRAY);
delimiterCharacterCB.setRenderer(new DelimiterListCellRenderer());
JPanel fixedSizePanel = new JPanel();
@ -429,14 +431,14 @@ public class FilterOptionsEditorDialog extends DialogComponentProvider {
optionsPanel.add(fixedSizePanel);
// Mode Row
JLabel label = new JLabel("Evaluation Mode:");
JLabel label = new GLabel("Evaluation Mode:");
JPanel buttonGroupPanel = new JPanel();
buttonGroupPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
ButtonGroup modeBtnGroup = new ButtonGroup();
MultitermEvaluationMode[] modes = MultitermEvaluationMode.values();
for (MultitermEvaluationMode mode : modes) {
JRadioButton modeRB = new JRadioButton(mode.name());
GRadioButton modeRB = new GRadioButton(mode.name());
modeRB.setToolTipText(mode.getDescription());
modeRB.addActionListener(e -> {
evalMode = MultitermEvaluationMode.valueOf(mode.name());
@ -465,19 +467,13 @@ public class FilterOptionsEditorDialog extends DialogComponentProvider {
}
@Override
protected String getText(Object value) {
String label = "";
char char0 = ((String) value).charAt(0);
label = FilterOptions.DELIMITER_NAME_MAP.get(char0);
if (label == null) {
label = "<i>Unrecognized</i>";
}
protected String getItemText(String value) {
char char0 = value.length() > 0 ? value.charAt(0) : ' ';
String delimiterName =
FilterOptions.DELIMITER_NAME_MAP.getOrDefault(char0, "<i>Unrecognized</i>");
return String.format("<html><font face=monospace>%s</font> &nbsp;&nbsp; <i>%s</i>",
char0 == ' ' ? "&nbsp;" : char0, label);
char0 == ' ' ? "&nbsp;" : char0, delimiterName);
}
}
}

View file

@ -22,6 +22,7 @@ import java.util.Arrays;
import javax.swing.*;
import docking.widgets.label.GIconLabel;
import resources.icons.EmptyIcon;
/**
@ -501,7 +502,7 @@ public class ImagePanel extends JPanel {
translateEnabled = enabled;
}
private class PanAndZoomComponent extends JLabel {
private class PanAndZoomComponent extends GIconLabel {
public static final String TRANSLATION_RESET_PROPERTY = "translation-reset";

View file

@ -0,0 +1,103 @@
/* ###
* 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 docking.widgets.label;
import javax.swing.*;
import docking.widgets.GComponent;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.checkbox.GHtmlCheckBox;
/**
* A 'dynamic' label (the text can be changed), with HTML rendering allowed.
* <p>
* See also:
* <table border=1>
* <tr><th>Class</th><th>Mutable text</th><th>HTML rendering</th><th>Description</th></tr>
* <tr><td>{@link GLabel}</td><td>Immutable</td><td>NO</td><td>Non-html unchangeable label</td></tr>
* <tr><td>{@link GDLabel}</td><td>Mutable</td><td>NO</td><td>Non-html changeable label</td></tr>
* <tr><td>{@link GHtmlLabel}</td><td>Immutable</td><td>YES</td><td>Html unchangeable label</td></tr>
* <tr><td>{@link GDHtmlLabel}</td><td>Mutable</td><td>YES</td><td>Html changeable label</td></tr>
* <tr><td>{@link GIconLabel}</td><td>N/A</td><td>NO</td><td>Label that only has an icon image, no text</td></tr>
* <tr><th colspan=4>Other components of note:</th></tr>
* <tr><td>{@link GCheckBox}</td><td></td><td>NO</td><td>Non-html checkbox</td></tr>
* <tr><td>{@link GHtmlCheckBox}</td><td></td><td>YES</td><td>Html checkbox</td></tr>
* </table>
*/
public class GDHtmlLabel extends JLabel implements GComponent {
/**
* Creates a label with no image and no text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering allowed.
* <p>
* See {@link JLabel#JLabel()}.
* <p>
*/
public GDHtmlLabel() {
super();
}
/**
* Creates a label with the specified text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering allowed.
* <p>
* See {@link JLabel#JLabel(String)}.
* <p>
* @param text string to be displayed by the label
*/
public GDHtmlLabel(String text) {
super(text);
}
/**
* Creates a label with the specified text and horizontal alignment,
* with HTML rendering allowed.
* <p>
* See {@link JLabel#JLabel(String, int)}.
* <p>
* @param text string to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GDHtmlLabel(String text, int horizontalAlignment) {
super(text, horizontalAlignment);
}
/**
* Creates a label with the specified text, image and horizontal alignment,
* with HTML rendering allowed.
* <p>
* See {@link JLabel#JLabel(String, Icon, int)}.
* <p>
*
* @param text string to be displayed by the label
* @param icon image to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GDHtmlLabel(String text, Icon icon, int horizontalAlignment) {
super(text, icon, horizontalAlignment);
}
}

View file

@ -0,0 +1,117 @@
/* ###
* 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 docking.widgets.label;
import javax.swing.*;
import docking.widgets.GComponent;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.checkbox.GHtmlCheckBox;
/**
* A 'dynamic' label (the text can be changed), with HTML rendering disabled.
* <p>
* See also:
* <table border=1>
* <tr><th>Class</th><th>Mutable text</th><th>HTML rendering</th><th>Description</th></tr>
* <tr><td>{@link GLabel}</td><td>Immutable</td><td>NO</td><td>Non-html unchangeable label</td></tr>
* <tr><td>{@link GDLabel}</td><td>Mutable</td><td>NO</td><td>Non-html changeable label</td></tr>
* <tr><td>{@link GHtmlLabel}</td><td>Immutable</td><td>YES</td><td>Html unchangeable label</td></tr>
* <tr><td>{@link GDHtmlLabel}</td><td>Mutable</td><td>YES</td><td>Html changeable label</td></tr>
* <tr><td>{@link GIconLabel}</td><td>N/A</td><td>NO</td><td>Label that only has an icon image, no text</td></tr>
* <tr><th colspan=4>Other components of note:</th></tr>
* <tr><td>{@link GCheckBox}</td><td></td><td>NO</td><td>Non-html checkbox</td></tr>
* <tr><td>{@link GHtmlCheckBox}</td><td></td><td>YES</td><td>Html checkbox</td></tr>
* </table>
*/
public class GDLabel extends JLabel implements GComponent {
/**
* Creates a label with no image and no text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel()}.
* <p>
*/
public GDLabel() {
super();
init();
}
/**
* Creates a label with the specified text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel(String)}.
* <p>
* @param text non-html string to be displayed by the label
*/
public GDLabel(String text) {
super(text);
init();
}
/**
* Creates a label with the specified text and horizontal alignment,
* with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel(String, int)}.
* <p>
* @param text non-html string to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GDLabel(String text, int horizontalAlignment) {
super(text, horizontalAlignment);
init();
}
/**
* Creates a label with the specified text, image and horizontal alignment,
* with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel(String, Icon, int)}.
* <p>
*
* @param text non-html string to be displayed by the label
* @param icon image to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GDLabel(String text, Icon icon, int horizontalAlignment) {
super(text, icon, horizontalAlignment);
init();
}
@Override
public void setText(String text) {
GComponent.warnAboutHtmlText(text);
super.setText(text);
}
private void init() {
setHTMLRenderingEnabled(false);
}
}

View file

@ -0,0 +1,129 @@
/* ###
* 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 docking.widgets.label;
import javax.swing.*;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.GComponent;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.checkbox.GHtmlCheckBox;
import ghidra.util.Msg;
import utilities.util.reflection.ReflectionUtilities;
/**
* An immutable label (the text can NOT be changed), with HTML rendering allowed.
* <p>
* See also:
* <table border=1>
* <tr><th>Class</th><th>Mutable text</th><th>HTML rendering</th><th>Description</th></tr>
* <tr><td>{@link GLabel}</td><td>Immutable</td><td>NO</td><td>Non-html unchangeable label</td></tr>
* <tr><td>{@link GDLabel}</td><td>Mutable</td><td>NO</td><td>Non-html changeable label</td></tr>
* <tr><td>{@link GHtmlLabel}</td><td>Immutable</td><td>YES</td><td>Html unchangeable label</td></tr>
* <tr><td>{@link GDHtmlLabel}</td><td>Mutable</td><td>YES</td><td>Html changeable label</td></tr>
* <tr><td>{@link GIconLabel}</td><td>N/A</td><td>NO</td><td>Label that only has an icon image, no text</td></tr>
* <tr><th colspan=4>Other components of note:</th></tr>
* <tr><td>{@link GCheckBox}</td><td></td><td>NO</td><td>Non-html checkbox</td></tr>
* <tr><td>{@link GHtmlCheckBox}</td><td></td><td>YES</td><td>Html checkbox</td></tr>
* </table>
*/
public class GHtmlLabel extends JLabel implements GComponent {
/**
* Creates a immutable label with no image and no text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering allowed.
* <p>
* See {@link JLabel#JLabel()}.
* <p>
*/
public GHtmlLabel() {
super();
}
/**
* Creates a immutable label with the specified text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering allowed.
* <p>
* See {@link JLabel#JLabel(String)}.
* <p>
* @param text string to be displayed by the label
*/
public GHtmlLabel(String text) {
super(text);
}
/**
* Creates a immutable label with the specified text and horizontal alignment,
* with HTML rendering allowed.
* <p>
* See {@link JLabel#JLabel(String, int)}.
* <p>
* @param text string to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GHtmlLabel(String text, int horizontalAlignment) {
super(text, horizontalAlignment);
}
/**
* Creates a immutable label with the specified text, image and horizontal alignment,
* with HTML rendering allowed.
* <p>
* See {@link JLabel#JLabel(String, Icon, int)}.
* <p>
*
* @param text string to be displayed by the label
* @param icon image to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GHtmlLabel(String text, Icon icon, int horizontalAlignment) {
super(text, icon, horizontalAlignment);
}
/**
* This is a half-way method of turning this label into an immutable instance.
* <p>
* If the user has a type of "GHtmlLabel", they will see the deprecated warning on calls to setText().
* <p>
* If there are calls to setText() after the initial value has been set by the ctor, a
* warning will be printed in the log.
* <p>
* @param text string this label will display
*/
@Deprecated
@Override
public void setText(String text) {
if (!StringUtils.isEmpty(getText())) {
Msg.warn(this,
"Trying to set text on an immutable label! Current text: [" + getText() +
"], new text: [" + text + "]",
ReflectionUtilities.createJavaFilteredThrowable());
return;
}
super.setText(text);
}
}

View file

@ -0,0 +1,108 @@
/* ###
* 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 docking.widgets.label;
import javax.swing.*;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.GComponent;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.checkbox.GHtmlCheckBox;
import ghidra.util.Msg;
import utilities.util.reflection.ReflectionUtilities;
/**
* A label that only contains an image and no text.
* <p>
* See also:
* <table border=1>
* <tr><th>Class</th><th>Mutable text</th><th>HTML rendering</th><th>Description</th></tr>
* <tr><td>{@link GLabel}</td><td>Immutable</td><td>NO</td><td>Non-html unchangeable label</td></tr>
* <tr><td>{@link GDLabel}</td><td>Mutable</td><td>NO</td><td>Non-html changeable label</td></tr>
* <tr><td>{@link GHtmlLabel}</td><td>Immutable</td><td>YES</td><td>Html unchangeable label</td></tr>
* <tr><td>{@link GDHtmlLabel}</td><td>Mutable</td><td>YES</td><td>Html changeable label</td></tr>
* <tr><td>{@link GIconLabel}</td><td>N/A</td><td>NO</td><td>Label that only has an icon image, no text</td></tr>
* <tr><th colspan=4>Other components of note:</th></tr>
* <tr><td>{@link GCheckBox}</td><td></td><td>NO</td><td>Non-html checkbox</td></tr>
* <tr><td>{@link GHtmlCheckBox}</td><td></td><td>YES</td><td>Html checkbox</td></tr>
* </table>
*/
public class GIconLabel extends GLabel implements GComponent {
/**
* Creates a immutable label with no image and no text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel()}.
* <p>
*/
public GIconLabel() {
super();
}
/**
* Creates a immutable label with the specified image,
* with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel(Icon)}.
* <p>
* @param image icon to be displayed by the label
*/
public GIconLabel(Icon image) {
super(image);
}
/**
* Creates a immutable label with the specified image and horizontal alignment,
* with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel(Icon, int)}.
* <p>
* @param image icon to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GIconLabel(Icon image, int horizontalAlignment) {
super(image, horizontalAlignment);
}
/**
* This is a half-way method of turning this label into an immutable instance.
* <p>
* If the user has a type of "GIconLabel", they will see the deprecated warning on calls to setText().
* <p>
* If there are calls to setText() with any non-null or non-empty value, a
* warning will be printed in the log.
* <p>
* @param text string this label will NOT display
*/
@Deprecated
@Override
public void setText(String text) {
if (!StringUtils.isEmpty(text)) {
Msg.warn(this, "Trying to set text on an icon label! New text: [" + text + "]",
ReflectionUtilities.createJavaFilteredThrowable());
return;
}
super.setText(text);
}
}

View file

@ -0,0 +1,162 @@
/* ###
* 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 docking.widgets.label;
import javax.swing.*;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.GComponent;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.checkbox.GHtmlCheckBox;
import ghidra.util.Msg;
import utilities.util.reflection.ReflectionUtilities;
/**
* An immutable label (the text can NOT be changed), with HTML rendering disabled.
* <p>
* See also:
* <table border=1>
* <tr><th>Class</th><th>Mutable text</th><th>HTML rendering</th><th>Description</th></tr>
* <tr><td>{@link GLabel}</td><td>Immutable</td><td>NO</td><td>Non-html unchangeable label</td></tr>
* <tr><td>{@link GDLabel}</td><td>Mutable</td><td>NO</td><td>Non-html changeable label</td></tr>
* <tr><td>{@link GHtmlLabel}</td><td>Immutable</td><td>YES</td><td>Html unchangeable label</td></tr>
* <tr><td>{@link GDHtmlLabel}</td><td>Mutable</td><td>YES</td><td>Html changeable label</td></tr>
* <tr><td>{@link GIconLabel}</td><td>N/A</td><td>NO</td><td>Label that only has an icon image, no text</td></tr>
* <tr><th colspan=4>Other components of note:</th></tr>
* <tr><td>{@link GCheckBox}</td><td></td><td>NO</td><td>Non-html checkbox</td></tr>
* <tr><td>{@link GHtmlCheckBox}</td><td></td><td>YES</td><td>Html checkbox</td></tr>
* </table>
*/
public class GLabel extends JLabel implements GComponent {
/**
* Creates a immutable label with no image and no text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel()}.
* <p>
*/
public GLabel() {
super();
init();
}
/**
* Creates a immutable label with the specified text, with {@link SwingConstants#LEADING} horizontal
* alignment, with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel(String)}.
* <p>
* @param text non-html string to be displayed by the label
*/
public GLabel(String text) {
super(text);
init();
}
/**
* Creates a immutable label with the specified text and horizontal alignment,
* with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel(String, int)}.
* <p>
* @param text non-html string to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GLabel(String text, int horizontalAlignment) {
super(text, horizontalAlignment);
init();
}
/**
* Creates a immutable label with the specified text, image and horizontal alignment,
* with HTML rendering disabled.
* <p>
* See {@link JLabel#JLabel(String, Icon, int)}.
* <p>
*
* @param text non-html string to be displayed by the label
* @param icon image to be displayed by the label
* @param horizontalAlignment One of
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
public GLabel(String text, Icon icon, int horizontalAlignment) {
super(text, icon, horizontalAlignment);
init();
}
/**
*
* @param image icon to display
* @param horizontalAlignment see
* {@link SwingConstants#LEFT},
* {@link SwingConstants#CENTER},
* {@link SwingConstants#RIGHT},
* {@link SwingConstants#LEADING},
* {@link SwingConstants#TRAILING}
*/
protected GLabel(Icon image, int horizontalAlignment) {
super(image, horizontalAlignment);
init();
}
/**
* @param image icon to display
*/
protected GLabel(Icon image) {
super(image);
init();
}
private void init() {
setHTMLRenderingEnabled(false);
}
/**
* This is a half-way method of turning this label into an immutable instance.
* <p>
* If the user has a type of "GLabel", they will see the deprecated warning on calls to setText().
* <p>
* If there are calls to setText() after the initial value has been set by the ctor, a
* warning will be printed in the log.
* <p>
* @param text string this label will display
*/
@Deprecated
@Override
public void setText(String text) {
if (!StringUtils.isEmpty(getText())) {
Msg.warn(this,
"Trying to set text on an immutable label! Current text: [" + getText() +
"], new text: [" + text + "]",
ReflectionUtilities.createJavaFilteredThrowable());
return;
}
GComponent.warnAboutHtmlText(text);
super.setText(text);
}
}

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,23 +15,26 @@
*/
package docking.widgets.list;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
import javax.swing.JList;
import javax.swing.ListModel;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import docking.widgets.GComponent;
import docking.widgets.table.GTable;
/**
* A sub-class of JList that provides an auto-lookup feature.
* <p>
* The user can begin typing the first few letters of a desired
* list element and the selection will automatically navigate to it.
* <p>
* HTML rendering is disabled by default.
* <p>
*
*/
public class GList<T> extends JList<T> {
public class GList<T> extends JList<T> implements GComponent {
private static final long serialVersionUID = 1L;
/**The timeout for the auto-lookup feature*/
@ -81,41 +83,28 @@ public class GList<T> extends JList<T> {
}
private void init() {
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
// if (e.isActionKey() ||
// e.getKeyChar() == KeyEvent.CHAR_UNDEFINED ||
// Character.isISOControl(e.getKeyChar())) {
// return;
// }
// long when = e.getWhen();
// if (when - lastLookupTime > KEY_TIMEOUT) {
// lookupString = ""+e.getKeyChar();
// }
// else {
// lookupString += ""+e.getKeyChar();
// }
// int index = getIndex(getModel(), lookupString);
// if (index >= 0) {
// setSelectedIndex(index);
// Rectangle rect = getCellBounds(index, index);
// scrollRectToVisible(rect);
// }
// lastLookupTime = when;
// e.consume();
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
});
setHTMLRenderingEnabled(false);
if (getCellRenderer() instanceof JComponent) {
GComponent.setHTMLRenderingFlag((JComponent) getCellRenderer(), false);
}
addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
ensureIndexIsVisible(getSelectedIndex());
}
});
}
// /**
// * Turns off the HTML rendering in the specified component and its current cell renderer.
// *
// * @param list the list
// */
// public static void turnOffHTMLRendering(JList<?> list) {
// turnOffHTMLRendering((JComponent) list);
// if (list.getCellRenderer() instanceof JComponent) {
// turnOffHTMLRendering((JComponent) list.getCellRenderer());
// }
// }
}

View file

@ -16,6 +16,7 @@
package docking.widgets.list;
import java.awt.*;
import java.util.function.Function;
import javax.swing.*;
@ -23,11 +24,32 @@ import docking.widgets.AbstractGCellRenderer;
/**
* Provides a common implementation of a list renderer, for use in both JList and JComboBox.
* <p>
* HTML rendering defaults to disabled. See {@link #setHTMLRenderingEnabled(boolean)}.
*
* @param <E> the element-type this list models.
*/
public class GListCellRenderer<E> extends AbstractGCellRenderer implements ListCellRenderer<E> {
/**
* Returns a new ListCellRenderer that maps the list's data instance to a string used in the cell.
* <p>
* Use this if you only need to provide a way to get the string value from the type being shown
* in the list.
*
* @param cellToTextMappingFunction a function that maps your custom type to a string value
* @return new GListCellRenderer instance
*/
public static <E> GListCellRenderer<E> createDefaultCellTextRenderer(
Function<E, String> cellToTextMappingFunction) {
return new GListCellRenderer<>() {
@Override
protected String getItemText(E value) {
return cellToTextMappingFunction.apply(value);
}
};
}
/**
* Constructs a new GListCellRenderer.
*/

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,8 +20,9 @@ import java.awt.event.*;
import javax.swing.*;
import resources.ResourceManager;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDLabel;
import resources.ResourceManager;
/**
* A widget that can be used to render an icon, title and close button for JTabbedPane. You would
@ -31,10 +31,10 @@ import docking.widgets.EmptyBorderButton;
public class DockingTabRenderer extends JPanel {
private static final int MAX_TITLE_LENGTH = 25;
private Icon EMPTY_ICON = ResourceManager.getScaledIcon(
ResourceManager.loadImage("images/close16.gif"), 8, 8);
private Icon CLOSE_ICON = ResourceManager.getScaledIcon(
ResourceManager.loadImage("images/close16.gif"), 8, 8);
private Icon EMPTY_ICON =
ResourceManager.getScaledIcon(ResourceManager.loadImage("images/close16.gif"), 8, 8);
private Icon CLOSE_ICON =
ResourceManager.getScaledIcon(ResourceManager.loadImage("images/close16.gif"), 8, 8);
private JLabel titleLabel;
private JLabel iconLabel;
@ -50,8 +50,8 @@ public class DockingTabRenderer extends JPanel {
final ForwardingMouseListener eventForwardingListener =
new ForwardingMouseListener(tabbedPane);
titleLabel = new JLabel();
iconLabel = new JLabel();
titleLabel = new GDLabel();
iconLabel = new GDLabel();
closeButton = new EmptyBorderButton();
setTitle(tabTitle, fullTitle);
@ -105,7 +105,8 @@ public class DockingTabRenderer extends JPanel {
@Override
public void hierarchyChanged(HierarchyEvent e) {
long changeFlags = e.getChangeFlags();
if (HierarchyEvent.DISPLAYABILITY_CHANGED == (changeFlags & HierarchyEvent.DISPLAYABILITY_CHANGED)) {
if (HierarchyEvent.DISPLAYABILITY_CHANGED == (changeFlags &
HierarchyEvent.DISPLAYABILITY_CHANGED)) {
Container myParent = getParent(); // should be a TabContainer

View file

@ -20,6 +20,8 @@ import java.awt.Component;
import javax.swing.JComponent;
import javax.swing.table.TableCellRenderer;
import docking.widgets.GComponent;
public class DefaultTableCellRendererWrapper extends GTableCellRenderer {
private final TableCellRenderer renderer;
@ -42,7 +44,7 @@ public class DefaultTableCellRendererWrapper extends GTableCellRenderer {
@Override
public void setHTMLRenderingEnabled(boolean enable) {
if (renderer instanceof JComponent) {
((JComponent) renderer).putClientProperty(HTML_DISABLE_STRING, !enable);
((JComponent) renderer).putClientProperty(GComponent.HTML_DISABLE_STRING, !enable);
}
super.setHTMLRenderingEnabled(enable);
}

View file

@ -17,11 +17,11 @@ package docking.widgets.table;
import java.awt.*;
import javax.swing.JCheckBox;
import docking.widgets.checkbox.GCheckBox;
public class GBooleanCellRenderer extends GTableCellRenderer {
protected JCheckBox cb = new JCheckBox();
protected GCheckBox cb = new GCheckBox();
public GBooleanCellRenderer() {
super();

View file

@ -66,6 +66,15 @@ public class GTableCellRenderer extends AbstractGCellRenderer implements TableCe
setFont(f);
}
/**
* Return the cell renderer text
* @param value Cell object value
* @return A string interpretation of value; generated by calling value.toString()
*/
protected String getText(Object value) {
return value == null ? "" : value.toString();
}
/**
* Satisfies the Java {@link javax.swing.table.TableCellRenderer} interface; retrieves
* column data via a GTableCellRenderingData object, and defers painting to

View file

@ -35,6 +35,7 @@ import docking.menu.*;
import docking.widgets.EmptyBorderButton;
import docking.widgets.EventTrigger;
import docking.widgets.filter.*;
import docking.widgets.label.GDLabel;
import docking.widgets.table.columnfilter.ColumnBasedTableFilter;
import docking.widgets.table.columnfilter.ColumnFilterSaveManager;
import docking.widgets.table.constraint.dialog.ColumnFilterDialog;
@ -348,7 +349,7 @@ public class GTableFilterPanel<ROW_OBJECT> extends JPanel {
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
searchLabel = new JLabel(filterLabel);
searchLabel = new GDLabel(filterLabel);
searchLabel.setToolTipText("Include only table elements that match the given search text");
filterField = new FilterTextField(table);
@ -401,26 +402,26 @@ public class GTableFilterPanel<ROW_OBJECT> extends JPanel {
RowObjectFilterModel<ROW_OBJECT> tableModel =
(RowObjectFilterModel<ROW_OBJECT>) table.getModel();
columnFilterAction = new NonToolbarMultiStateAction<ColumnBasedTableFilter<ROW_OBJECT>>(
"Column Filter", "GTableFilterPanel") {
columnFilterAction =
new NonToolbarMultiStateAction<>("Column Filter", "GTableFilterPanel") {
@Override
public void actionStateChanged(
ActionState<ColumnBasedTableFilter<ROW_OBJECT>> newActionState,
EventTrigger trigger) {
if (trigger != EventTrigger.GUI_ACTION) {
return;
@Override
public void actionStateChanged(
ActionState<ColumnBasedTableFilter<ROW_OBJECT>> newActionState,
EventTrigger trigger) {
if (trigger != EventTrigger.GUI_ACTION) {
return;
}
ColumnFilterActionState state = (ColumnFilterActionState) newActionState;
state.performAction();
}
ColumnFilterActionState state = (ColumnFilterActionState) newActionState;
state.performAction();
}
@Override
protected void doActionPerformed(ActionContext context) {
showFilterDialog(tableModel);
}
@Override
protected void doActionPerformed(ActionContext context) {
showFilterDialog(tableModel);
}
};
};
columnFilterAction.setPerformActionOnPrimaryButtonClick(true);
HelpLocation helpLocation = new HelpLocation("Trees", "Column_Filters");
columnFilterAction.setHelpLocation(helpLocation);

View file

@ -24,6 +24,7 @@ import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import docking.widgets.label.GDLabel;
import resources.*;
import resources.icons.EmptyIcon;
import resources.icons.TranslateIcon;
@ -51,8 +52,8 @@ public class GTableHeaderRenderer extends JPanel implements TableCellRenderer {
private static final Icon FILTER_ICON =
ResourceManager.getScaledIcon(ResourceManager.loadImage("images/filter_off.png"), 12, 12);
private JLabel textLabel = new JLabel();
private JLabel iconLabel = new JLabel();
private JLabel textLabel = new GDLabel();
private JLabel iconLabel = new GDLabel();
private Icon helpIcon = null;
private CustomPaddingBorder customBorder;
protected boolean isPaintingPrimarySortColumn;

View file

@ -28,6 +28,7 @@ import javax.swing.*;
import org.apache.commons.lang3.StringUtils;
import docking.DialogComponentProvider;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.table.columnfilter.ColumnBasedTableFilter;
import docking.widgets.table.columnfilter.ColumnFilterSaveManager;
import ghidra.util.HTMLUtilities;
@ -152,7 +153,7 @@ public class ColumnFilterArchiveDialog<R> extends DialogComponentProvider {
panel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEmptyBorder(19, 0, 26, 5), "Preview"));
previewLabel = new JLabel();
previewLabel = new GDHtmlLabel();
previewLabel.setVerticalAlignment(SwingConstants.TOP);
panel.add(new JScrollPane(previewLabel));
return panel;

View file

@ -28,6 +28,7 @@ import docking.*;
import docking.action.*;
import docking.widgets.OptionDialog;
import docking.widgets.dialogs.InputDialog;
import docking.widgets.label.GLabel;
import docking.widgets.table.GTableFilterPanel;
import docking.widgets.table.RowObjectFilterModel;
import docking.widgets.table.columnfilter.*;
@ -359,18 +360,18 @@ public class ColumnFilterDialog<R> extends DialogComponentProvider
filterPanelContainer.getParent().validate();
}
private Component createLogicalOperationLabel(LogicOperation op) {
JLabel jLabel = new JLabel("<" + op + ">", SwingConstants.CENTER);
jLabel.setForeground(Color.GRAY);
return jLabel;
private GLabel createLogicalOperationLabel(LogicOperation op) {
GLabel label = new GLabel("<" + op + ">", SwingConstants.CENTER);
label.setForeground(Color.GRAY);
return label;
}
private JComponent buildHeaderPanel() {
JPanel headerPanel = new JPanel(new FilterPanelLayout(200, 0));
headerPanel.add(new JLabel("Table Column", SwingConstants.CENTER));
headerPanel.add(new JLabel("Filter", SwingConstants.CENTER));
headerPanel.add(new JLabel("Filter Value", SwingConstants.CENTER));
headerPanel.add(new GLabel("Table Column", SwingConstants.CENTER));
headerPanel.add(new GLabel("Filter", SwingConstants.CENTER));
headerPanel.add(new GLabel("Filter Value", SwingConstants.CENTER));
headerPanel.setBorder(new CompoundBorder(
BorderFactory.createMatteBorder(0, 0, 1, 0, Color.DARK_GRAY.brighter().brighter()),

View file

@ -25,6 +25,7 @@ import javax.swing.border.BevelBorder;
import docking.widgets.EmptyBorderButton;
import docking.widgets.combobox.GhidraComboBox;
import docking.widgets.label.GDLabel;
import docking.widgets.list.GListCellRenderer;
import ghidra.util.layout.VerticalLayout;
import resources.ResourceManager;
@ -114,7 +115,7 @@ class ColumnFilterPanel extends JPanel {
}
private Component createOrLabel() {
JLabel jLabel = new JLabel("<OR>", SwingConstants.CENTER);
JLabel jLabel = new GDLabel("<OR>", SwingConstants.CENTER);
jLabel.setForeground(Color.GRAY);
return jLabel;
}

View file

@ -22,6 +22,7 @@ import java.awt.event.ActionListener;
import javax.swing.*;
import docking.widgets.EmptyBorderButton;
import docking.widgets.combobox.GComboBox;
import docking.widgets.list.GListCellRenderer;
import docking.widgets.table.constraint.ColumnConstraint;
import resources.Icons;
@ -82,7 +83,7 @@ public class ConstraintFilterPanel extends JPanel {
private Component buildConstraintCombo() {
JPanel panel = new JPanel(new BorderLayout());
constraintComboBox = new JComboBox<>();
constraintComboBox = new GComboBox<>();
constraintComboBox.setRenderer(new ConstraintComboBoxCellRenderer());
constraintComboBox.addActionListener(constraintComboBoxListener);
panel.add(constraintComboBox, BorderLayout.CENTER);
@ -121,15 +122,8 @@ public class ConstraintFilterPanel extends JPanel {
private class ConstraintComboBoxCellRenderer extends GListCellRenderer<ColumnConstraint<?>> {
@Override
public Component getListCellRendererComponent(JList<? extends ColumnConstraint<?>> list,
ColumnConstraint<?> value, int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
label.setText(value.getName());
return label;
protected String getItemText(ColumnConstraint<?> value) {
return value.getName();
}
@Override

View file

@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils;
import docking.widgets.DropDownTextField;
import docking.widgets.DropDownTextFieldDataModel;
import docking.widgets.list.GListCellRenderer;
import docking.widgets.table.constraint.*;
import ghidra.util.HTMLUtilities;
@ -200,14 +201,13 @@ public class AutocompletingStringConstraintEditor extends DataLoadingConstraintE
* Cell renderer for suggestion nominees. Substrings that match the models' query
* are highlighted for ease-of-use.
*/
private class AutocompleteListCellRenderer implements ListCellRenderer<String> {
private DefaultListCellRenderer delegate = new DefaultListCellRenderer();
private class AutocompleteListCellRenderer extends GListCellRenderer<String> {
private final AutocompleteDataModel model;
public AutocompleteListCellRenderer(AutocompleteDataModel autocompleteDataModel) {
this.model = autocompleteDataModel;
this.setHTMLRenderingEnabled(true);
}
private String formatListValue(String value, boolean isSelected) {
@ -216,7 +216,7 @@ public class AutocompletingStringConstraintEditor extends DataLoadingConstraintE
Color color = isSelected ? Color.YELLOW : Color.MAGENTA;
StringBuffer sb = new StringBuffer("<html>");
StringBuilder sb = new StringBuilder("<html>");
// find and highlight all instances of the user-defined pattern
while (matcher.find()) {
String group = matcher.group(1);
@ -226,19 +226,17 @@ public class AutocompletingStringConstraintEditor extends DataLoadingConstraintE
matcher.appendTail(sb);
return sb.toString();
}
@Override
public Component getListCellRendererComponent(JList<? extends String> list, String value,
int index, boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) delegate.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
String valueString = formatListValue(value, isSelected);
label.setText(valueString);
return label;
setText(valueString);
return this;
}
}

View file

@ -18,10 +18,13 @@ package docking.widgets.table.constrainteditor;
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.*;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.combobox.GComboBox;
import docking.widgets.list.GListCellRenderer;
import docking.widgets.table.constraint.BooleanMatchColumnConstraint;
import docking.widgets.table.constraint.ColumnConstraint;
@ -44,8 +47,9 @@ public class BooleanConstraintEditor extends AbstractColumnConstraintEditor<Bool
protected Component buildInlineEditorComponent() {
JPanel panel = new JPanel(new BorderLayout());
comboBox = new JComboBox<>(new Boolean[] { Boolean.TRUE, Boolean.FALSE });
comboBox.setRenderer(new BooleanCellRenderer());
comboBox = new GComboBox<>(new Boolean[] { Boolean.TRUE, Boolean.FALSE });
comboBox.setRenderer(GListCellRenderer.createDefaultCellTextRenderer(
b -> StringUtils.capitalize(b.toString())));
comboBox.addItemListener(e -> valueChanged());
panel.add(comboBox, BorderLayout.CENTER);
@ -71,20 +75,6 @@ public class BooleanConstraintEditor extends AbstractColumnConstraintEditor<Bool
comboBox.setSelectedIndex(0);
}
private class BooleanCellRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index,
isSelected, cellHasFocus);
setText(StringUtils.capitalize(((Boolean) value).toString()));
return label;
}
}
@Override
protected boolean checkEditorValueValidity() {
return true;

View file

@ -26,6 +26,7 @@ import javax.swing.*;
import docking.DisabledComponentLayerFactory;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.ColumnData;
import ghidra.util.HTMLUtilities;
@ -90,7 +91,7 @@ public abstract class DataLoadingConstraintEditor<T> extends AbstractColumnConst
@Override
protected Component buildInlineEditorComponent() {
JPanel editorPanel = new JPanel(new BorderLayout());
statusLabel = new JLabel();
statusLabel = new GDHtmlLabel();
statusLabel.setHorizontalAlignment(SwingConstants.CENTER);
taskMonitorComponent = new TaskMonitorComponent();

View file

@ -23,6 +23,7 @@ import java.util.Calendar;
import javax.swing.*;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.RangeColumnConstraint;
import docking.widgets.table.constraint.provider.DateColumnConstraintProvider;
@ -107,7 +108,7 @@ public class DateRangeConstraintEditor extends AbstractColumnConstraintEditor<Lo
panel.add(controlPanel);
infoLabel = new JLabel();
infoLabel = new GDHtmlLabel();
infoLabel.setForeground(Color.GRAY);
infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(infoLabel);
@ -115,32 +116,6 @@ public class DateRangeConstraintEditor extends AbstractColumnConstraintEditor<Lo
return panel;
}
private void rangeChanged() {
if (!hasEditorComponents()) {
return;
}
String statusMsg = "";
if (checkEditorValueValidity()) {
LocalDate start = lowerSpinnerModel.getDate();
LocalDate end = upperSpinnerModel.getDate();
// add one because the date range is inclusive.
long days = ChronoUnit.DAYS.between(start, end) + 1;
// add one because the date range is inclusive.
statusMsg += formatStatus(String.format("Range Size: %,d days", days), false);
}
else {
statusMsg += formatStatus(getErrorMessage(), true);
}
infoLabel.setText(statusMsg);
valueChanged();
}
@Override
protected void updateInfoMessage(boolean isValid) {
if (isValid) {

View file

@ -25,6 +25,7 @@ import javax.swing.JSpinner.NumberEditor;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.numberformat.BoundedRangeDecimalFormatterFactory;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.RangeColumnConstraint;
@ -75,7 +76,7 @@ public class DoubleRangeConstraintEditor extends AbstractColumnConstraintEditor<
infoLabelNumberFormat = new DecimalFormat(DISPLAY_FORMAT);
infoLabel = new JLabel();
infoLabel = new GDHtmlLabel();
infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(infoLabel);

View file

@ -22,6 +22,7 @@ import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.event.ChangeListener;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.table.constraint.ColumnConstraint;
import ghidra.util.HTMLUtilities;
@ -48,7 +49,7 @@ public final class DummyConstraintEditor<T> implements ColumnConstraintEditor<T>
public Component getInlineComponent() {
JPanel panel = new JPanel();
JLabel errorLabel = new JLabel(
JLabel errorLabel = new GDHtmlLabel(
"<html>" + HTMLUtilities.bold(HTMLUtilities.colorString(Color.RED, message)));
panel.add(errorLabel);

View file

@ -21,6 +21,8 @@ import java.util.*;
import javax.swing.*;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.EnumColumnConstraint;
@ -56,7 +58,7 @@ public class EnumConstraintEditor<T extends Enum<T>> extends AbstractColumnConst
panel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 10));
for (T t : allValues) {
JCheckBox jCheckBox = new JCheckBox(getElementDisplayName(t));
GCheckBox jCheckBox = new GCheckBox(getElementDisplayName(t));
enumCheckboxMap.put(t, jCheckBox);
@ -76,7 +78,7 @@ public class EnumConstraintEditor<T extends Enum<T>> extends AbstractColumnConst
JPanel outerPanel = new JPanel(new BorderLayout());
outerPanel.add(panel, BorderLayout.CENTER);
infoLabel = new JLabel("");
infoLabel = new GDHtmlLabel("");
infoLabel.setForeground(Color.GRAY);
infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
outerPanel.add(infoLabel, BorderLayout.SOUTH);

View file

@ -21,6 +21,7 @@ import javax.swing.*;
import org.apache.commons.lang3.StringUtils;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.spinner.IntegerSpinner;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.SingleValueColumnConstraint;
@ -70,7 +71,7 @@ public class IntegerConstraintEditor<T extends Number> extends AbstractColumnCon
spinnerModel.addChangeListener(e -> valueChanged());
panel.add(spinner.getSpinner(), BorderLayout.CENTER);
statusLabel = new JLabel();
statusLabel = new GDHtmlLabel();
panel.add(statusLabel, BorderLayout.SOUTH);
statusLabel.setForeground(Color.RED);
statusLabel.setHorizontalAlignment(SwingConstants.CENTER);

View file

@ -20,6 +20,7 @@ import java.math.BigInteger;
import javax.swing.*;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.spinner.IntegerSpinner;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.RangeColumnConstraint;
@ -103,7 +104,7 @@ public class IntegerRangeConstraintEditor<T extends Number>
panel.add(rangeControlPanel);
infoLabel = new JLabel();
infoLabel = new GDHtmlLabel();
infoLabel.setForeground(Color.GRAY);
infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(infoLabel);

View file

@ -19,6 +19,7 @@ import java.awt.*;
import javax.swing.*;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.StringColumnConstraint;
@ -51,7 +52,7 @@ public class StringConstraintEditor extends AbstractColumnConstraintEditor<Strin
panel.add(textField, BorderLayout.CENTER);
infoLabel = new JLabel("abc"); // temporary text in the label so that it sizes properly
infoLabel = new GDHtmlLabel("abc"); // temporary text in the label so that it sizes properly
infoLabel.setForeground(Color.RED);
infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(infoLabel, BorderLayout.SOUTH);

View file

@ -20,6 +20,7 @@ import java.math.BigInteger;
import javax.swing.*;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.SingleValueColumnConstraint;
import docking.widgets.textfield.IntegerTextField;
@ -57,7 +58,7 @@ public class UnsignedLongConstraintEditor extends AbstractColumnConstraintEditor
field.addChangeListener(e -> valueChanged());
panel.add(field.getComponent(), BorderLayout.CENTER);
statusLabel = new JLabel();
statusLabel = new GDHtmlLabel();
panel.add(statusLabel, BorderLayout.SOUTH);
statusLabel.setForeground(Color.RED);
statusLabel.setHorizontalAlignment(SwingConstants.CENTER);

View file

@ -20,6 +20,7 @@ import java.math.BigInteger;
import javax.swing.*;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.table.constraint.ColumnConstraint;
import docking.widgets.table.constraint.RangeColumnConstraint;
import docking.widgets.textfield.IntegerTextField;
@ -68,7 +69,7 @@ public class UnsignedLongRangeConstraintEditor extends AbstractColumnConstraintE
panel.add(rangeControlPanel);
infoLabel = new JLabel();
infoLabel = new GDHtmlLabel();
infoLabel.setForeground(Color.GRAY);
infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(infoLabel);

View file

@ -21,6 +21,7 @@ import java.awt.FlowLayout;
import javax.swing.*;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GLabel;
import docking.widgets.table.GTable;
import ghidra.util.task.TaskMonitor;
import ghidra.util.task.TaskMonitorComponent;
@ -150,13 +151,13 @@ public class GThreadedTablePanel<T> extends JPanel {
}
private void buildPending() {
JLabel label = new JLabel("Update pending...", SwingConstants.CENTER);
refreshButton = new EmptyBorderButton(Icons.REFRESH_ICON);
refreshButton.addActionListener(e -> threadedModel.reload());
refreshButton.setToolTipText("Force Refresh Now");
pendingPanel = new JPanel(new FlowLayout());
pendingPanel.setName("Pending Panel");
pendingPanel.add(label, BorderLayout.CENTER);
pendingPanel.add(new GLabel("Update pending...", SwingConstants.CENTER),
BorderLayout.CENTER);
pendingPanel.add(refreshButton, BorderLayout.EAST);
}

View file

@ -16,7 +16,6 @@
package docking.widgets.textfield;
import java.awt.Component;
import java.awt.Window;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
@ -24,7 +23,8 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
@ -54,7 +54,7 @@ import org.apache.commons.lang3.StringUtils;
*
* JTextField second = new JTextField();
* hbox.add(second);
* hbox.add(new JLabel("-"));
* hbox.add(new GLabel("-"));
* linker.linkField(second, "-", "-");
*
* JTextField third = new JTextField();
@ -859,39 +859,4 @@ public class TextFieldLinker {
return linker;
}
/**
* A demonstration of the {@link TextFieldLinker}
*
* It demonstrates three fields. The first two are separated by whitespace. The second two are
* separated by a dash.
*/
public static class TextFieldLinkerDemo {
public static void main(String[] args) {
JDialog dialog = new JDialog((Window) null, "TextFieldLinker Demo");
Box hbox = Box.createHorizontalBox();
dialog.add(hbox);
TextFieldLinker linker = new TextFieldLinker();
JTextField first = new JTextField();
hbox.add(first);
hbox.add(Box.createHorizontalStrut(10));
linker.linkField(first, "\\s+", " ");
JTextField second = new JTextField();
hbox.add(second);
hbox.add(new JLabel("-"));
linker.linkField(second, "-", "-");
JTextField third = new JTextField();
hbox.add(third);
linker.linkLastField(third);
dialog.setBounds(2560, 500, 400, 200);
dialog.setModal(true);
linker.setVisible(true);
dialog.setVisible(true);
}
}
}

View file

@ -26,6 +26,7 @@ import docking.DockingWindowManager;
import docking.help.HelpService;
import docking.widgets.EmptyBorderButton;
import docking.widgets.filter.*;
import docking.widgets.label.GLabel;
import docking.widgets.tree.internal.DefaultGTreeDataTransformer;
import docking.widgets.tree.support.GTreeFilter;
import ghidra.framework.options.PreferenceState;
@ -120,7 +121,7 @@ public class DefaultGTreeFilterProvider implements GTreeFilterProvider {
private JPanel createFilterPanel() {
JPanel newFilterPanel = new JPanel(new BorderLayout());
newFilterPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
JLabel filterLabel = new JLabel(" Filter: ");
JLabel filterLabel = new GLabel(" Filter: ");
newFilterPanel.add(filterLabel, BorderLayout.WEST);
filterField = new FilterTextField(gTree.getJTree());

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,54 +21,59 @@ import javax.swing.Icon;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
import docking.widgets.GComponent;
import docking.widgets.tree.GTree;
import docking.widgets.tree.GTreeNode;
public class GTreeRenderer extends DefaultTreeCellRenderer {
public class GTreeRenderer extends DefaultTreeCellRenderer implements GComponent {
private static final long serialVersionUID = 1L;
private static final Color VALID_DROP_TARGET_COLOR = new Color( 200, 200, 255 );
private static final Color VALID_DROP_TARGET_COLOR = new Color(200, 200, 255);
private static final int DEFAULT_MIN_ICON_WIDTH = 22;
private Object dropTarget;
private boolean paintDropTarget;
private Font cachedDefaultFont;
private Font cachedBoldFont;
private int minIconWidth = DEFAULT_MIN_ICON_WIDTH;
public GTreeRenderer() {
setHTMLRenderingEnabled(false);
}
/**
*
* @see javax.swing.tree.DefaultTreeCellRenderer#getTreeCellRendererComponent(javax.swing.JTree, java.lang.Object, boolean, boolean, boolean, int, boolean)
*/
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected1, boolean expanded, boolean leaf, int row, boolean hasFocus1) {
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected1,
boolean expanded, boolean leaf, int row, boolean hasFocus1) {
super.getTreeCellRendererComponent(tree, value, selected1, expanded, leaf, row, hasFocus1);
GTreeNode node = (GTreeNode)value;
super.getTreeCellRendererComponent(tree, value, selected1, expanded, leaf, row, hasFocus1);
GTreeNode node = (GTreeNode) value;
String text = node.getName();
setText(text);
setToolTipText(node.getToolTip());
Icon icon = node.getIcon(expanded);
if ( icon == null ) {
if (icon == null) {
icon = getIcon();
}
else {
setIcon( icon );
setIcon(icon);
}
updateIconTextGap(icon, minIconWidth);
paintDropTarget = (value==dropTarget);
paintDropTarget = (value == dropTarget);
GTree gtree = node.getTree();
GTreeFilter filter = gtree == null ? null : gtree.getFilter();
boolean isBold = (filter != null) && filter.showFilterMatches() && filter.acceptsNode(node);
setFont( getFont( isBold ) );
return this;
setFont(getFont(isBold));
return this;
}
protected void updateIconTextGap(Icon icon, int minWidth) {
@ -77,15 +81,15 @@ public class GTreeRenderer extends DefaultTreeCellRenderer {
if (icon != null) {
iconWidth = icon.getIconWidth();
}
setIconTextGap(Math.max(minWidth-iconWidth, 2));
setIconTextGap(Math.max(minWidth - iconWidth, 2));
}
@Override // overridden to recalculate icon text gaps
public void setIcon( Icon icon ) {
super.setIcon( icon );
updateIconTextGap( icon, minIconWidth );
public void setIcon(Icon icon) {
super.setIcon(icon);
updateIconTextGap(icon, minIconWidth);
}
public int getMinIconWidth() {
return minIconWidth;
}
@ -98,29 +102,29 @@ public class GTreeRenderer extends DefaultTreeCellRenderer {
private Font getFont(boolean bold) {
Font font = getFont();
// check if someone set a new font on the renderer
if ( font != cachedDefaultFont && font != cachedBoldFont ) {
if (font != cachedDefaultFont && font != cachedBoldFont) {
cachedDefaultFont = font;
// Bug Alert!:
// We must create a new font here and not use deriveFont(). Using derive font has
// bugs when calculating the string width for a bold derived font.
cachedBoldFont = new Font( font.getFamily(), Font.BOLD, font.getSize() );
cachedBoldFont = new Font(font.getFamily(), Font.BOLD, font.getSize());
}
return bold ? cachedBoldFont : cachedDefaultFont;
}
// our parent makes this call in the paint() method so we cannot just call setBackground() in
// getTreeCellRendererComponent(), but we must instead make sure that the paint() method gets
// the correct color
@Override
public Color getBackgroundNonSelectionColor() {
if ( paintDropTarget ) {
if (paintDropTarget) {
return VALID_DROP_TARGET_COLOR;
}
return super.getBackgroundNonSelectionColor();
}
public void setRendererDropTarget( Object target ) {
public void setRendererDropTarget(Object target) {
this.dropTarget = target;
}
}

View file

@ -28,6 +28,7 @@ import docking.DockingWindowManager;
import docking.help.Help;
import docking.help.HelpService;
import docking.widgets.EmptyBorderButton;
import docking.widgets.label.GDLabel;
import ghidra.util.*;
import resources.ResourceManager;
@ -215,8 +216,8 @@ public class WizardManager extends DialogComponentProvider implements WizardPane
}
});
titleLabel = (wizardIcon == null ? new JLabel(INIT_TITLE)
: new JLabel(INIT_TITLE, wizardIcon, SwingConstants.TRAILING));
titleLabel = (wizardIcon == null ? new GDLabel(INIT_TITLE)
: new GDLabel(INIT_TITLE, wizardIcon, SwingConstants.TRAILING));
EmptyBorderButton helpButton =
new EmptyBorderButton(ResourceManager.loadImage("images/information.png"));

View file

@ -16,8 +16,6 @@
package ghidra.util.task;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.*;
@ -26,6 +24,7 @@ import docking.DialogComponentProvider;
import docking.DockingWindowManager;
import docking.util.AnimatedIcon;
import docking.widgets.OptionDialog;
import docking.widgets.label.GIconLabel;
import ghidra.util.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.timer.GTimer;
@ -170,18 +169,13 @@ public class TaskDialog extends DialogComponentProvider implements TaskMonitor {
SystemUtilities.runIfSwingOrPostSwingLater(() -> {
mainPanel.removeAll();
List<Icon> iconList = new ArrayList<>();
iconList.add(ResourceManager.loadImage("images/eatbits1.png"));
iconList.add(ResourceManager.loadImage("images/eatbits2.png"));
iconList.add(ResourceManager.loadImage("images/eatbits3.png"));
iconList.add(ResourceManager.loadImage("images/eatbits4.png"));
iconList.add(ResourceManager.loadImage("images/eatbits5.png"));
iconList.add(ResourceManager.loadImage("images/eatbits6.png"));
iconList.add(ResourceManager.loadImage("images/eatbits7.png"));
AnimatedIcon icon = new AnimatedIcon(iconList, 200, 0);
JPanel panel = new JPanel(new BorderLayout());
panel.setSize(new Dimension(200, 100));
panel.add(new JLabel(icon));
String[] filenames = { "images/eatbits1.png", "images/eatbits2.png",
"images/eatbits3.png", "images/eatbits4.png", "images/eatbits5.png",
"images/eatbits6.png", "images/eatbits7.png" };
panel.add(
new GIconLabel(new AnimatedIcon(ResourceManager.loadImages(filenames), 200, 0)));
mainPanel.add(panel, BorderLayout.CENTER);
repack();

View file

@ -18,8 +18,6 @@ package ghidra.util.task;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@ -29,6 +27,8 @@ import docking.ToolTipManager;
import docking.util.AnimatedIcon;
import docking.widgets.EmptyBorderButton;
import docking.widgets.OptionDialog;
import docking.widgets.label.GDHtmlLabel;
import docking.widgets.label.GIconLabel;
import ghidra.util.Issue;
import ghidra.util.SystemUtilities;
import ghidra.util.datastruct.WeakDataStructureFactory;
@ -400,7 +400,7 @@ public class TaskMonitorComponent extends JPanel implements TaskMonitor {
private void buildProgressPanel(boolean includeTextField, boolean includeCancelButton) {
setLayout(new BorderLayout(5, 1));
messageLabel = new JLabel(" ") {
messageLabel = new GDHtmlLabel(" ") {
@Override
public void invalidate() {
// don't care
@ -465,63 +465,15 @@ public class TaskMonitorComponent extends JPanel implements TaskMonitor {
}
private void createAnimatedIcon() {
List<Icon> iconList = new ArrayList<>();
iconList.add(ResourceManager.loadImage("images/hourglass24_01.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_02.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_02.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_03.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_03.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_04.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_04.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_05.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_05.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_06.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_06.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_07.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_07.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_08.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_08.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_09.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_10.png"));
iconList.add(ResourceManager.loadImage("images/hourglass24_11.png"));
AnimatedIcon progressIcon = new AnimatedIcon(iconList, 150, 0);
imageLabel = new JLabel(progressIcon);
}
/**
* Simple test for the TaskMonitorComponent class.
* @param args not used
*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e) {
// don't care
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
final TaskMonitorComponent tm = new TaskMonitorComponent();
f.getContentPane().add(tm);
tm.showCancelButton(true);
f.pack();
f.setVisible(true);
// tm.initialize(78);
// TaskMonitor monitor = new UnknownProgressWrappingTaskMonitor(tm, 10);
//
// for (int i = 0; i < 78; i++) {
// try {
// Thread.sleep(250);
// monitor.setProgress(i);
// System.out.println("set progress to " + i);
// }
// catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
String[] filenames = { "images/hourglass24_01.png", "images/hourglass24_02.png",
"images/hourglass24_02.png", "images/hourglass24_03.png", "images/hourglass24_03.png",
"images/hourglass24_04.png", "images/hourglass24_04.png", "images/hourglass24_05.png",
"images/hourglass24_05.png", "images/hourglass24_06.png", "images/hourglass24_06.png",
"images/hourglass24_07.png", "images/hourglass24_07.png", "images/hourglass24_08.png",
"images/hourglass24_08.png", "images/hourglass24_09.png", "images/hourglass24_10.png",
"images/hourglass24_11.png" };
imageLabel =
new GIconLabel(new AnimatedIcon(ResourceManager.loadImages(filenames), 150, 0));
}
@Override