diff options
| author | 2022-09-14 13:12:55 +0100 | |
|---|---|---|
| committer | 2022-09-14 13:12:55 +0100 | |
| commit | 9c736848fb7aa82d295b3aa2946e6cd132ee998f (patch) | |
| tree | b982613cfa7201b2db25cb64a5950f9a2c34a5b3 /enigma-swing | |
| parent | Nested packages in Swing UI (#458) (diff) | |
| download | enigma-fork-9c736848fb7aa82d295b3aa2946e6cd132ee998f.tar.gz enigma-fork-9c736848fb7aa82d295b3aa2946e6cd132ee998f.tar.xz enigma-fork-9c736848fb7aa82d295b3aa2946e6cd132ee998f.zip | |
Add checkstyle (#460)
Diffstat (limited to 'enigma-swing')
79 files changed, 1757 insertions, 1390 deletions
diff --git a/enigma-swing/build.gradle b/enigma-swing/build.gradle index d783e95..a4a13d8 100644 --- a/enigma-swing/build.gradle +++ b/enigma-swing/build.gradle | |||
| @@ -1,18 +1,18 @@ | |||
| 1 | plugins { | 1 | plugins { |
| 2 | id 'application' | 2 | id 'application' |
| 3 | id 'com.github.johnrengelman.shadow' version '7.0.0' | 3 | id 'com.github.johnrengelman.shadow' version '7.0.0' |
| 4 | } | 4 | } |
| 5 | 5 | ||
| 6 | dependencies { | 6 | dependencies { |
| 7 | implementation project(':enigma') | 7 | implementation project(':enigma') |
| 8 | implementation project(':enigma-server') | 8 | implementation project(':enigma-server') |
| 9 | 9 | ||
| 10 | implementation 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3' | 10 | implementation 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3' |
| 11 | implementation 'com.formdev:flatlaf:1.6.1' | 11 | implementation 'com.formdev:flatlaf:1.6.1' |
| 12 | implementation 'com.formdev:flatlaf-extras:1.6.1' // for SVG icons | 12 | implementation 'com.formdev:flatlaf-extras:1.6.1' // for SVG icons |
| 13 | implementation 'de.sciss:syntaxpane:1.2.0' | 13 | implementation 'de.sciss:syntaxpane:1.2.0' |
| 14 | implementation 'com.github.lukeu:swing-dpi:0.9' | 14 | implementation 'com.github.lukeu:swing-dpi:0.9' |
| 15 | implementation 'org.drjekyll:fontchooser:2.5.2' | 15 | implementation 'org.drjekyll:fontchooser:2.5.2' |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | mainClassName = 'cuchaz.enigma.gui.Main' | 18 | mainClassName = 'cuchaz.enigma.gui.Main' |
| @@ -20,9 +20,9 @@ mainClassName = 'cuchaz.enigma.gui.Main' | |||
| 20 | jar.manifest.attributes 'Main-Class': mainClassName | 20 | jar.manifest.attributes 'Main-Class': mainClassName |
| 21 | 21 | ||
| 22 | publishing { | 22 | publishing { |
| 23 | publications { | 23 | publications { |
| 24 | shadow(MavenPublication) { publication -> | 24 | shadow(MavenPublication) { publication -> |
| 25 | publication.from components.java | 25 | publication.from components.java |
| 26 | } | 26 | } |
| 27 | } | 27 | } |
| 28 | } | 28 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/BrowserCaret.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/BrowserCaret.java index af105db..a213a59 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/BrowserCaret.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/BrowserCaret.java | |||
| @@ -1,20 +1,19 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| 14 | import javax.swing.text.DefaultCaret; | 14 | import javax.swing.text.DefaultCaret; |
| 15 | 15 | ||
| 16 | public class BrowserCaret extends DefaultCaret { | 16 | public class BrowserCaret extends DefaultCaret { |
| 17 | |||
| 18 | @Override | 17 | @Override |
| 19 | public boolean isSelectionVisible() { | 18 | public boolean isSelectionVisible() { |
| 20 | return true; | 19 | return true; |
| @@ -24,5 +23,4 @@ public class BrowserCaret extends DefaultCaret { | |||
| 24 | public boolean isVisible() { | 23 | public boolean isVisible() { |
| 25 | return true; | 24 | return true; |
| 26 | } | 25 | } |
| 27 | |||
| 28 | } | 26 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/ClassSelector.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/ClassSelector.java index b7d3c4e..4b9fa59 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/ClassSelector.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/ClassSelector.java | |||
| @@ -1,35 +1,43 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| 14 | import cuchaz.enigma.gui.node.ClassSelectorClassNode; | 14 | import java.awt.Component; |
| 15 | import cuchaz.enigma.gui.util.GuiUtil; | ||
| 16 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 17 | import cuchaz.enigma.utils.validation.ValidationContext; | ||
| 18 | |||
| 19 | import javax.swing.*; | ||
| 20 | import javax.swing.event.CellEditorListener; | ||
| 21 | import javax.swing.event.ChangeEvent; | ||
| 22 | import javax.swing.tree.*; | ||
| 23 | import java.awt.*; | ||
| 24 | import java.awt.event.KeyAdapter; | 15 | import java.awt.event.KeyAdapter; |
| 25 | import java.awt.event.KeyEvent; | 16 | import java.awt.event.KeyEvent; |
| 26 | import java.awt.event.MouseAdapter; | 17 | import java.awt.event.MouseAdapter; |
| 27 | import java.awt.event.MouseEvent; | 18 | import java.awt.event.MouseEvent; |
| 19 | import java.util.ArrayList; | ||
| 20 | import java.util.Collection; | ||
| 21 | import java.util.Comparator; | ||
| 22 | import java.util.EventObject; | ||
| 28 | import java.util.List; | 23 | import java.util.List; |
| 29 | import java.util.*; | ||
| 30 | 24 | ||
| 31 | public class ClassSelector extends JTree { | 25 | import javax.swing.JTree; |
| 26 | import javax.swing.event.CellEditorListener; | ||
| 27 | import javax.swing.event.ChangeEvent; | ||
| 28 | import javax.swing.tree.DefaultMutableTreeNode; | ||
| 29 | import javax.swing.tree.DefaultTreeCellEditor; | ||
| 30 | import javax.swing.tree.DefaultTreeCellRenderer; | ||
| 31 | import javax.swing.tree.DefaultTreeModel; | ||
| 32 | import javax.swing.tree.TreeNode; | ||
| 33 | import javax.swing.tree.TreePath; | ||
| 34 | |||
| 35 | import cuchaz.enigma.gui.node.ClassSelectorClassNode; | ||
| 36 | import cuchaz.enigma.gui.util.GuiUtil; | ||
| 37 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 38 | import cuchaz.enigma.utils.validation.ValidationContext; | ||
| 32 | 39 | ||
| 40 | public class ClassSelector extends JTree { | ||
| 33 | public static final Comparator<ClassEntry> DEOBF_CLASS_COMPARATOR = Comparator.comparing(ClassEntry::getFullName); | 41 | public static final Comparator<ClassEntry> DEOBF_CLASS_COMPARATOR = Comparator.comparing(ClassEntry::getFullName); |
| 34 | 42 | ||
| 35 | private final Comparator<ClassEntry> comparator; | 43 | private final Comparator<ClassEntry> comparator; |
| @@ -56,6 +64,7 @@ public class ClassSelector extends JTree { | |||
| 56 | if (selectionListener != null && event.getClickCount() == 2) { | 64 | if (selectionListener != null && event.getClickCount() == 2) { |
| 57 | // get the selected node | 65 | // get the selected node |
| 58 | TreePath path = getSelectionPath(); | 66 | TreePath path = getSelectionPath(); |
| 67 | |||
| 59 | if (path != null && path.getLastPathComponent() instanceof ClassSelectorClassNode node) { | 68 | if (path != null && path.getLastPathComponent() instanceof ClassSelectorClassNode node) { |
| 60 | selectionListener.onSelectClass(node.getObfEntry()); | 69 | selectionListener.onSelectClass(node.getObfEntry()); |
| 61 | } | 70 | } |
| @@ -121,23 +130,31 @@ public class ClassSelector extends JTree { | |||
| 121 | TreePath path = getSelectionPath(); | 130 | TreePath path = getSelectionPath(); |
| 122 | 131 | ||
| 123 | Object realPath = path.getLastPathComponent(); | 132 | Object realPath = path.getLastPathComponent(); |
| 133 | |||
| 124 | if (realPath instanceof DefaultMutableTreeNode node && data != null) { | 134 | if (realPath instanceof DefaultMutableTreeNode node && data != null) { |
| 125 | TreeNode parentNode = node.getParent(); | 135 | TreeNode parentNode = node.getParent(); |
| 126 | if (parentNode == null) | 136 | |
| 137 | if (parentNode == null) { | ||
| 127 | return; | 138 | return; |
| 139 | } | ||
| 140 | |||
| 128 | boolean allowEdit = true; | 141 | boolean allowEdit = true; |
| 142 | |||
| 129 | for (int i = 0; i < parentNode.getChildCount(); i++) { | 143 | for (int i = 0; i < parentNode.getChildCount(); i++) { |
| 130 | TreeNode childNode = parentNode.getChildAt(i); | 144 | TreeNode childNode = parentNode.getChildAt(i); |
| 145 | |||
| 131 | if (childNode != null && childNode.toString().equals(data) && childNode != node) { | 146 | if (childNode != null && childNode.toString().equals(data) && childNode != node) { |
| 132 | allowEdit = false; | 147 | allowEdit = false; |
| 133 | break; | 148 | break; |
| 134 | } | 149 | } |
| 135 | } | 150 | } |
| 151 | |||
| 136 | if (allowEdit && renameSelectionListener != null) { | 152 | if (allowEdit && renameSelectionListener != null) { |
| 137 | Object prevData = node.getUserObject(); | 153 | Object prevData = node.getUserObject(); |
| 138 | Object objectData = node.getUserObject() instanceof ClassEntry ? new ClassEntry(((ClassEntry) prevData).getPackageName() + "/" + data) : data; | 154 | Object objectData = node.getUserObject() instanceof ClassEntry ? new ClassEntry(((ClassEntry) prevData).getPackageName() + "/" + data) : data; |
| 139 | gui.validateImmediateAction(vc -> { | 155 | gui.validateImmediateAction(vc -> { |
| 140 | renameSelectionListener.onSelectionRename(vc, node.getUserObject(), objectData, node); | 156 | renameSelectionListener.onSelectionRename(vc, node.getUserObject(), objectData, node); |
| 157 | |||
| 141 | if (vc.canProceed()) { | 158 | if (vc.canProceed()) { |
| 142 | node.setUserObject(objectData); // Make sure that it's modified | 159 | node.setUserObject(objectData); // Make sure that it's modified |
| 143 | } else { | 160 | } else { |
| @@ -206,15 +223,19 @@ public class ClassSelector extends JTree { | |||
| 206 | public List<StateEntry> getExpansionState() { | 223 | public List<StateEntry> getExpansionState() { |
| 207 | List<StateEntry> state = new ArrayList<>(); | 224 | List<StateEntry> state = new ArrayList<>(); |
| 208 | int rowCount = getRowCount(); | 225 | int rowCount = getRowCount(); |
| 226 | |||
| 209 | for (int i = 0; i < rowCount; i++) { | 227 | for (int i = 0; i < rowCount; i++) { |
| 210 | TreePath path = getPathForRow(i); | 228 | TreePath path = getPathForRow(i); |
| 229 | |||
| 211 | if (isPathSelected(path)) { | 230 | if (isPathSelected(path)) { |
| 212 | state.add(new StateEntry(State.SELECTED, path)); | 231 | state.add(new StateEntry(State.SELECTED, path)); |
| 213 | } | 232 | } |
| 233 | |||
| 214 | if (isExpanded(path)) { | 234 | if (isExpanded(path)) { |
| 215 | state.add(new StateEntry(State.EXPANDED, path)); | 235 | state.add(new StateEntry(State.EXPANDED, path)); |
| 216 | } | 236 | } |
| 217 | } | 237 | } |
| 238 | |||
| 218 | return state; | 239 | return state; |
| 219 | } | 240 | } |
| 220 | 241 | ||
| @@ -223,8 +244,8 @@ public class ClassSelector extends JTree { | |||
| 223 | 244 | ||
| 224 | for (StateEntry entry : expansionState) { | 245 | for (StateEntry entry : expansionState) { |
| 225 | switch (entry.state) { | 246 | switch (entry.state) { |
| 226 | case SELECTED -> addSelectionPath(entry.path); | 247 | case SELECTED -> addSelectionPath(entry.path); |
| 227 | case EXPANDED -> expandPath(entry.path); | 248 | case EXPANDED -> expandPath(entry.path); |
| 228 | } | 249 | } |
| 229 | } | 250 | } |
| 230 | } | 251 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/EditableType.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/EditableType.java index 1e8d6cf..6028609 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/EditableType.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/EditableType.java | |||
| @@ -2,7 +2,11 @@ package cuchaz.enigma.gui; | |||
| 2 | 2 | ||
| 3 | import javax.annotation.Nullable; | 3 | import javax.annotation.Nullable; |
| 4 | 4 | ||
| 5 | import cuchaz.enigma.translation.representation.entry.*; | 5 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 6 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 7 | import cuchaz.enigma.translation.representation.entry.FieldEntry; | ||
| 8 | import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; | ||
| 9 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 6 | 10 | ||
| 7 | public enum EditableType { | 11 | public enum EditableType { |
| 8 | CLASS, | 12 | CLASS, |
| @@ -10,8 +14,7 @@ public enum EditableType { | |||
| 10 | FIELD, | 14 | FIELD, |
| 11 | PARAMETER, | 15 | PARAMETER, |
| 12 | LOCAL_VARIABLE, | 16 | LOCAL_VARIABLE, |
| 13 | JAVADOC, | 17 | JAVADOC; |
| 14 | ; | ||
| 15 | 18 | ||
| 16 | @Nullable | 19 | @Nullable |
| 17 | public static EditableType fromEntry(Entry<?> entry) { | 20 | public static EditableType fromEntry(Entry<?> entry) { |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/EnigmaQuickFindDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/EnigmaQuickFindDialog.java index c912be3..0af8f9c 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/EnigmaQuickFindDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/EnigmaQuickFindDialog.java | |||
| @@ -1,16 +1,22 @@ | |||
| 1 | package cuchaz.enigma.gui; | 1 | package cuchaz.enigma.gui; |
| 2 | 2 | ||
| 3 | import de.sciss.syntaxpane.actions.DocumentSearchData; | 3 | import java.awt.Component; |
| 4 | import de.sciss.syntaxpane.actions.gui.QuickFindDialog; | 4 | import java.awt.Container; |
| 5 | 5 | import java.awt.Point; | |
| 6 | import javax.swing.*; | ||
| 7 | import javax.swing.text.JTextComponent; | ||
| 8 | import java.awt.*; | ||
| 9 | import java.awt.event.KeyAdapter; | 6 | import java.awt.event.KeyAdapter; |
| 10 | import java.awt.event.KeyEvent; | 7 | import java.awt.event.KeyEvent; |
| 11 | import java.util.stream.IntStream; | 8 | import java.util.stream.IntStream; |
| 12 | import java.util.stream.Stream; | 9 | import java.util.stream.Stream; |
| 13 | 10 | ||
| 11 | import javax.swing.JButton; | ||
| 12 | import javax.swing.JTextField; | ||
| 13 | import javax.swing.JToolBar; | ||
| 14 | import javax.swing.SwingUtilities; | ||
| 15 | import javax.swing.text.JTextComponent; | ||
| 16 | |||
| 17 | import de.sciss.syntaxpane.actions.DocumentSearchData; | ||
| 18 | import de.sciss.syntaxpane.actions.gui.QuickFindDialog; | ||
| 19 | |||
| 14 | public class EnigmaQuickFindDialog extends QuickFindDialog { | 20 | public class EnigmaQuickFindDialog extends QuickFindDialog { |
| 15 | public EnigmaQuickFindDialog(JTextComponent target) { | 21 | public EnigmaQuickFindDialog(JTextComponent target) { |
| 16 | super(target, DocumentSearchData.getFromEditor(target)); | 22 | super(target, DocumentSearchData.getFromEditor(target)); |
| @@ -22,6 +28,7 @@ public class EnigmaQuickFindDialog extends QuickFindDialog { | |||
| 22 | @Override | 28 | @Override |
| 23 | public void keyPressed(KeyEvent e) { | 29 | public void keyPressed(KeyEvent e) { |
| 24 | super.keyPressed(e); | 30 | super.keyPressed(e); |
| 31 | |||
| 25 | if (e.getKeyCode() == KeyEvent.VK_ENTER) { | 32 | if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
| 26 | JToolBar toolBar = getToolBar(); | 33 | JToolBar toolBar = getToolBar(); |
| 27 | boolean next = !e.isShiftDown(); | 34 | boolean next = !e.isShiftDown(); |
| @@ -78,13 +85,10 @@ public class EnigmaQuickFindDialog extends QuickFindDialog { | |||
| 78 | } | 85 | } |
| 79 | 86 | ||
| 80 | private static Stream<Component> components(Container container) { | 87 | private static Stream<Component> components(Container container) { |
| 81 | return IntStream.range(0, container.getComponentCount()) | 88 | return IntStream.range(0, container.getComponentCount()).mapToObj(container::getComponent); |
| 82 | .mapToObj(container::getComponent); | ||
| 83 | } | 89 | } |
| 84 | 90 | ||
| 85 | private static <T extends Component> Stream<T> components(Container container, Class<T> type) { | 91 | private static <T extends Component> Stream<T> components(Container container, Class<T> type) { |
| 86 | return components(container) | 92 | return components(container).filter(type::isInstance).map(type::cast); |
| 87 | .filter(type::isInstance) | ||
| 88 | .map(type::cast); | ||
| 89 | } | 93 | } |
| 90 | } | 94 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/EnigmaSyntaxKit.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/EnigmaSyntaxKit.java index 43745dd..b81782e 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/EnigmaSyntaxKit.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/EnigmaSyntaxKit.java | |||
| @@ -10,7 +10,6 @@ import de.sciss.syntaxpane.util.Configuration; | |||
| 10 | import cuchaz.enigma.gui.config.UiConfig; | 10 | import cuchaz.enigma.gui.config.UiConfig; |
| 11 | 11 | ||
| 12 | public class EnigmaSyntaxKit extends JavaSyntaxKit { | 12 | public class EnigmaSyntaxKit extends JavaSyntaxKit { |
| 13 | |||
| 14 | private static Configuration configuration = null; | 13 | private static Configuration configuration = null; |
| 15 | 14 | ||
| 16 | @Override | 15 | @Override |
| @@ -18,23 +17,20 @@ public class EnigmaSyntaxKit extends JavaSyntaxKit { | |||
| 18 | if (configuration == null) { | 17 | if (configuration == null) { |
| 19 | initConfig(DefaultSyntaxKit.getConfig(JavaSyntaxKit.class)); | 18 | initConfig(DefaultSyntaxKit.getConfig(JavaSyntaxKit.class)); |
| 20 | } | 19 | } |
| 20 | |||
| 21 | return configuration; | 21 | return configuration; |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | public void initConfig(Configuration baseConfig) { | 24 | public void initConfig(Configuration baseConfig) { |
| 25 | configuration = flattenConfiguration(baseConfig, EnigmaSyntaxKit.class); | 25 | configuration = flattenConfiguration(baseConfig, EnigmaSyntaxKit.class); |
| 26 | 26 | ||
| 27 | // Remove all actions except a select few because they disregard the | 27 | // Remove all actions except a select few because they disregard the |
| 28 | // editable state of the editor, or at least are useless anyway because | 28 | // editable state of the editor, or at least are useless anyway because |
| 29 | // they would try editing the file. | 29 | // they would try editing the file. |
| 30 | // Also includes the Action.insert-date action which is written in | 30 | // Also includes the Action.insert-date action which is written in |
| 31 | // Javascript and causes the editor to freeze on first load for a short | 31 | // Javascript and causes the editor to freeze on first load for a short |
| 32 | // time. | 32 | // time. |
| 33 | configuration.keySet().removeIf(s -> s.startsWith("Action.") && | 33 | configuration.keySet().removeIf(s -> s.startsWith("Action.") && !(s.startsWith("Action.find") || s.startsWith("Action.goto-line") || s.startsWith("Action.jump-to-pair") || s.startsWith("Action.quick-find"))); |
| 34 | !(s.startsWith("Action.find") || | ||
| 35 | s.startsWith("Action.goto-line") || | ||
| 36 | s.startsWith("Action.jump-to-pair") || | ||
| 37 | s.startsWith("Action.quick-find"))); | ||
| 38 | 34 | ||
| 39 | // See de.sciss.syntaxpane.TokenType | 35 | // See de.sciss.syntaxpane.TokenType |
| 40 | configuration.put("Style.KEYWORD", String.format("%d, 0", UiConfig.getHighlightColor().getRGB())); | 36 | configuration.put("Style.KEYWORD", String.format("%d, 0", UiConfig.getHighlightColor().getRGB())); |
| @@ -59,27 +55,28 @@ public class EnigmaSyntaxKit extends JavaSyntaxKit { | |||
| 59 | 55 | ||
| 60 | Font editorFont = UiConfig.activeUseCustomFonts() ? UiConfig.getEditorFont() : UiConfig.getFallbackEditorFont(); | 56 | Font editorFont = UiConfig.activeUseCustomFonts() ? UiConfig.getEditorFont() : UiConfig.getFallbackEditorFont(); |
| 61 | configuration.put("DefaultFont", UiConfig.encodeFont(editorFont)); | 57 | configuration.put("DefaultFont", UiConfig.encodeFont(editorFont)); |
| 62 | } | 58 | } |
| 59 | |||
| 60 | /** | ||
| 61 | * Creates a new configuration from the passed configuration so that it has | ||
| 62 | * no parents and all its values are on the same level. This is needed since | ||
| 63 | * there is no way to remove map entries from parent configurations. | ||
| 64 | * | ||
| 65 | * @param source the configuration to flatten | ||
| 66 | * @param configClass the class for the new configuration | ||
| 67 | * @return a new configuration | ||
| 68 | */ | ||
| 69 | private static Configuration flattenConfiguration(Configuration source, Class<?> configClass) { | ||
| 70 | Configuration config = new Configuration(configClass, null); | ||
| 63 | 71 | ||
| 64 | /** | 72 | for (String p : source.stringPropertyNames()) { |
| 65 | * Creates a new configuration from the passed configuration so that it has | 73 | config.put(p, source.getString(p)); |
| 66 | * no parents and all its values are on the same level. This is needed since | 74 | } |
| 67 | * there is no way to remove map entries from parent configurations. | 75 | |
| 68 | * | 76 | return config; |
| 69 | * @param source the configuration to flatten | ||
| 70 | * @param configClass the class for the new configuration | ||
| 71 | * @return a new configuration | ||
| 72 | */ | ||
| 73 | private static Configuration flattenConfiguration(Configuration source, Class<?> configClass) { | ||
| 74 | Configuration config = new Configuration(configClass, null); | ||
| 75 | for (String p : source.stringPropertyNames()) { | ||
| 76 | config.put(p, source.getString(p)); | ||
| 77 | } | ||
| 78 | return config; | ||
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | public static void invalidate() { | 79 | public static void invalidate() { |
| 82 | configuration = null; | 80 | configuration = null; |
| 83 | } | 81 | } |
| 84 | |||
| 85 | } | 82 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/ExceptionIgnorer.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/ExceptionIgnorer.java index 6246192..76d1859 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/ExceptionIgnorer.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/ExceptionIgnorer.java | |||
| @@ -1,28 +1,27 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| 14 | public class ExceptionIgnorer { | 14 | public class ExceptionIgnorer { |
| 15 | |||
| 16 | public static boolean shouldIgnore(Throwable t) { | 15 | public static boolean shouldIgnore(Throwable t) { |
| 17 | |||
| 18 | // is this that pesky concurrent access bug in the highlight painter system? | 16 | // is this that pesky concurrent access bug in the highlight painter system? |
| 19 | // (ancient ui code is ancient) | 17 | // (ancient ui code is ancient) |
| 20 | if (t instanceof ArrayIndexOutOfBoundsException) { | 18 | if (t instanceof ArrayIndexOutOfBoundsException) { |
| 21 | StackTraceElement[] stackTrace = t.getStackTrace(); | 19 | StackTraceElement[] stackTrace = t.getStackTrace(); |
| 22 | if (stackTrace.length > 1) { | ||
| 23 | 20 | ||
| 21 | if (stackTrace.length > 1) { | ||
| 24 | // does this stack frame match javax.swing.text.DefaultHighlighter.paint*() ? | 22 | // does this stack frame match javax.swing.text.DefaultHighlighter.paint*() ? |
| 25 | StackTraceElement frame = stackTrace[1]; | 23 | StackTraceElement frame = stackTrace[1]; |
| 24 | |||
| 26 | if (frame.getClassName().equals("javax.swing.text.DefaultHighlighter") && frame.getMethodName().startsWith("paint")) { | 25 | if (frame.getClassName().equals("javax.swing.text.DefaultHighlighter") && frame.getMethodName().startsWith("paint")) { |
| 27 | return true; | 26 | return true; |
| 28 | } | 27 | } |
| @@ -31,5 +30,4 @@ public class ExceptionIgnorer { | |||
| 31 | 30 | ||
| 32 | return false; | 31 | return false; |
| 33 | } | 32 | } |
| 34 | |||
| 35 | } | 33 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java index 5a1e3d8..b3117ce 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| @@ -17,7 +17,6 @@ import java.awt.Point; | |||
| 17 | import java.awt.event.ActionEvent; | 17 | import java.awt.event.ActionEvent; |
| 18 | import java.nio.file.Path; | 18 | import java.nio.file.Path; |
| 19 | import java.util.Collection; | 19 | import java.util.Collection; |
| 20 | import java.util.Collections; | ||
| 21 | import java.util.List; | 20 | import java.util.List; |
| 22 | import java.util.Set; | 21 | import java.util.Set; |
| 23 | import java.util.concurrent.CompletableFuture; | 22 | import java.util.concurrent.CompletableFuture; |
| @@ -25,12 +24,23 @@ import java.util.function.Consumer; | |||
| 25 | import java.util.function.Function; | 24 | import java.util.function.Function; |
| 26 | 25 | ||
| 27 | import javax.annotation.Nullable; | 26 | import javax.annotation.Nullable; |
| 28 | import javax.swing.*; | 27 | import javax.swing.AbstractAction; |
| 28 | import javax.swing.DefaultListModel; | ||
| 29 | import javax.swing.JButton; | ||
| 30 | import javax.swing.JFileChooser; | ||
| 31 | import javax.swing.JFrame; | ||
| 32 | import javax.swing.JLabel; | ||
| 33 | import javax.swing.JList; | ||
| 34 | import javax.swing.JOptionPane; | ||
| 35 | import javax.swing.JPanel; | ||
| 36 | import javax.swing.JScrollBar; | ||
| 37 | import javax.swing.JScrollPane; | ||
| 38 | import javax.swing.JSplitPane; | ||
| 39 | import javax.swing.JTabbedPane; | ||
| 40 | import javax.swing.JTextField; | ||
| 41 | import javax.swing.SwingUtilities; | ||
| 42 | import javax.swing.WindowConstants; | ||
| 29 | import javax.swing.tree.DefaultMutableTreeNode; | 43 | import javax.swing.tree.DefaultMutableTreeNode; |
| 30 | import javax.swing.tree.TreeNode; | ||
| 31 | import javax.swing.tree.TreePath; | ||
| 32 | |||
| 33 | import com.google.common.collect.Lists; | ||
| 34 | 44 | ||
| 35 | import cuchaz.enigma.Enigma; | 45 | import cuchaz.enigma.Enigma; |
| 36 | import cuchaz.enigma.EnigmaProfile; | 46 | import cuchaz.enigma.EnigmaProfile; |
| @@ -39,8 +49,19 @@ import cuchaz.enigma.gui.config.Themes; | |||
| 39 | import cuchaz.enigma.gui.config.UiConfig; | 49 | import cuchaz.enigma.gui.config.UiConfig; |
| 40 | import cuchaz.enigma.gui.dialog.JavadocDialog; | 50 | import cuchaz.enigma.gui.dialog.JavadocDialog; |
| 41 | import cuchaz.enigma.gui.dialog.SearchDialog; | 51 | import cuchaz.enigma.gui.dialog.SearchDialog; |
| 42 | import cuchaz.enigma.gui.elements.*; | 52 | import cuchaz.enigma.gui.elements.CallsTree; |
| 43 | import cuchaz.enigma.gui.panels.*; | 53 | import cuchaz.enigma.gui.elements.CollapsibleTabbedPane; |
| 54 | import cuchaz.enigma.gui.elements.EditorTabbedPane; | ||
| 55 | import cuchaz.enigma.gui.elements.ImplementationsTree; | ||
| 56 | import cuchaz.enigma.gui.elements.InheritanceTree; | ||
| 57 | import cuchaz.enigma.gui.elements.MainWindow; | ||
| 58 | import cuchaz.enigma.gui.elements.MenuBar; | ||
| 59 | import cuchaz.enigma.gui.elements.ValidatableUi; | ||
| 60 | import cuchaz.enigma.gui.panels.DeobfPanel; | ||
| 61 | import cuchaz.enigma.gui.panels.EditorPanel; | ||
| 62 | import cuchaz.enigma.gui.panels.IdentifierPanel; | ||
| 63 | import cuchaz.enigma.gui.panels.ObfPanel; | ||
| 64 | import cuchaz.enigma.gui.panels.StructurePanel; | ||
| 44 | import cuchaz.enigma.gui.renderer.MessageListCellRenderer; | 65 | import cuchaz.enigma.gui.renderer.MessageListCellRenderer; |
| 45 | import cuchaz.enigma.gui.util.GuiUtil; | 66 | import cuchaz.enigma.gui.util.GuiUtil; |
| 46 | import cuchaz.enigma.gui.util.LanguageUtil; | 67 | import cuchaz.enigma.gui.util.LanguageUtil; |
| @@ -57,7 +78,6 @@ import cuchaz.enigma.utils.validation.ParameterizedMessage; | |||
| 57 | import cuchaz.enigma.utils.validation.ValidationContext; | 78 | import cuchaz.enigma.utils.validation.ValidationContext; |
| 58 | 79 | ||
| 59 | public class Gui { | 80 | public class Gui { |
| 60 | |||
| 61 | private final MainWindow mainWindow = new MainWindow(Enigma.NAME); | 81 | private final MainWindow mainWindow = new MainWindow(Enigma.NAME); |
| 62 | private final GuiController controller; | 82 | private final GuiController controller; |
| 63 | 83 | ||
| @@ -179,6 +199,7 @@ public class Gui { | |||
| 179 | 199 | ||
| 180 | // restore state | 200 | // restore state |
| 181 | int[] layout = UiConfig.getLayout(); | 201 | int[] layout = UiConfig.getLayout(); |
| 202 | |||
| 182 | if (layout.length >= 4) { | 203 | if (layout.length >= 4) { |
| 183 | this.splitClasses.setDividerLocation(layout[0]); | 204 | this.splitClasses.setDividerLocation(layout[0]); |
| 184 | this.splitCenter.setDividerLocation(layout[1]); | 205 | this.splitCenter.setDividerLocation(layout[1]); |
| @@ -200,6 +221,7 @@ public class Gui { | |||
| 200 | frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); | 221 | frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); |
| 201 | 222 | ||
| 202 | Point windowPos = UiConfig.getWindowPos("Main Window", null); | 223 | Point windowPos = UiConfig.getWindowPos("Main Window", null); |
| 224 | |||
| 203 | if (windowPos != null) { | 225 | if (windowPos != null) { |
| 204 | frame.setLocation(windowPos); | 226 | frame.setLocation(windowPos); |
| 205 | } else { | 227 | } else { |
| @@ -327,18 +349,26 @@ public class Gui { | |||
| 327 | 349 | ||
| 328 | public void startDocChange(EditorPanel editor) { | 350 | public void startDocChange(EditorPanel editor) { |
| 329 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); | 351 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); |
| 330 | if (cursorReference == null || !this.isEditable(EditableType.JAVADOC)) return; | 352 | |
| 353 | if (cursorReference == null || !this.isEditable(EditableType.JAVADOC)) { | ||
| 354 | return; | ||
| 355 | } | ||
| 356 | |||
| 331 | JavadocDialog.show(mainWindow.frame(), getController(), cursorReference); | 357 | JavadocDialog.show(mainWindow.frame(), getController(), cursorReference); |
| 332 | } | 358 | } |
| 333 | 359 | ||
| 334 | public void startRename(EditorPanel editor, String text) { | 360 | public void startRename(EditorPanel editor, String text) { |
| 335 | if (editor != this.editorTabbedPane.getActiveEditor()) return; | 361 | if (editor != this.editorTabbedPane.getActiveEditor()) { |
| 362 | return; | ||
| 363 | } | ||
| 336 | 364 | ||
| 337 | infoPanel.startRenaming(text); | 365 | infoPanel.startRenaming(text); |
| 338 | } | 366 | } |
| 339 | 367 | ||
| 340 | public void startRename(EditorPanel editor) { | 368 | public void startRename(EditorPanel editor) { |
| 341 | if (editor != this.editorTabbedPane.getActiveEditor()) return; | 369 | if (editor != this.editorTabbedPane.getActiveEditor()) { |
| 370 | return; | ||
| 371 | } | ||
| 342 | 372 | ||
| 343 | infoPanel.startRenaming(); | 373 | infoPanel.startRenaming(); |
| 344 | } | 374 | } |
| @@ -349,7 +379,10 @@ public class Gui { | |||
| 349 | 379 | ||
| 350 | public void showInheritance(EditorPanel editor) { | 380 | public void showInheritance(EditorPanel editor) { |
| 351 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); | 381 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); |
| 352 | if (cursorReference == null) return; | 382 | |
| 383 | if (cursorReference == null) { | ||
| 384 | return; | ||
| 385 | } | ||
| 353 | 386 | ||
| 354 | this.inheritanceTree.display(cursorReference.entry); | 387 | this.inheritanceTree.display(cursorReference.entry); |
| 355 | tabs.setSelectedIndex(1); | 388 | tabs.setSelectedIndex(1); |
| @@ -357,7 +390,10 @@ public class Gui { | |||
| 357 | 390 | ||
| 358 | public void showImplementations(EditorPanel editor) { | 391 | public void showImplementations(EditorPanel editor) { |
| 359 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); | 392 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); |
| 360 | if (cursorReference == null) return; | 393 | |
| 394 | if (cursorReference == null) { | ||
| 395 | return; | ||
| 396 | } | ||
| 361 | 397 | ||
| 362 | this.implementationsTree.display(cursorReference.entry); | 398 | this.implementationsTree.display(cursorReference.entry); |
| 363 | tabs.setSelectedIndex(2); | 399 | tabs.setSelectedIndex(2); |
| @@ -365,7 +401,10 @@ public class Gui { | |||
| 365 | 401 | ||
| 366 | public void showCalls(EditorPanel editor, boolean recurse) { | 402 | public void showCalls(EditorPanel editor, boolean recurse) { |
| 367 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); | 403 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); |
| 368 | if (cursorReference == null) return; | 404 | |
| 405 | if (cursorReference == null) { | ||
| 406 | return; | ||
| 407 | } | ||
| 369 | 408 | ||
| 370 | this.callsTree.showCalls(cursorReference.entry, recurse); | 409 | this.callsTree.showCalls(cursorReference.entry, recurse); |
| 371 | tabs.setSelectedIndex(3); | 410 | tabs.setSelectedIndex(3); |
| @@ -373,7 +412,10 @@ public class Gui { | |||
| 373 | 412 | ||
| 374 | public void toggleMapping(EditorPanel editor) { | 413 | public void toggleMapping(EditorPanel editor) { |
| 375 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); | 414 | EntryReference<Entry<?>, Entry<?>> cursorReference = editor.getCursorReference(); |
| 376 | if (cursorReference == null) return; | 415 | |
| 416 | if (cursorReference == null) { | ||
| 417 | return; | ||
| 418 | } | ||
| 377 | 419 | ||
| 378 | Entry<?> obfEntry = cursorReference.entry; | 420 | Entry<?> obfEntry = cursorReference.entry; |
| 379 | toggleMappingFromEntry(obfEntry); | 421 | toggleMappingFromEntry(obfEntry); |
| @@ -388,14 +430,15 @@ public class Gui { | |||
| 388 | } | 430 | } |
| 389 | 431 | ||
| 390 | public void showDiscardDiag(Function<Integer, Void> callback, String... options) { | 432 | public void showDiscardDiag(Function<Integer, Void> callback, String... options) { |
| 391 | int response = JOptionPane.showOptionDialog(this.mainWindow.frame(), I18n.translate("prompt.close.summary"), I18n.translate("prompt.close.title"), JOptionPane.YES_NO_CANCEL_OPTION, | 433 | int response = JOptionPane.showOptionDialog(this.mainWindow.frame(), I18n.translate("prompt.close.summary"), I18n.translate("prompt.close.title"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]); |
| 392 | JOptionPane.QUESTION_MESSAGE, null, options, options[2]); | ||
| 393 | callback.apply(response); | 434 | callback.apply(response); |
| 394 | } | 435 | } |
| 395 | 436 | ||
| 396 | public CompletableFuture<Void> saveMapping() { | 437 | public CompletableFuture<Void> saveMapping() { |
| 397 | if (this.enigmaMappingsFileChooser.getSelectedFile() != null || this.enigmaMappingsFileChooser.showSaveDialog(this.mainWindow.frame()) == JFileChooser.APPROVE_OPTION) | 438 | if (this.enigmaMappingsFileChooser.getSelectedFile() != null || this.enigmaMappingsFileChooser.showSaveDialog(this.mainWindow.frame()) == JFileChooser.APPROVE_OPTION) { |
| 398 | return this.controller.saveMappings(this.enigmaMappingsFileChooser.getSelectedFile().toPath()); | 439 | return this.controller.saveMappings(this.enigmaMappingsFileChooser.getSelectedFile().toPath()); |
| 440 | } | ||
| 441 | |||
| 399 | return CompletableFuture.completedFuture(null); | 442 | return CompletableFuture.completedFuture(null); |
| 400 | } | 443 | } |
| 401 | 444 | ||
| @@ -421,16 +464,13 @@ public class Gui { | |||
| 421 | private void exit() { | 464 | private void exit() { |
| 422 | UiConfig.setWindowPos("Main Window", this.mainWindow.frame().getLocationOnScreen()); | 465 | UiConfig.setWindowPos("Main Window", this.mainWindow.frame().getLocationOnScreen()); |
| 423 | UiConfig.setWindowSize("Main Window", this.mainWindow.frame().getSize()); | 466 | UiConfig.setWindowSize("Main Window", this.mainWindow.frame().getSize()); |
| 424 | UiConfig.setLayout( | 467 | UiConfig.setLayout(this.splitClasses.getDividerLocation(), this.splitCenter.getDividerLocation(), this.splitRight.getDividerLocation(), this.logSplit.getDividerLocation()); |
| 425 | this.splitClasses.getDividerLocation(), | ||
| 426 | this.splitCenter.getDividerLocation(), | ||
| 427 | this.splitRight.getDividerLocation(), | ||
| 428 | this.logSplit.getDividerLocation()); | ||
| 429 | UiConfig.save(); | 468 | UiConfig.save(); |
| 430 | 469 | ||
| 431 | if (searchDialog != null) { | 470 | if (searchDialog != null) { |
| 432 | searchDialog.dispose(); | 471 | searchDialog.dispose(); |
| 433 | } | 472 | } |
| 473 | |||
| 434 | this.mainWindow.frame().dispose(); | 474 | this.mainWindow.frame().dispose(); |
| 435 | System.exit(0); | 475 | System.exit(0); |
| 436 | } | 476 | } |
| @@ -452,6 +492,7 @@ public class Gui { | |||
| 452 | 492 | ||
| 453 | onRenameFromClassTree(vc, prevDataChild, dataChild, node); | 493 | onRenameFromClassTree(vc, prevDataChild, dataChild, node); |
| 454 | } | 494 | } |
| 495 | |||
| 455 | node.setUserObject(data); | 496 | node.setUserObject(data); |
| 456 | // Ob package will never be modified, just reload deob view | 497 | // Ob package will never be modified, just reload deob view |
| 457 | this.deobfPanel.deobfClasses.reload(); | 498 | this.deobfPanel.deobfClasses.reload(); |
| @@ -462,11 +503,7 @@ public class Gui { | |||
| 462 | // fast enough for now | 503 | // fast enough for now |
| 463 | EntryRemapper mapper = this.controller.project.getMapper(); | 504 | EntryRemapper mapper = this.controller.project.getMapper(); |
| 464 | ClassEntry deobf = (ClassEntry) prevData; | 505 | ClassEntry deobf = (ClassEntry) prevData; |
| 465 | ClassEntry obf = mapper.getObfToDeobf().getAllEntries() | 506 | ClassEntry obf = mapper.getObfToDeobf().getAllEntries().filter(e -> e instanceof ClassEntry).map(e -> (ClassEntry) e).filter(e -> mapper.deobfuscate(e).equals(deobf)).findAny().orElse(deobf); |
| 466 | .filter(e -> e instanceof ClassEntry) | ||
| 467 | .map(e -> (ClassEntry) e) | ||
| 468 | .filter(e -> mapper.deobfuscate(e).equals(deobf)) | ||
| 469 | .findAny().orElse(deobf); | ||
| 470 | 507 | ||
| 471 | this.controller.applyChange(vc, EntryChange.modify(obf).withDeobfName(((ClassEntry) data).getFullName())); | 508 | this.controller.applyChange(vc, EntryChange.modify(obf).withDeobfName(((ClassEntry) data).getFullName())); |
| 472 | } else { | 509 | } else { |
| @@ -493,16 +530,12 @@ public class Gui { | |||
| 493 | this.obfPanel.obfClasses.removeEntry(classEntry); | 530 | this.obfPanel.obfClasses.removeEntry(classEntry); |
| 494 | this.deobfPanel.deobfClasses.reload(); | 531 | this.deobfPanel.deobfClasses.reload(); |
| 495 | this.obfPanel.obfClasses.reload(); | 532 | this.obfPanel.obfClasses.reload(); |
| 496 | } | 533 | } else if (!isOldOb) { // Deob -> ob |
| 497 | // Deob -> ob | ||
| 498 | else if (!isOldOb) { | ||
| 499 | this.obfPanel.obfClasses.moveClassIn(classEntry); | 534 | this.obfPanel.obfClasses.moveClassIn(classEntry); |
| 500 | this.deobfPanel.deobfClasses.removeEntry(classEntry); | 535 | this.deobfPanel.deobfClasses.removeEntry(classEntry); |
| 501 | this.deobfPanel.deobfClasses.reload(); | 536 | this.deobfPanel.deobfClasses.reload(); |
| 502 | this.obfPanel.obfClasses.reload(); | 537 | this.obfPanel.obfClasses.reload(); |
| 503 | } | 538 | } else if (isOldOb) { // Local move |
| 504 | // Local move | ||
| 505 | else if (isOldOb) { | ||
| 506 | this.obfPanel.obfClasses.moveClassIn(classEntry); | 539 | this.obfPanel.obfClasses.moveClassIn(classEntry); |
| 507 | this.obfPanel.obfClasses.reload(); | 540 | this.obfPanel.obfClasses.reload(); |
| 508 | } else { | 541 | } else { |
| @@ -526,6 +559,7 @@ public class Gui { | |||
| 526 | if (searchDialog == null) { | 559 | if (searchDialog == null) { |
| 527 | searchDialog = new SearchDialog(this); | 560 | searchDialog = new SearchDialog(this); |
| 528 | } | 561 | } |
| 562 | |||
| 529 | return searchDialog; | 563 | return searchDialog; |
| 530 | } | 564 | } |
| 531 | 565 | ||
| @@ -549,9 +583,11 @@ public class Gui { | |||
| 549 | 583 | ||
| 550 | private void sendMessage() { | 584 | private void sendMessage() { |
| 551 | String text = chatBox.getText().trim(); | 585 | String text = chatBox.getText().trim(); |
| 586 | |||
| 552 | if (!text.isEmpty()) { | 587 | if (!text.isEmpty()) { |
| 553 | getController().sendPacket(new MessageC2SPacket(text)); | 588 | getController().sendPacket(new MessageC2SPacket(text)); |
| 554 | } | 589 | } |
| 590 | |||
| 555 | chatBox.setText(""); | 591 | chatBox.setText(""); |
| 556 | } | 592 | } |
| 557 | 593 | ||
| @@ -617,16 +653,17 @@ public class Gui { | |||
| 617 | public boolean validateImmediateAction(Consumer<ValidationContext> op) { | 653 | public boolean validateImmediateAction(Consumer<ValidationContext> op) { |
| 618 | ValidationContext vc = new ValidationContext(); | 654 | ValidationContext vc = new ValidationContext(); |
| 619 | op.accept(vc); | 655 | op.accept(vc); |
| 656 | |||
| 620 | if (!vc.canProceed()) { | 657 | if (!vc.canProceed()) { |
| 621 | List<ParameterizedMessage> messages = vc.getMessages(); | 658 | List<ParameterizedMessage> messages = vc.getMessages(); |
| 622 | String text = ValidatableUi.formatMessages(messages); | 659 | String text = ValidatableUi.formatMessages(messages); |
| 623 | JOptionPane.showMessageDialog(this.getFrame(), text, String.format("%d message(s)", messages.size()), JOptionPane.ERROR_MESSAGE); | 660 | JOptionPane.showMessageDialog(this.getFrame(), text, String.format("%d message(s)", messages.size()), JOptionPane.ERROR_MESSAGE); |
| 624 | } | 661 | } |
| 662 | |||
| 625 | return vc.canProceed(); | 663 | return vc.canProceed(); |
| 626 | } | 664 | } |
| 627 | 665 | ||
| 628 | public boolean isEditable(EditableType t) { | 666 | public boolean isEditable(EditableType t) { |
| 629 | return this.editableTypes.contains(t); | 667 | return this.editableTypes.contains(t); |
| 630 | } | 668 | } |
| 631 | |||
| 632 | } | 669 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java index 47a854f..0eb9a16 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| @@ -32,7 +32,17 @@ import com.google.common.collect.Lists; | |||
| 32 | import cuchaz.enigma.Enigma; | 32 | import cuchaz.enigma.Enigma; |
| 33 | import cuchaz.enigma.EnigmaProfile; | 33 | import cuchaz.enigma.EnigmaProfile; |
| 34 | import cuchaz.enigma.EnigmaProject; | 34 | import cuchaz.enigma.EnigmaProject; |
| 35 | import cuchaz.enigma.analysis.*; | 35 | import cuchaz.enigma.analysis.ClassImplementationsTreeNode; |
| 36 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; | ||
| 37 | import cuchaz.enigma.analysis.ClassReferenceTreeNode; | ||
| 38 | import cuchaz.enigma.analysis.EntryReference; | ||
| 39 | import cuchaz.enigma.analysis.FieldReferenceTreeNode; | ||
| 40 | import cuchaz.enigma.analysis.IndexTreeBuilder; | ||
| 41 | import cuchaz.enigma.analysis.MethodImplementationsTreeNode; | ||
| 42 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; | ||
| 43 | import cuchaz.enigma.analysis.MethodReferenceTreeNode; | ||
| 44 | import cuchaz.enigma.analysis.StructureTreeNode; | ||
| 45 | import cuchaz.enigma.analysis.StructureTreeOptions; | ||
| 36 | import cuchaz.enigma.api.service.ObfuscationTestService; | 46 | import cuchaz.enigma.api.service.ObfuscationTestService; |
| 37 | import cuchaz.enigma.classhandle.ClassHandle; | 47 | import cuchaz.enigma.classhandle.ClassHandle; |
| 38 | import cuchaz.enigma.classhandle.ClassHandleProvider; | 48 | import cuchaz.enigma.classhandle.ClassHandleProvider; |
| @@ -44,7 +54,12 @@ import cuchaz.enigma.gui.newabstraction.EntryValidation; | |||
| 44 | import cuchaz.enigma.gui.stats.StatsGenerator; | 54 | import cuchaz.enigma.gui.stats.StatsGenerator; |
| 45 | import cuchaz.enigma.gui.stats.StatsMember; | 55 | import cuchaz.enigma.gui.stats.StatsMember; |
| 46 | import cuchaz.enigma.gui.util.History; | 56 | import cuchaz.enigma.gui.util.History; |
| 47 | import cuchaz.enigma.network.*; | 57 | import cuchaz.enigma.network.ClientPacketHandler; |
| 58 | import cuchaz.enigma.network.EnigmaClient; | ||
| 59 | import cuchaz.enigma.network.EnigmaServer; | ||
| 60 | import cuchaz.enigma.network.IntegratedEnigmaServer; | ||
| 61 | import cuchaz.enigma.network.Message; | ||
| 62 | import cuchaz.enigma.network.ServerPacketHandler; | ||
| 48 | import cuchaz.enigma.network.packet.EntryChangeC2SPacket; | 63 | import cuchaz.enigma.network.packet.EntryChangeC2SPacket; |
| 49 | import cuchaz.enigma.network.packet.LoginC2SPacket; | 64 | import cuchaz.enigma.network.packet.LoginC2SPacket; |
| 50 | import cuchaz.enigma.network.packet.Packet; | 65 | import cuchaz.enigma.network.packet.Packet; |
| @@ -54,7 +69,12 @@ import cuchaz.enigma.source.SourceIndex; | |||
| 54 | import cuchaz.enigma.source.Token; | 69 | import cuchaz.enigma.source.Token; |
| 55 | import cuchaz.enigma.translation.TranslateResult; | 70 | import cuchaz.enigma.translation.TranslateResult; |
| 56 | import cuchaz.enigma.translation.Translator; | 71 | import cuchaz.enigma.translation.Translator; |
| 57 | import cuchaz.enigma.translation.mapping.*; | 72 | import cuchaz.enigma.translation.mapping.EntryChange; |
| 73 | import cuchaz.enigma.translation.mapping.EntryMapping; | ||
| 74 | import cuchaz.enigma.translation.mapping.EntryRemapper; | ||
| 75 | import cuchaz.enigma.translation.mapping.EntryUtil; | ||
| 76 | import cuchaz.enigma.translation.mapping.MappingDelta; | ||
| 77 | import cuchaz.enigma.translation.mapping.ResolutionStrategy; | ||
| 58 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; | 78 | import cuchaz.enigma.translation.mapping.serde.MappingFormat; |
| 59 | import cuchaz.enigma.translation.mapping.serde.MappingParseException; | 79 | import cuchaz.enigma.translation.mapping.serde.MappingParseException; |
| 60 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; | 80 | import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; |
| @@ -90,9 +110,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 90 | 110 | ||
| 91 | public GuiController(Gui gui, EnigmaProfile profile) { | 111 | public GuiController(Gui gui, EnigmaProfile profile) { |
| 92 | this.gui = gui; | 112 | this.gui = gui; |
| 93 | this.enigma = Enigma.builder() | 113 | this.enigma = Enigma.builder().setProfile(profile).build(); |
| 94 | .setProfile(profile) | ||
| 95 | .build(); | ||
| 96 | } | 114 | } |
| 97 | 115 | ||
| 98 | public boolean isDirty() { | 116 | public boolean isDirty() { |
| @@ -121,7 +139,9 @@ public class GuiController implements ClientPacketHandler { | |||
| 121 | } | 139 | } |
| 122 | 140 | ||
| 123 | public CompletableFuture<Void> openMappings(MappingFormat format, Path path) { | 141 | public CompletableFuture<Void> openMappings(MappingFormat format, Path path) { |
| 124 | if (project == null) return CompletableFuture.completedFuture(null); | 142 | if (project == null) { |
| 143 | return CompletableFuture.completedFuture(null); | ||
| 144 | } | ||
| 125 | 145 | ||
| 126 | gui.setMappingsFile(path); | 146 | gui.setMappingsFile(path); |
| 127 | 147 | ||
| @@ -145,7 +165,9 @@ public class GuiController implements ClientPacketHandler { | |||
| 145 | 165 | ||
| 146 | @Override | 166 | @Override |
| 147 | public void openMappings(EntryTree<EntryMapping> mappings) { | 167 | public void openMappings(EntryTree<EntryMapping> mappings) { |
| 148 | if (project == null) return; | 168 | if (project == null) { |
| 169 | return; | ||
| 170 | } | ||
| 149 | 171 | ||
| 150 | project.setMappings(mappings); | 172 | project.setMappings(mappings); |
| 151 | refreshClasses(); | 173 | refreshClasses(); |
| @@ -168,7 +190,9 @@ public class GuiController implements ClientPacketHandler { | |||
| 168 | * @return the future of saving | 190 | * @return the future of saving |
| 169 | */ | 191 | */ |
| 170 | public CompletableFuture<Void> saveMappings(Path path, MappingFormat format) { | 192 | public CompletableFuture<Void> saveMappings(Path path, MappingFormat format) { |
| 171 | if (project == null) return CompletableFuture.completedFuture(null); | 193 | if (project == null) { |
| 194 | return CompletableFuture.completedFuture(null); | ||
| 195 | } | ||
| 172 | 196 | ||
| 173 | return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { | 197 | return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { |
| 174 | EntryRemapper mapper = project.getMapper(); | 198 | EntryRemapper mapper = project.getMapper(); |
| @@ -189,7 +213,9 @@ public class GuiController implements ClientPacketHandler { | |||
| 189 | } | 213 | } |
| 190 | 214 | ||
| 191 | public void closeMappings() { | 215 | public void closeMappings() { |
| 192 | if (project == null) return; | 216 | if (project == null) { |
| 217 | return; | ||
| 218 | } | ||
| 193 | 219 | ||
| 194 | project.setMappings(null); | 220 | project.setMappings(null); |
| 195 | 221 | ||
| @@ -202,9 +228,11 @@ public class GuiController implements ClientPacketHandler { | |||
| 202 | Path jarPath = this.project.getJarPath(); | 228 | Path jarPath = this.project.getJarPath(); |
| 203 | MappingFormat loadedMappingFormat = this.loadedMappingFormat; | 229 | MappingFormat loadedMappingFormat = this.loadedMappingFormat; |
| 204 | Path loadedMappingPath = this.loadedMappingPath; | 230 | Path loadedMappingPath = this.loadedMappingPath; |
| 231 | |||
| 205 | if (jarPath != null) { | 232 | if (jarPath != null) { |
| 206 | this.closeJar(); | 233 | this.closeJar(); |
| 207 | CompletableFuture<Void> f = this.openJar(jarPath); | 234 | CompletableFuture<Void> f = this.openJar(jarPath); |
| 235 | |||
| 208 | if (loadedMappingFormat != null && loadedMappingPath != null) { | 236 | if (loadedMappingFormat != null && loadedMappingPath != null) { |
| 209 | f.whenComplete((v, t) -> this.openMappings(loadedMappingFormat, loadedMappingPath)); | 237 | f.whenComplete((v, t) -> this.openMappings(loadedMappingFormat, loadedMappingPath)); |
| 210 | } | 238 | } |
| @@ -214,6 +242,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 214 | public void reloadMappings() { | 242 | public void reloadMappings() { |
| 215 | MappingFormat loadedMappingFormat = this.loadedMappingFormat; | 243 | MappingFormat loadedMappingFormat = this.loadedMappingFormat; |
| 216 | Path loadedMappingPath = this.loadedMappingPath; | 244 | Path loadedMappingPath = this.loadedMappingPath; |
| 245 | |||
| 217 | if (loadedMappingFormat != null && loadedMappingPath != null) { | 246 | if (loadedMappingFormat != null && loadedMappingPath != null) { |
| 218 | this.closeMappings(); | 247 | this.closeMappings(); |
| 219 | this.openMappings(loadedMappingFormat, loadedMappingPath); | 248 | this.openMappings(loadedMappingFormat, loadedMappingPath); |
| @@ -221,29 +250,34 @@ public class GuiController implements ClientPacketHandler { | |||
| 221 | } | 250 | } |
| 222 | 251 | ||
| 223 | public CompletableFuture<Void> dropMappings() { | 252 | public CompletableFuture<Void> dropMappings() { |
| 224 | if (project == null) return CompletableFuture.completedFuture(null); | 253 | if (project == null) { |
| 254 | return CompletableFuture.completedFuture(null); | ||
| 255 | } | ||
| 225 | 256 | ||
| 226 | return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> project.dropMappings(progress)); | 257 | return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> project.dropMappings(progress)); |
| 227 | } | 258 | } |
| 228 | 259 | ||
| 229 | public CompletableFuture<Void> exportSource(final Path path) { | 260 | public CompletableFuture<Void> exportSource(final Path path) { |
| 230 | if (project == null) return CompletableFuture.completedFuture(null); | 261 | if (project == null) { |
| 262 | return CompletableFuture.completedFuture(null); | ||
| 263 | } | ||
| 231 | 264 | ||
| 232 | return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { | 265 | return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { |
| 233 | EnigmaProject.JarExport jar = project.exportRemappedJar(progress); | 266 | EnigmaProject.JarExport jar = project.exportRemappedJar(progress); |
| 234 | jar.decompileStream(progress, chp.getDecompilerService(), EnigmaProject.DecompileErrorStrategy.TRACE_AS_SOURCE) | 267 | jar.decompileStream(progress, chp.getDecompilerService(), EnigmaProject.DecompileErrorStrategy.TRACE_AS_SOURCE).forEach(source -> { |
| 235 | .forEach(source -> { | 268 | try { |
| 236 | try { | 269 | source.writeTo(source.resolvePath(path)); |
| 237 | source.writeTo(source.resolvePath(path)); | 270 | } catch (IOException e) { |
| 238 | } catch (IOException e) { | 271 | e.printStackTrace(); |
| 239 | e.printStackTrace(); | 272 | } |
| 240 | } | 273 | }); |
| 241 | }); | ||
| 242 | }); | 274 | }); |
| 243 | } | 275 | } |
| 244 | 276 | ||
| 245 | public CompletableFuture<Void> exportJar(final Path path) { | 277 | public CompletableFuture<Void> exportJar(final Path path) { |
| 246 | if (project == null) return CompletableFuture.completedFuture(null); | 278 | if (project == null) { |
| 279 | return CompletableFuture.completedFuture(null); | ||
| 280 | } | ||
| 247 | 281 | ||
| 248 | return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { | 282 | return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { |
| 249 | EnigmaProject.JarExport jar = project.exportRemappedJar(progress); | 283 | EnigmaProject.JarExport jar = project.exportRemappedJar(progress); |
| @@ -269,20 +303,14 @@ public class GuiController implements ClientPacketHandler { | |||
| 269 | } | 303 | } |
| 270 | 304 | ||
| 271 | try { | 305 | try { |
| 272 | return tokenHandle.getSource().get() | 306 | return tokenHandle.getSource().get().map(DecompiledClassSource::getIndex).map(index -> new ReadableToken(index.getLineNumber(token.start), index.getColumnNumber(token.start), index.getColumnNumber(token.end))).unwrapOr(null); |
| 273 | .map(DecompiledClassSource::getIndex) | ||
| 274 | .map(index -> new ReadableToken( | ||
| 275 | index.getLineNumber(token.start), | ||
| 276 | index.getColumnNumber(token.start), | ||
| 277 | index.getColumnNumber(token.end))) | ||
| 278 | .unwrapOr(null); | ||
| 279 | } catch (InterruptedException | ExecutionException e) { | 307 | } catch (InterruptedException | ExecutionException e) { |
| 280 | throw new RuntimeException(e); | 308 | throw new RuntimeException(e); |
| 281 | } | 309 | } |
| 282 | } | 310 | } |
| 283 | 311 | ||
| 284 | /** | 312 | /** |
| 285 | * Navigates to the declaration with respect to navigation history | 313 | * Navigates to the declaration with respect to navigation history. |
| 286 | * | 314 | * |
| 287 | * @param entry the entry whose declaration will be navigated to | 315 | * @param entry the entry whose declaration will be navigated to |
| 288 | */ | 316 | */ |
| @@ -290,11 +318,12 @@ public class GuiController implements ClientPacketHandler { | |||
| 290 | if (entry == null) { | 318 | if (entry == null) { |
| 291 | throw new IllegalArgumentException("Entry cannot be null!"); | 319 | throw new IllegalArgumentException("Entry cannot be null!"); |
| 292 | } | 320 | } |
| 321 | |||
| 293 | openReference(EntryReference.declaration(entry, entry.getName())); | 322 | openReference(EntryReference.declaration(entry, entry.getName())); |
| 294 | } | 323 | } |
| 295 | 324 | ||
| 296 | /** | 325 | /** |
| 297 | * Navigates to the reference with respect to navigation history | 326 | * Navigates to the reference with respect to navigation history. |
| 298 | * | 327 | * |
| 299 | * @param reference the reference | 328 | * @param reference the reference |
| 300 | */ | 329 | */ |
| @@ -302,6 +331,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 302 | if (reference == null) { | 331 | if (reference == null) { |
| 303 | throw new IllegalArgumentException("Reference cannot be null!"); | 332 | throw new IllegalArgumentException("Reference cannot be null!"); |
| 304 | } | 333 | } |
| 334 | |||
| 305 | if (this.referenceHistory == null) { | 335 | if (this.referenceHistory == null) { |
| 306 | this.referenceHistory = new History<>(reference); | 336 | this.referenceHistory = new History<>(reference); |
| 307 | } else { | 337 | } else { |
| @@ -317,11 +347,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 317 | EntryRemapper mapper = this.project.getMapper(); | 347 | EntryRemapper mapper = this.project.getMapper(); |
| 318 | 348 | ||
| 319 | SourceIndex index = source.getIndex(); | 349 | SourceIndex index = source.getIndex(); |
| 320 | return mapper.getObfResolver().resolveReference(reference, ResolutionStrategy.RESOLVE_CLOSEST) | 350 | return mapper.getObfResolver().resolveReference(reference, ResolutionStrategy.RESOLVE_CLOSEST).stream().flatMap(r -> index.getReferenceTokens(r).stream()).sorted().toList(); |
| 321 | .stream() | ||
| 322 | .flatMap(r -> index.getReferenceTokens(r).stream()) | ||
| 323 | .sorted() | ||
| 324 | .toList(); | ||
| 325 | } | 351 | } |
| 326 | 352 | ||
| 327 | public void openPreviousReference() { | 353 | public void openPreviousReference() { |
| @@ -349,6 +375,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 349 | // entry is not in the jar. Ignore it | 375 | // entry is not in the jar. Ignore it |
| 350 | return; | 376 | return; |
| 351 | } | 377 | } |
| 378 | |||
| 352 | openDeclaration(entry); | 379 | openDeclaration(entry); |
| 353 | } | 380 | } |
| 354 | 381 | ||
| @@ -356,12 +383,15 @@ public class GuiController implements ClientPacketHandler { | |||
| 356 | if (!project.isRenamable(reference.getLocationClassEntry())) { | 383 | if (!project.isRenamable(reference.getLocationClassEntry())) { |
| 357 | return; | 384 | return; |
| 358 | } | 385 | } |
| 386 | |||
| 359 | openReference(reference); | 387 | openReference(reference); |
| 360 | } | 388 | } |
| 361 | 389 | ||
| 362 | public void refreshClasses() { | 390 | public void refreshClasses() { |
| 363 | if (project == null) return; | 391 | if (project == null) { |
| 364 | 392 | return; | |
| 393 | } | ||
| 394 | |||
| 365 | List<ClassEntry> obfClasses = Lists.newArrayList(); | 395 | List<ClassEntry> obfClasses = Lists.newArrayList(); |
| 366 | List<ClassEntry> deobfClasses = Lists.newArrayList(); | 396 | List<ClassEntry> deobfClasses = Lists.newArrayList(); |
| 367 | this.addSeparatedClasses(obfClasses, deobfClasses); | 397 | this.addSeparatedClasses(obfClasses, deobfClasses); |
| @@ -373,8 +403,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 373 | EntryRemapper mapper = project.getMapper(); | 403 | EntryRemapper mapper = project.getMapper(); |
| 374 | 404 | ||
| 375 | Collection<ClassEntry> classes = project.getJarIndex().getEntryIndex().getClasses(); | 405 | Collection<ClassEntry> classes = project.getJarIndex().getEntryIndex().getClasses(); |
| 376 | Stream<ClassEntry> visibleClasses = classes.stream() | 406 | Stream<ClassEntry> visibleClasses = classes.stream().filter(entry -> !entry.isInnerClass()); |
| 377 | .filter(entry -> !entry.isInnerClass()); | ||
| 378 | 407 | ||
| 379 | visibleClasses.forEach(entry -> { | 408 | visibleClasses.forEach(entry -> { |
| 380 | if (gui.isSingleClassTree()) { | 409 | if (gui.isSingleClassTree()) { |
| @@ -428,12 +457,15 @@ public class GuiController implements ClientPacketHandler { | |||
| 428 | public MethodImplementationsTreeNode getMethodImplementations(MethodEntry entry) { | 457 | public MethodImplementationsTreeNode getMethodImplementations(MethodEntry entry) { |
| 429 | Translator translator = project.getMapper().getDeobfuscator(); | 458 | Translator translator = project.getMapper().getDeobfuscator(); |
| 430 | List<MethodImplementationsTreeNode> rootNodes = indexTreeBuilder.buildMethodImplementations(translator, entry); | 459 | List<MethodImplementationsTreeNode> rootNodes = indexTreeBuilder.buildMethodImplementations(translator, entry); |
| 460 | |||
| 431 | if (rootNodes.isEmpty()) { | 461 | if (rootNodes.isEmpty()) { |
| 432 | return null; | 462 | return null; |
| 433 | } | 463 | } |
| 464 | |||
| 434 | if (rootNodes.size() > 1) { | 465 | if (rootNodes.size() > 1) { |
| 435 | System.err.println("WARNING: Method " + entry + " implements multiple interfaces. Only showing first one."); | 466 | System.err.println("WARNING: Method " + entry + " implements multiple interfaces. Only showing first one."); |
| 436 | } | 467 | } |
| 468 | |||
| 437 | return MethodImplementationsTreeNode.findNode(rootNodes.get(0), entry); | 469 | return MethodImplementationsTreeNode.findNode(rootNodes.get(0), entry); |
| 438 | } | 470 | } |
| 439 | 471 | ||
| @@ -481,13 +513,20 @@ public class GuiController implements ClientPacketHandler { | |||
| 481 | public void applyChange(ValidationContext vc, EntryChange<?> change) { | 513 | public void applyChange(ValidationContext vc, EntryChange<?> change) { |
| 482 | this.applyChange0(vc, change); | 514 | this.applyChange0(vc, change); |
| 483 | gui.showStructure(gui.getActiveEditor()); | 515 | gui.showStructure(gui.getActiveEditor()); |
| 484 | if (!vc.canProceed()) return; | 516 | |
| 517 | if (!vc.canProceed()) { | ||
| 518 | return; | ||
| 519 | } | ||
| 520 | |||
| 485 | this.sendPacket(new EntryChangeC2SPacket(change)); | 521 | this.sendPacket(new EntryChangeC2SPacket(change)); |
| 486 | } | 522 | } |
| 487 | 523 | ||
| 488 | private void applyChange0(ValidationContext vc, EntryChange<?> change) { | 524 | private void applyChange0(ValidationContext vc, EntryChange<?> change) { |
| 489 | validateChange(vc, change); | 525 | validateChange(vc, change); |
| 490 | if (!vc.canProceed()) return; | 526 | |
| 527 | if (!vc.canProceed()) { | ||
| 528 | return; | ||
| 529 | } | ||
| 491 | 530 | ||
| 492 | Entry<?> target = change.getTarget(); | 531 | Entry<?> target = change.getTarget(); |
| 493 | EntryMapping prev = this.project.getMapper().getDeobfMapping(target); | 532 | EntryMapping prev = this.project.getMapper().getDeobfMapping(target); |
| @@ -506,6 +545,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 506 | if (!Objects.equals(prev.javadoc(), mapping.javadoc())) { | 545 | if (!Objects.equals(prev.javadoc(), mapping.javadoc())) { |
| 507 | this.chp.invalidateJavadoc(target.getTopLevelClass()); | 546 | this.chp.invalidateJavadoc(target.getTopLevelClass()); |
| 508 | } | 547 | } |
| 548 | |||
| 509 | gui.showStructure(gui.getActiveEditor()); | 549 | gui.showStructure(gui.getActiveEditor()); |
| 510 | } | 550 | } |
| 511 | 551 | ||
| @@ -517,10 +557,7 @@ public class GuiController implements ClientPacketHandler { | |||
| 517 | File statsFile = File.createTempFile("stats", ".html"); | 557 | File statsFile = File.createTempFile("stats", ".html"); |
| 518 | 558 | ||
| 519 | try (FileWriter w = new FileWriter(statsFile)) { | 559 | try (FileWriter w = new FileWriter(statsFile)) { |
| 520 | w.write( | 560 | w.write(Utils.readResourceToString("/stats.html").replace("/*data*/", data)); |
| 521 | Utils.readResourceToString("/stats.html") | ||
| 522 | .replace("/*data*/", data) | ||
| 523 | ); | ||
| 524 | } | 561 | } |
| 525 | 562 | ||
| 526 | Desktop.getDesktop().open(statsFile); | 563 | Desktop.getDesktop().open(statsFile); |
| @@ -573,15 +610,18 @@ public class GuiController implements ClientPacketHandler { | |||
| 573 | if (client != null) { | 610 | if (client != null) { |
| 574 | client.disconnect(); | 611 | client.disconnect(); |
| 575 | } | 612 | } |
| 613 | |||
| 576 | if (server != null) { | 614 | if (server != null) { |
| 577 | server.stop(); | 615 | server.stop(); |
| 578 | } | 616 | } |
| 617 | |||
| 579 | client = null; | 618 | client = null; |
| 580 | server = null; | 619 | server = null; |
| 581 | SwingUtilities.invokeLater(() -> { | 620 | SwingUtilities.invokeLater(() -> { |
| 582 | if (reason != null) { | 621 | if (reason != null) { |
| 583 | JOptionPane.showMessageDialog(gui.getFrame(), I18n.translate(reason), I18n.translate("disconnect.disconnected"), JOptionPane.INFORMATION_MESSAGE); | 622 | JOptionPane.showMessageDialog(gui.getFrame(), I18n.translate(reason), I18n.translate("disconnect.disconnected"), JOptionPane.INFORMATION_MESSAGE); |
| 584 | } | 623 | } |
| 624 | |||
| 585 | gui.setConnectionState(ConnectionState.NOT_CONNECTED); | 625 | gui.setConnectionState(ConnectionState.NOT_CONNECTED); |
| 586 | }); | 626 | }); |
| 587 | } | 627 | } |
| @@ -602,5 +642,4 @@ public class GuiController implements ClientPacketHandler { | |||
| 602 | public void updateUserList(List<String> users) { | 642 | public void updateUserList(List<String> users) { |
| 603 | gui.setUserList(users); | 643 | gui.setUserList(users); |
| 604 | } | 644 | } |
| 605 | |||
| 606 | } | 645 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java index 1172a39..56f4385 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| @@ -20,7 +20,11 @@ import java.util.List; | |||
| 20 | import java.util.Set; | 20 | import java.util.Set; |
| 21 | 21 | ||
| 22 | import com.google.common.io.MoreFiles; | 22 | import com.google.common.io.MoreFiles; |
| 23 | import joptsimple.*; | 23 | import joptsimple.OptionException; |
| 24 | import joptsimple.OptionParser; | ||
| 25 | import joptsimple.OptionSet; | ||
| 26 | import joptsimple.OptionSpec; | ||
| 27 | import joptsimple.ValueConverter; | ||
| 24 | 28 | ||
| 25 | import cuchaz.enigma.EnigmaProfile; | 29 | import cuchaz.enigma.EnigmaProfile; |
| 26 | import cuchaz.enigma.gui.config.Themes; | 30 | import cuchaz.enigma.gui.config.Themes; |
| @@ -30,21 +34,14 @@ import cuchaz.enigma.translation.mapping.serde.MappingFormat; | |||
| 30 | import cuchaz.enigma.utils.I18n; | 34 | import cuchaz.enigma.utils.I18n; |
| 31 | 35 | ||
| 32 | public class Main { | 36 | public class Main { |
| 33 | |||
| 34 | public static void main(String[] args) throws IOException { | 37 | public static void main(String[] args) throws IOException { |
| 35 | OptionParser parser = new OptionParser(); | 38 | OptionParser parser = new OptionParser(); |
| 36 | 39 | ||
| 37 | OptionSpec<Path> jar = parser.accepts("jar", "Jar file to open at startup") | 40 | OptionSpec<Path> jar = parser.accepts("jar", "Jar file to open at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); |
| 38 | .withRequiredArg() | ||
| 39 | .withValuesConvertedBy(PathConverter.INSTANCE); | ||
| 40 | 41 | ||
| 41 | OptionSpec<Path> mappings = parser.accepts("mappings", "Mappings file to open at startup") | 42 | OptionSpec<Path> mappings = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); |
| 42 | .withRequiredArg() | ||
| 43 | .withValuesConvertedBy(PathConverter.INSTANCE); | ||
| 44 | 43 | ||
| 45 | OptionSpec<Path> profile = parser.accepts("profile", "Profile json to apply at startup") | 44 | OptionSpec<Path> profile = parser.accepts("profile", "Profile json to apply at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); |
| 46 | .withRequiredArg() | ||
| 47 | .withValuesConvertedBy(PathConverter.INSTANCE); | ||
| 48 | 45 | ||
| 49 | parser.acceptsAll(List.of("edit-all", "e"), "Enable editing everything"); | 46 | parser.acceptsAll(List.of("edit-all", "e"), "Enable editing everything"); |
| 50 | parser.acceptsAll(List.of("no-edit-all", "E"), "Disable editing everything"); | 47 | parser.acceptsAll(List.of("no-edit-all", "E"), "Disable editing everything"); |
| @@ -78,26 +75,26 @@ public class Main { | |||
| 78 | for (OptionSpec<?> spec : options.specs()) { | 75 | for (OptionSpec<?> spec : options.specs()) { |
| 79 | for (String s : spec.options()) { | 76 | for (String s : spec.options()) { |
| 80 | switch (s) { | 77 | switch (s) { |
| 81 | case "edit-all" -> editables.addAll(List.of(EditableType.values())); | 78 | case "edit-all" -> editables.addAll(List.of(EditableType.values())); |
| 82 | case "no-edit-all" -> editables.clear(); | 79 | case "no-edit-all" -> editables.clear(); |
| 83 | case "edit-classes" -> editables.add(EditableType.CLASS); | 80 | case "edit-classes" -> editables.add(EditableType.CLASS); |
| 84 | case "no-edit-classes" -> editables.remove(EditableType.CLASS); | 81 | case "no-edit-classes" -> editables.remove(EditableType.CLASS); |
| 85 | case "edit-methods" -> editables.add(EditableType.METHOD); | 82 | case "edit-methods" -> editables.add(EditableType.METHOD); |
| 86 | case "no-edit-methods" -> editables.remove(EditableType.METHOD); | 83 | case "no-edit-methods" -> editables.remove(EditableType.METHOD); |
| 87 | case "edit-fields" -> editables.add(EditableType.FIELD); | 84 | case "edit-fields" -> editables.add(EditableType.FIELD); |
| 88 | case "no-edit-fields" -> editables.remove(EditableType.FIELD); | 85 | case "no-edit-fields" -> editables.remove(EditableType.FIELD); |
| 89 | case "edit-parameters" -> editables.add(EditableType.PARAMETER); | 86 | case "edit-parameters" -> editables.add(EditableType.PARAMETER); |
| 90 | case "no-edit-parameters" -> editables.remove(EditableType.PARAMETER); | 87 | case "no-edit-parameters" -> editables.remove(EditableType.PARAMETER); |
| 91 | case "edit-locals" -> { | 88 | case "edit-locals" -> { |
| 92 | editables.add(EditableType.LOCAL_VARIABLE); | 89 | editables.add(EditableType.LOCAL_VARIABLE); |
| 93 | System.err.println("warning: --edit-locals has no effect as local variables are currently not editable"); | 90 | System.err.println("warning: --edit-locals has no effect as local variables are currently not editable"); |
| 94 | } | 91 | } |
| 95 | case "no-edit-locals" -> { | 92 | case "no-edit-locals" -> { |
| 96 | editables.remove(EditableType.LOCAL_VARIABLE); | 93 | editables.remove(EditableType.LOCAL_VARIABLE); |
| 97 | System.err.println("warning: --no-edit-locals has no effect as local variables are currently not editable"); | 94 | System.err.println("warning: --no-edit-locals has no effect as local variables are currently not editable"); |
| 98 | } | 95 | } |
| 99 | case "edit-javadocs" -> editables.add(EditableType.JAVADOC); | 96 | case "edit-javadocs" -> editables.add(EditableType.JAVADOC); |
| 100 | case "no-edit-javadocs" -> editables.remove(EditableType.JAVADOC); | 97 | case "no-edit-javadocs" -> editables.remove(EditableType.JAVADOC); |
| 101 | } | 98 | } |
| 102 | } | 99 | } |
| 103 | } | 100 | } |
| @@ -110,7 +107,7 @@ public class Main { | |||
| 110 | 107 | ||
| 111 | Gui gui = new Gui(parsedProfile, editables); | 108 | Gui gui = new Gui(parsedProfile, editables); |
| 112 | GuiController controller = gui.getController(); | 109 | GuiController controller = gui.getController(); |
| 113 | 110 | ||
| 114 | if (options.has("single-class-tree")) { | 111 | if (options.has("single-class-tree")) { |
| 115 | gui.setSingleClassTree(true); | 112 | gui.setSingleClassTree(true); |
| 116 | } | 113 | } |
| @@ -120,6 +117,7 @@ public class Main { | |||
| 120 | CrashDialog.init(gui.getFrame()); | 117 | CrashDialog.init(gui.getFrame()); |
| 121 | Thread.setDefaultUncaughtExceptionHandler((thread, t) -> { | 118 | Thread.setDefaultUncaughtExceptionHandler((thread, t) -> { |
| 122 | t.printStackTrace(System.err); | 119 | t.printStackTrace(System.err); |
| 120 | |||
| 123 | if (!ExceptionIgnorer.shouldIgnore(t)) { | 121 | if (!ExceptionIgnorer.shouldIgnore(t)) { |
| 124 | CrashDialog.show(t); | 122 | CrashDialog.show(t); |
| 125 | } | 123 | } |
| @@ -128,19 +126,19 @@ public class Main { | |||
| 128 | 126 | ||
| 129 | if (options.has(jar)) { | 127 | if (options.has(jar)) { |
| 130 | Path jarPath = options.valueOf(jar); | 128 | Path jarPath = options.valueOf(jar); |
| 131 | controller.openJar(jarPath) | 129 | controller.openJar(jarPath).whenComplete((v, t) -> { |
| 132 | .whenComplete((v, t) -> { | 130 | if (options.has(mappings)) { |
| 133 | if (options.has(mappings)) { | 131 | Path mappingsPath = options.valueOf(mappings); |
| 134 | Path mappingsPath = options.valueOf(mappings); | 132 | |
| 135 | if (Files.isDirectory(mappingsPath)) { | 133 | if (Files.isDirectory(mappingsPath)) { |
| 136 | controller.openMappings(MappingFormat.ENIGMA_DIRECTORY, mappingsPath); | 134 | controller.openMappings(MappingFormat.ENIGMA_DIRECTORY, mappingsPath); |
| 137 | } else if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(mappingsPath))) { | 135 | } else if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(mappingsPath))) { |
| 138 | controller.openMappings(MappingFormat.ENIGMA_ZIP, mappingsPath); | 136 | controller.openMappings(MappingFormat.ENIGMA_ZIP, mappingsPath); |
| 139 | } else { | 137 | } else { |
| 140 | controller.openMappings(MappingFormat.ENIGMA_FILE, mappingsPath); | 138 | controller.openMappings(MappingFormat.ENIGMA_FILE, mappingsPath); |
| 141 | } | 139 | } |
| 142 | } | 140 | } |
| 143 | }); | 141 | }); |
| 144 | } | 142 | } |
| 145 | } catch (OptionException e) { | 143 | } catch (OptionException e) { |
| 146 | System.out.println("Invalid arguments: " + e.getMessage()); | 144 | System.out.println("Invalid arguments: " + e.getMessage()); |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/NestedPackages.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/NestedPackages.java index 309f910..c4541fc 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/NestedPackages.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/NestedPackages.java | |||
| @@ -1,21 +1,22 @@ | |||
| 1 | package cuchaz.enigma.gui; | 1 | package cuchaz.enigma.gui; |
| 2 | 2 | ||
| 3 | import cuchaz.enigma.gui.node.ClassSelectorClassNode; | 3 | import java.util.Collection; |
| 4 | import cuchaz.enigma.gui.node.ClassSelectorPackageNode; | 4 | import java.util.Comparator; |
| 5 | import cuchaz.enigma.translation.mapping.EntryRemapper; | 5 | import java.util.Enumeration; |
| 6 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | 6 | import java.util.HashMap; |
| 7 | import java.util.Map; | ||
| 7 | 8 | ||
| 8 | import javax.swing.tree.DefaultMutableTreeNode; | 9 | import javax.swing.tree.DefaultMutableTreeNode; |
| 9 | import javax.swing.tree.MutableTreeNode; | 10 | import javax.swing.tree.MutableTreeNode; |
| 10 | import javax.swing.tree.TreeNode; | 11 | import javax.swing.tree.TreeNode; |
| 11 | import javax.swing.tree.TreePath; | 12 | import javax.swing.tree.TreePath; |
| 12 | import java.util.Collection; | ||
| 13 | import java.util.Comparator; | ||
| 14 | import java.util.HashMap; | ||
| 15 | import java.util.Map; | ||
| 16 | 13 | ||
| 17 | public class NestedPackages { | 14 | import cuchaz.enigma.gui.node.ClassSelectorClassNode; |
| 15 | import cuchaz.enigma.gui.node.ClassSelectorPackageNode; | ||
| 16 | import cuchaz.enigma.translation.mapping.EntryRemapper; | ||
| 17 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 18 | 18 | ||
| 19 | public class NestedPackages { | ||
| 19 | private final DefaultMutableTreeNode root = new DefaultMutableTreeNode(); | 20 | private final DefaultMutableTreeNode root = new DefaultMutableTreeNode(); |
| 20 | private final Map<String, DefaultMutableTreeNode> packageToNode = new HashMap<>(); | 21 | private final Map<String, DefaultMutableTreeNode> packageToNode = new HashMap<>(); |
| 21 | private final Map<ClassEntry, ClassSelectorClassNode> classToNode = new HashMap<>(); | 22 | private final Map<ClassEntry, ClassSelectorClassNode> classToNode = new HashMap<>(); |
| @@ -42,20 +43,20 @@ public class NestedPackages { | |||
| 42 | return 0; | 43 | return 0; |
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| 45 | for (var entry : entries) { | 46 | for (ClassEntry entry : entries) { |
| 46 | addEntry(entry); | 47 | addEntry(entry); |
| 47 | } | 48 | } |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | public void addEntry(ClassEntry entry) { | 51 | public void addEntry(ClassEntry entry) { |
| 51 | var translated = remapper.deobfuscate(entry); | 52 | ClassEntry translated = remapper.deobfuscate(entry); |
| 52 | var me = new ClassSelectorClassNode(entry, translated); | 53 | var me = new ClassSelectorClassNode(entry, translated); |
| 53 | classToNode.put(entry, me); | 54 | classToNode.put(entry, me); |
| 54 | insert(getPackage(translated.getPackageName()), me); | 55 | insert(getPackage(translated.getPackageName()), me); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | public DefaultMutableTreeNode getPackage(String packageName) { | 58 | public DefaultMutableTreeNode getPackage(String packageName) { |
| 58 | var node = packageToNode.get(packageName); | 59 | DefaultMutableTreeNode node = packageToNode.get(packageName); |
| 59 | 60 | ||
| 60 | if (packageName == null) { | 61 | if (packageName == null) { |
| 61 | return root; | 62 | return root; |
| @@ -75,7 +76,7 @@ public class NestedPackages { | |||
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | public TreePath getPackagePath(String packageName) { | 78 | public TreePath getPackagePath(String packageName) { |
| 78 | var node = packageToNode.getOrDefault(packageName, root); | 79 | DefaultMutableTreeNode node = packageToNode.getOrDefault(packageName, root); |
| 79 | return new TreePath(node.getPath()); | 80 | return new TreePath(node.getPath()); |
| 80 | } | 81 | } |
| 81 | 82 | ||
| @@ -84,15 +85,15 @@ public class NestedPackages { | |||
| 84 | } | 85 | } |
| 85 | 86 | ||
| 86 | public void removeClassNode(ClassEntry entry) { | 87 | public void removeClassNode(ClassEntry entry) { |
| 87 | var node = classToNode.remove(entry); | 88 | ClassSelectorClassNode node = classToNode.remove(entry); |
| 88 | 89 | ||
| 89 | if (node != null) { | 90 | if (node != null) { |
| 90 | node.removeFromParent(); | 91 | node.removeFromParent(); |
| 91 | // remove dangling packages | 92 | // remove dangling packages |
| 92 | var packageNode = packageToNode.get(entry.getPackageName()); | 93 | DefaultMutableTreeNode packageNode = packageToNode.get(entry.getPackageName()); |
| 93 | 94 | ||
| 94 | while (packageNode != null && packageNode.getChildCount() == 0) { | 95 | while (packageNode != null && packageNode.getChildCount() == 0) { |
| 95 | var theNode = packageNode; | 96 | DefaultMutableTreeNode theNode = packageNode; |
| 96 | packageNode = (DefaultMutableTreeNode) packageNode.getParent(); | 97 | packageNode = (DefaultMutableTreeNode) packageNode.getParent(); |
| 97 | theNode.removeFromParent(); | 98 | theNode.removeFromParent(); |
| 98 | 99 | ||
| @@ -108,8 +109,8 @@ public class NestedPackages { | |||
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | private void insert(DefaultMutableTreeNode parent, MutableTreeNode child) { | 111 | private void insert(DefaultMutableTreeNode parent, MutableTreeNode child) { |
| 111 | var index = 0; | 112 | int index = 0; |
| 112 | var children = parent.children(); | 113 | Enumeration<TreeNode> children = parent.children(); |
| 113 | 114 | ||
| 114 | while (children.hasMoreElements()) { | 115 | while (children.hasMoreElements()) { |
| 115 | if (comparator.compare(children.nextElement(), child) < 0) { | 116 | if (comparator.compare(children.nextElement(), child) < 0) { |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/QuickFindAction.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/QuickFindAction.java index b7fa2eb..ff80e17 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/QuickFindAction.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/QuickFindAction.java | |||
| @@ -1,10 +1,11 @@ | |||
| 1 | package cuchaz.enigma.gui; | 1 | package cuchaz.enigma.gui; |
| 2 | 2 | ||
| 3 | import de.sciss.syntaxpane.SyntaxDocument; | 3 | import java.awt.event.ActionEvent; |
| 4 | import de.sciss.syntaxpane.actions.DefaultSyntaxAction; | ||
| 5 | 4 | ||
| 6 | import javax.swing.text.JTextComponent; | 5 | import javax.swing.text.JTextComponent; |
| 7 | import java.awt.event.ActionEvent; | 6 | |
| 7 | import de.sciss.syntaxpane.SyntaxDocument; | ||
| 8 | import de.sciss.syntaxpane.actions.DefaultSyntaxAction; | ||
| 8 | 9 | ||
| 9 | public final class QuickFindAction extends DefaultSyntaxAction { | 10 | public final class QuickFindAction extends DefaultSyntaxAction { |
| 10 | public QuickFindAction() { | 11 | public QuickFindAction() { |
| @@ -26,6 +27,7 @@ public final class QuickFindAction extends DefaultSyntaxAction { | |||
| 26 | 27 | ||
| 27 | public static Data get(JTextComponent target) { | 28 | public static Data get(JTextComponent target) { |
| 28 | Object o = target.getDocument().getProperty(KEY); | 29 | Object o = target.getDocument().getProperty(KEY); |
| 30 | |||
| 29 | if (o instanceof Data) { | 31 | if (o instanceof Data) { |
| 30 | return (Data) o; | 32 | return (Data) o; |
| 31 | } | 33 | } |
| @@ -39,6 +41,7 @@ public final class QuickFindAction extends DefaultSyntaxAction { | |||
| 39 | if (findDialog == null) { | 41 | if (findDialog == null) { |
| 40 | findDialog = new EnigmaQuickFindDialog(target); | 42 | findDialog = new EnigmaQuickFindDialog(target); |
| 41 | } | 43 | } |
| 44 | |||
| 42 | findDialog.showFor(target); | 45 | findDialog.showFor(target); |
| 43 | } | 46 | } |
| 44 | } | 47 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/ReadableToken.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/ReadableToken.java index 3e4b30c..eac11ed 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/ReadableToken.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/ReadableToken.java | |||
| @@ -1,18 +1,17 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| 14 | public class ReadableToken { | 14 | public class ReadableToken { |
| 15 | |||
| 16 | public int line; | 15 | public int line; |
| 17 | public int startColumn; | 16 | public int startColumn; |
| 18 | public int endColumn; | 17 | public int endColumn; |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java index 4ef0442..000793e 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/TokenListCellRenderer.java | |||
| @@ -1,23 +1,26 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui; | 12 | package cuchaz.enigma.gui; |
| 13 | 13 | ||
| 14 | import cuchaz.enigma.source.Token; | 14 | import java.awt.Component; |
| 15 | 15 | ||
| 16 | import javax.swing.*; | 16 | import javax.swing.DefaultListCellRenderer; |
| 17 | import java.awt.*; | 17 | import javax.swing.JLabel; |
| 18 | import javax.swing.JList; | ||
| 19 | import javax.swing.ListCellRenderer; | ||
| 18 | 20 | ||
| 19 | public class TokenListCellRenderer implements ListCellRenderer<Token> { | 21 | import cuchaz.enigma.source.Token; |
| 20 | 22 | ||
| 23 | public class TokenListCellRenderer implements ListCellRenderer<Token> { | ||
| 21 | private GuiController controller; | 24 | private GuiController controller; |
| 22 | private DefaultListCellRenderer defaultRenderer; | 25 | private DefaultListCellRenderer defaultRenderer; |
| 23 | 26 | ||
| @@ -32,5 +35,4 @@ public class TokenListCellRenderer implements ListCellRenderer<Token> { | |||
| 32 | label.setText(this.controller.getReadableToken(token).toString()); | 35 | label.setText(this.controller.getReadableToken(token).toString()); |
| 33 | return label; | 36 | return label; |
| 34 | } | 37 | } |
| 35 | |||
| 36 | } | 38 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/LookAndFeel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/LookAndFeel.java index cec3fa1..2088aac 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/LookAndFeel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/LookAndFeel.java | |||
| @@ -40,11 +40,11 @@ public enum LookAndFeel { | |||
| 40 | 40 | ||
| 41 | try { | 41 | try { |
| 42 | switch (this) { | 42 | switch (this) { |
| 43 | case NONE -> UIManager.setLookAndFeel(NONE_LAF); | 43 | case NONE -> UIManager.setLookAndFeel(NONE_LAF); |
| 44 | case DEFAULT -> UIManager.setLookAndFeel(new FlatLightLaf()); | 44 | case DEFAULT -> UIManager.setLookAndFeel(new FlatLightLaf()); |
| 45 | case METAL -> UIManager.setLookAndFeel(new MetalLookAndFeel()); | 45 | case METAL -> UIManager.setLookAndFeel(new MetalLookAndFeel()); |
| 46 | case DARCULA -> UIManager.setLookAndFeel(new FlatDarkLaf()); | 46 | case DARCULA -> UIManager.setLookAndFeel(new FlatDarkLaf()); |
| 47 | case SYSTEM -> UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); | 47 | case SYSTEM -> UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); |
| 48 | } | 48 | } |
| 49 | } catch (Exception e) { | 49 | } catch (Exception e) { |
| 50 | throw new Error("Failed to set global look and feel", e); | 50 | throw new Error("Failed to set global look and feel", e); |
| @@ -66,5 +66,4 @@ public enum LookAndFeel { | |||
| 66 | int b = (int) (0.3 * c.getRed() + 0.59 * c.getGreen() + 0.11 * c.getBlue()); | 66 | int b = (int) (0.3 * c.getRed() + 0.59 * c.getGreen() + 0.11 * c.getBlue()); |
| 67 | return b < 85; | 67 | return b < 85; |
| 68 | } | 68 | } |
| 69 | |||
| 70 | } | 69 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/NetConfig.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/NetConfig.java index 4439cb8..eaf20e7 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/NetConfig.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/NetConfig.java | |||
| @@ -4,7 +4,6 @@ import cuchaz.enigma.config.ConfigContainer; | |||
| 4 | import cuchaz.enigma.network.EnigmaServer; | 4 | import cuchaz.enigma.network.EnigmaServer; |
| 5 | 5 | ||
| 6 | public final class NetConfig { | 6 | public final class NetConfig { |
| 7 | |||
| 8 | private NetConfig() { | 7 | private NetConfig() { |
| 9 | } | 8 | } |
| 10 | 9 | ||
| @@ -53,5 +52,4 @@ public final class NetConfig { | |||
| 53 | public static void setServerPort(int port) { | 52 | public static void setServerPort(int port) { |
| 54 | cfg.data().section("Server").setInt("Port", port); | 53 | cfg.data().section("Server").setInt("Port", port); |
| 55 | } | 54 | } |
| 56 | |||
| 57 | } | 55 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/OldConfigImporter.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/OldConfigImporter.java index 660d231..2e84991 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/OldConfigImporter.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/OldConfigImporter.java | |||
| @@ -5,7 +5,6 @@ import java.awt.Font; | |||
| 5 | import cuchaz.enigma.gui.config.legacy.Config; | 5 | import cuchaz.enigma.gui.config.legacy.Config; |
| 6 | 6 | ||
| 7 | public final class OldConfigImporter { | 7 | public final class OldConfigImporter { |
| 8 | |||
| 9 | private OldConfigImporter() { | 8 | private OldConfigImporter() { |
| 10 | } | 9 | } |
| 11 | 10 | ||
| @@ -13,14 +12,15 @@ public final class OldConfigImporter { | |||
| 13 | public static void doImport() { | 12 | public static void doImport() { |
| 14 | if (Config.CONFIG_FILE.exists()) { | 13 | if (Config.CONFIG_FILE.exists()) { |
| 15 | Config config = new Config(); | 14 | Config config = new Config(); |
| 15 | |||
| 16 | if (config.editorFont != null) { | 16 | if (config.editorFont != null) { |
| 17 | UiConfig.setEditorFont(Font.decode(config.editorFont)); | 17 | UiConfig.setEditorFont(Font.decode(config.editorFont)); |
| 18 | } | 18 | } |
| 19 | |||
| 19 | UiConfig.setLanguage(config.language); | 20 | UiConfig.setLanguage(config.language); |
| 20 | UiConfig.setLookAndFeel(config.lookAndFeel); | 21 | UiConfig.setLookAndFeel(config.lookAndFeel); |
| 21 | UiConfig.setScaleFactor(config.scaleFactor); | 22 | UiConfig.setScaleFactor(config.scaleFactor); |
| 22 | UiConfig.setDecompiler(config.decompiler); | 23 | UiConfig.setDecompiler(config.decompiler); |
| 23 | } | 24 | } |
| 24 | } | 25 | } |
| 25 | |||
| 26 | } | 26 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/Themes.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/Themes.java index 839a5cb..e2db968 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/Themes.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/Themes.java | |||
| @@ -16,7 +16,6 @@ import cuchaz.enigma.gui.util.ScaleUtil; | |||
| 16 | import cuchaz.enigma.source.RenamableTokenType; | 16 | import cuchaz.enigma.source.RenamableTokenType; |
| 17 | 17 | ||
| 18 | public class Themes { | 18 | public class Themes { |
| 19 | |||
| 20 | private static final Set<ThemeChangeListener> listeners = new HashSet<>(); | 19 | private static final Set<ThemeChangeListener> listeners = new HashSet<>(); |
| 21 | 20 | ||
| 22 | // Calling this after the UI is initialized (e.g. when the user changes | 21 | // Calling this after the UI is initialized (e.g. when the user changes |
| @@ -87,11 +86,8 @@ public class Themes { | |||
| 87 | } | 86 | } |
| 88 | 87 | ||
| 89 | public static ImmutableMap<RenamableTokenType, BoxHighlightPainter> getBoxHighlightPainters() { | 88 | public static ImmutableMap<RenamableTokenType, BoxHighlightPainter> getBoxHighlightPainters() { |
| 90 | return ImmutableMap.of( | 89 | return ImmutableMap.of(RenamableTokenType.OBFUSCATED, BoxHighlightPainter.create(UiConfig.getObfuscatedColor(), UiConfig.getObfuscatedOutlineColor()), RenamableTokenType.PROPOSED, BoxHighlightPainter.create(UiConfig.getProposedColor(), UiConfig.getProposedOutlineColor()), |
| 91 | RenamableTokenType.OBFUSCATED, BoxHighlightPainter.create(UiConfig.getObfuscatedColor(), UiConfig.getObfuscatedOutlineColor()), | 90 | RenamableTokenType.DEOBFUSCATED, BoxHighlightPainter.create(UiConfig.getDeobfuscatedColor(), UiConfig.getDeobfuscatedOutlineColor())); |
| 92 | RenamableTokenType.PROPOSED, BoxHighlightPainter.create(UiConfig.getProposedColor(), UiConfig.getProposedOutlineColor()), | ||
| 93 | RenamableTokenType.DEOBFUSCATED, BoxHighlightPainter.create(UiConfig.getDeobfuscatedColor(), UiConfig.getDeobfuscatedOutlineColor()) | ||
| 94 | ); | ||
| 95 | } | 91 | } |
| 96 | 92 | ||
| 97 | public static void addListener(ThemeChangeListener listener) { | 93 | public static void addListener(ThemeChangeListener listener) { |
| @@ -101,5 +97,4 @@ public class Themes { | |||
| 101 | public static void removeListener(ThemeChangeListener listener) { | 97 | public static void removeListener(ThemeChangeListener listener) { |
| 102 | listeners.remove(listener); | 98 | listeners.remove(listener); |
| 103 | } | 99 | } |
| 104 | |||
| 105 | } | 100 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/UiConfig.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/UiConfig.java index 8a10ace..cdf27ca 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/UiConfig.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/UiConfig.java | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | package cuchaz.enigma.gui.config; | 1 | package cuchaz.enigma.gui.config; |
| 2 | 2 | ||
| 3 | import java.awt.*; | 3 | import java.awt.Color; |
| 4 | import java.awt.Dimension; | ||
| 5 | import java.awt.Font; | ||
| 6 | import java.awt.Point; | ||
| 7 | import java.awt.Toolkit; | ||
| 4 | import java.util.Optional; | 8 | import java.util.Optional; |
| 5 | import java.util.OptionalInt; | 9 | import java.util.OptionalInt; |
| 6 | 10 | ||
| @@ -10,7 +14,6 @@ import cuchaz.enigma.gui.util.ScaleUtil; | |||
| 10 | import cuchaz.enigma.utils.I18n; | 14 | import cuchaz.enigma.utils.I18n; |
| 11 | 15 | ||
| 12 | public final class UiConfig { | 16 | public final class UiConfig { |
| 13 | |||
| 14 | private UiConfig() { | 17 | private UiConfig() { |
| 15 | } | 18 | } |
| 16 | 19 | ||
| @@ -82,11 +85,11 @@ public final class UiConfig { | |||
| 82 | * @return an integer array composed of these 4 dimensions | 85 | * @return an integer array composed of these 4 dimensions |
| 83 | */ | 86 | */ |
| 84 | public static int[] getLayout() { | 87 | public static int[] getLayout() { |
| 85 | return swing.data().section("Main Window").getIntArray("Layout").orElseGet(() -> new int[] { -1, -1, -1, -1 }); | 88 | return swing.data().section("Main Window").getIntArray("Layout").orElseGet(() -> new int[]{-1, -1, -1, -1}); |
| 86 | } | 89 | } |
| 87 | 90 | ||
| 88 | public static void setLayout(int leftV, int left, int right, int rightH) { | 91 | public static void setLayout(int leftV, int left, int right, int rightH) { |
| 89 | swing.data().section("Main Window").setIntArray("Layout", new int[] { leftV, left, right, rightH }); | 92 | swing.data().section("Main Window").setIntArray("Layout", new int[]{leftV, left, right, rightH}); |
| 90 | } | 93 | } |
| 91 | 94 | ||
| 92 | public static LookAndFeel getLookAndFeel() { | 95 | public static LookAndFeel getLookAndFeel() { |
| @@ -287,6 +290,7 @@ public final class UiConfig { | |||
| 287 | ConfigSection section = swing.data().section(window); | 290 | ConfigSection section = swing.data().section(window); |
| 288 | OptionalInt width = section.getInt(String.format("Width %s", screenSize.width)); | 291 | OptionalInt width = section.getInt(String.format("Width %s", screenSize.width)); |
| 289 | OptionalInt height = section.getInt(String.format("Height %s", screenSize.height)); | 292 | OptionalInt height = section.getInt(String.format("Height %s", screenSize.height)); |
| 293 | |||
| 290 | if (width.isPresent() && height.isPresent()) { | 294 | if (width.isPresent() && height.isPresent()) { |
| 291 | return new Dimension(width.getAsInt(), height.getAsInt()); | 295 | return new Dimension(width.getAsInt(), height.getAsInt()); |
| 292 | } else { | 296 | } else { |
| @@ -306,6 +310,7 @@ public final class UiConfig { | |||
| 306 | ConfigSection section = swing.data().section(window); | 310 | ConfigSection section = swing.data().section(window); |
| 307 | OptionalInt x = section.getInt(String.format("X %s", screenSize.width)); | 311 | OptionalInt x = section.getInt(String.format("X %s", screenSize.width)); |
| 308 | OptionalInt y = section.getInt(String.format("Y %s", screenSize.height)); | 312 | OptionalInt y = section.getInt(String.format("Y %s", screenSize.height)); |
| 313 | |||
| 309 | if (x.isPresent() && y.isPresent()) { | 314 | if (x.isPresent() && y.isPresent()) { |
| 310 | int ix = x.getAsInt(); | 315 | int ix = x.getAsInt(); |
| 311 | int iy = y.getAsInt(); | 316 | int iy = y.getAsInt(); |
| @@ -354,6 +359,7 @@ public final class UiConfig { | |||
| 354 | 359 | ||
| 355 | public static void setLookAndFeelDefaults(LookAndFeel laf, boolean isDark) { | 360 | public static void setLookAndFeelDefaults(LookAndFeel laf, boolean isDark) { |
| 356 | ConfigSection s = swing.data().section("Themes").section(laf.name()).section("Colors"); | 361 | ConfigSection s = swing.data().section("Themes").section(laf.name()).section("Colors"); |
| 362 | |||
| 357 | if (!isDark) { | 363 | if (!isDark) { |
| 358 | // Defaults found here: https://github.com/Sciss/SyntaxPane/blob/122da367ff7a5d31627a70c62a48a9f0f4f85a0a/src/main/resources/de/sciss/syntaxpane/defaultsyntaxkit/config.properties#L139 | 364 | // Defaults found here: https://github.com/Sciss/SyntaxPane/blob/122da367ff7a5d31627a70c62a48a9f0f4f85a0a/src/main/resources/de/sciss/syntaxpane/defaultsyntaxkit/config.properties#L139 |
| 359 | s.setIfAbsentRgbColor("Line Numbers Foreground", 0x333300); | 365 | s.setIfAbsentRgbColor("Line Numbers Foreground", 0x333300); |
| @@ -412,5 +418,4 @@ public final class UiConfig { | |||
| 412 | s.setIfAbsentRgbColor("Text", 0xF8F8F2); | 418 | s.setIfAbsentRgbColor("Text", 0xF8F8F2); |
| 413 | } | 419 | } |
| 414 | } | 420 | } |
| 415 | |||
| 416 | } | 421 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/legacy/Config.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/legacy/Config.java index 1265750..0e8f7da 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/config/legacy/Config.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/config/legacy/Config.java | |||
| @@ -6,7 +6,15 @@ import java.lang.reflect.Type; | |||
| 6 | import java.nio.charset.Charset; | 6 | import java.nio.charset.Charset; |
| 7 | 7 | ||
| 8 | import com.google.common.io.Files; | 8 | import com.google.common.io.Files; |
| 9 | import com.google.gson.*; | 9 | import com.google.gson.Gson; |
| 10 | import com.google.gson.GsonBuilder; | ||
| 11 | import com.google.gson.InstanceCreator; | ||
| 12 | import com.google.gson.JsonDeserializationContext; | ||
| 13 | import com.google.gson.JsonDeserializer; | ||
| 14 | import com.google.gson.JsonElement; | ||
| 15 | import com.google.gson.JsonPrimitive; | ||
| 16 | import com.google.gson.JsonSerializationContext; | ||
| 17 | import com.google.gson.JsonSerializer; | ||
| 10 | 18 | ||
| 11 | import cuchaz.enigma.gui.config.Decompiler; | 19 | import cuchaz.enigma.gui.config.Decompiler; |
| 12 | import cuchaz.enigma.utils.I18n; | 20 | import cuchaz.enigma.utils.I18n; |
| @@ -28,7 +36,7 @@ public class Config { | |||
| 28 | } | 36 | } |
| 29 | 37 | ||
| 30 | Color baseColor = new Color(rgb); | 38 | Color baseColor = new Color(rgb); |
| 31 | return new Color(baseColor.getRed(), baseColor.getGreen(), baseColor.getBlue(), (int)(255 * alpha)); | 39 | return new Color(baseColor.getRed(), baseColor.getGreen(), baseColor.getBlue(), (int) (255 * alpha)); |
| 32 | } | 40 | } |
| 33 | } | 41 | } |
| 34 | 42 | ||
| @@ -73,12 +81,7 @@ public class Config { | |||
| 73 | public Decompiler decompiler = Decompiler.CFR; | 81 | public Decompiler decompiler = Decompiler.CFR; |
| 74 | 82 | ||
| 75 | public Config() { | 83 | public Config() { |
| 76 | gson = new GsonBuilder() | 84 | gson = new GsonBuilder().registerTypeAdapter(Integer.class, new IntSerializer()).registerTypeAdapter(Integer.class, new IntDeserializer()).registerTypeAdapter(Config.class, (InstanceCreator<Config>) type -> this).setPrettyPrinting().create(); |
| 77 | .registerTypeAdapter(Integer.class, new IntSerializer()) | ||
| 78 | .registerTypeAdapter(Integer.class, new IntDeserializer()) | ||
| 79 | .registerTypeAdapter(Config.class, (InstanceCreator<Config>) type -> this) | ||
| 80 | .setPrettyPrinting() | ||
| 81 | .create(); | ||
| 82 | this.loadConfig(); | 85 | this.loadConfig(); |
| 83 | } | 86 | } |
| 84 | 87 | ||
| @@ -105,5 +108,4 @@ public class Config { | |||
| 105 | return (int) Long.parseLong(json.getAsString().replace("#", ""), 16); | 108 | return (int) Long.parseLong(json.getAsString().replace("#", ""), 16); |
| 106 | } | 109 | } |
| 107 | } | 110 | } |
| 108 | |||
| 109 | } | 111 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java index f8922e6..c221120 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/AboutDialog.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.dialog; | 12 | package cuchaz.enigma.gui.dialog; |
| 13 | 13 | ||
| @@ -15,7 +15,11 @@ import java.awt.Container; | |||
| 15 | import java.awt.GridBagConstraints; | 15 | import java.awt.GridBagConstraints; |
| 16 | import java.awt.GridBagLayout; | 16 | import java.awt.GridBagLayout; |
| 17 | 17 | ||
| 18 | import javax.swing.*; | 18 | import javax.swing.JButton; |
| 19 | import javax.swing.JDialog; | ||
| 20 | import javax.swing.JFrame; | ||
| 21 | import javax.swing.JLabel; | ||
| 22 | import javax.swing.WindowConstants; | ||
| 19 | 23 | ||
| 20 | import cuchaz.enigma.Enigma; | 24 | import cuchaz.enigma.Enigma; |
| 21 | import cuchaz.enigma.gui.util.GridBagConstraintsBuilder; | 25 | import cuchaz.enigma.gui.util.GridBagConstraintsBuilder; |
| @@ -23,16 +27,12 @@ import cuchaz.enigma.gui.util.GuiUtil; | |||
| 23 | import cuchaz.enigma.utils.I18n; | 27 | import cuchaz.enigma.utils.I18n; |
| 24 | 28 | ||
| 25 | public class AboutDialog { | 29 | public class AboutDialog { |
| 26 | |||
| 27 | public static void show(JFrame parent) { | 30 | public static void show(JFrame parent) { |
| 28 | JDialog frame = new JDialog(parent, String.format(I18n.translate("menu.help.about.title"), Enigma.NAME), true); | 31 | JDialog frame = new JDialog(parent, String.format(I18n.translate("menu.help.about.title"), Enigma.NAME), true); |
| 29 | Container pane = frame.getContentPane(); | 32 | Container pane = frame.getContentPane(); |
| 30 | pane.setLayout(new GridBagLayout()); | 33 | pane.setLayout(new GridBagLayout()); |
| 31 | 34 | ||
| 32 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create() | 35 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2).weight(1.0, 0.0).anchor(GridBagConstraints.WEST); |
| 33 | .insets(2) | ||
| 34 | .weight(1.0, 0.0) | ||
| 35 | .anchor(GridBagConstraints.WEST); | ||
| 36 | 36 | ||
| 37 | JLabel title = new JLabel(Enigma.NAME); | 37 | JLabel title = new JLabel(Enigma.NAME); |
| 38 | title.setFont(title.getFont().deriveFont(title.getFont().getSize2D() * 1.5f)); | 38 | title.setFont(title.getFont().deriveFont(title.getFont().getSize2D() * 1.5f)); |
| @@ -52,5 +52,4 @@ public class AboutDialog { | |||
| 52 | frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); | 52 | frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); |
| 53 | frame.setVisible(true); | 53 | frame.setVisible(true); |
| 54 | } | 54 | } |
| 55 | |||
| 56 | } | 55 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/AbstractDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/AbstractDialog.java index c9ca809..76232c4 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/AbstractDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/AbstractDialog.java | |||
| @@ -1,6 +1,12 @@ | |||
| 1 | package cuchaz.enigma.gui.dialog; | 1 | package cuchaz.enigma.gui.dialog; |
| 2 | 2 | ||
| 3 | import java.awt.*; | 3 | import java.awt.BorderLayout; |
| 4 | import java.awt.Component; | ||
| 5 | import java.awt.Container; | ||
| 6 | import java.awt.FlowLayout; | ||
| 7 | import java.awt.Frame; | ||
| 8 | import java.awt.GridBagConstraints; | ||
| 9 | import java.awt.GridBagLayout; | ||
| 4 | import java.util.List; | 10 | import java.util.List; |
| 5 | 11 | ||
| 6 | import javax.swing.JButton; | 12 | import javax.swing.JButton; |
| @@ -15,7 +21,6 @@ import cuchaz.enigma.utils.Pair; | |||
| 15 | import cuchaz.enigma.utils.validation.ValidationContext; | 21 | import cuchaz.enigma.utils.validation.ValidationContext; |
| 16 | 22 | ||
| 17 | public abstract class AbstractDialog extends JDialog { | 23 | public abstract class AbstractDialog extends JDialog { |
| 18 | |||
| 19 | protected final ValidationContext vc = new ValidationContext(); | 24 | protected final ValidationContext vc = new ValidationContext(); |
| 20 | 25 | ||
| 21 | private boolean actionConfirm = false; | 26 | private boolean actionConfirm = false; |
| @@ -38,6 +43,7 @@ public abstract class AbstractDialog extends JDialog { | |||
| 38 | inputContainer.add(label, cb.pos(0, i).weightX(0.0).anchor(GridBagConstraints.LINE_END).fill(GridBagConstraints.NONE).build()); | 43 | inputContainer.add(label, cb.pos(0, i).weightX(0.0).anchor(GridBagConstraints.LINE_END).fill(GridBagConstraints.NONE).build()); |
| 39 | inputContainer.add(component, cb.pos(1, i).weightX(1.0).anchor(GridBagConstraints.LINE_END).fill(GridBagConstraints.HORIZONTAL).build()); | 44 | inputContainer.add(component, cb.pos(1, i).weightX(1.0).anchor(GridBagConstraints.LINE_END).fill(GridBagConstraints.HORIZONTAL).build()); |
| 40 | } | 45 | } |
| 46 | |||
| 41 | contentPane.add(inputContainer, BorderLayout.CENTER); | 47 | contentPane.add(inputContainer, BorderLayout.CENTER); |
| 42 | Container buttonContainer = new JPanel(new FlowLayout(FlowLayout.RIGHT, ScaleUtil.scale(4), ScaleUtil.scale(4))); | 48 | Container buttonContainer = new JPanel(new FlowLayout(FlowLayout.RIGHT, ScaleUtil.scale(4), ScaleUtil.scale(4))); |
| 43 | JButton connectButton = new JButton(I18n.translate(confirmAction)); | 49 | JButton connectButton = new JButton(I18n.translate(confirmAction)); |
| @@ -57,6 +63,7 @@ public abstract class AbstractDialog extends JDialog { | |||
| 57 | protected void confirm() { | 63 | protected void confirm() { |
| 58 | vc.reset(); | 64 | vc.reset(); |
| 59 | validateInputs(); | 65 | validateInputs(); |
| 66 | |||
| 60 | if (vc.canProceed()) { | 67 | if (vc.canProceed()) { |
| 61 | actionConfirm = true; | 68 | actionConfirm = true; |
| 62 | setVisible(false); | 69 | setVisible(false); |
| @@ -74,5 +81,4 @@ public abstract class AbstractDialog extends JDialog { | |||
| 74 | 81 | ||
| 75 | public void validateInputs() { | 82 | public void validateInputs() { |
| 76 | } | 83 | } |
| 77 | |||
| 78 | } | 84 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ChangeDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ChangeDialog.java index df65473..51948b5 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ChangeDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ChangeDialog.java | |||
| @@ -14,7 +14,6 @@ import javax.swing.JPanel; | |||
| 14 | import cuchaz.enigma.utils.I18n; | 14 | import cuchaz.enigma.utils.I18n; |
| 15 | 15 | ||
| 16 | public class ChangeDialog { | 16 | public class ChangeDialog { |
| 17 | |||
| 18 | public static void show(Window parent) { | 17 | public static void show(Window parent) { |
| 19 | // init frame | 18 | // init frame |
| 20 | JDialog frame = new JDialog(parent, I18n.translate("menu.view.change.title"), Dialog.DEFAULT_MODALITY_TYPE); | 19 | JDialog frame = new JDialog(parent, I18n.translate("menu.view.change.title"), Dialog.DEFAULT_MODALITY_TYPE); |
| @@ -48,5 +47,4 @@ public class ChangeDialog { | |||
| 48 | frame.setLocationRelativeTo(parent); | 47 | frame.setLocationRelativeTo(parent); |
| 49 | frame.setVisible(true); | 48 | frame.setVisible(true); |
| 50 | } | 49 | } |
| 51 | |||
| 52 | } | 50 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java index 2486dfe..1c2bd4c 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ConnectToServerDialog.java | |||
| @@ -20,7 +20,6 @@ import cuchaz.enigma.utils.validation.Message; | |||
| 20 | import cuchaz.enigma.utils.validation.StandardValidation; | 20 | import cuchaz.enigma.utils.validation.StandardValidation; |
| 21 | 21 | ||
| 22 | public class ConnectToServerDialog extends AbstractDialog { | 22 | public class ConnectToServerDialog extends AbstractDialog { |
| 23 | |||
| 24 | private JTextField usernameField; | 23 | private JTextField usernameField; |
| 25 | private ValidatableTextField ipField; | 24 | private ValidatableTextField ipField; |
| 26 | private JPasswordField passwordField; | 25 | private JPasswordField passwordField; |
| @@ -45,16 +44,13 @@ public class ConnectToServerDialog extends AbstractDialog { | |||
| 45 | ipField.addActionListener(event -> confirm()); | 44 | ipField.addActionListener(event -> confirm()); |
| 46 | passwordField.addActionListener(event -> confirm()); | 45 | passwordField.addActionListener(event -> confirm()); |
| 47 | 46 | ||
| 48 | return Arrays.asList( | 47 | return Arrays.asList(new Pair<>("prompt.connect.username", usernameField), new Pair<>("prompt.connect.address", ipField), new Pair<>("prompt.password", passwordField)); |
| 49 | new Pair<>("prompt.connect.username", usernameField), | ||
| 50 | new Pair<>("prompt.connect.address", ipField), | ||
| 51 | new Pair<>("prompt.password", passwordField) | ||
| 52 | ); | ||
| 53 | } | 48 | } |
| 54 | 49 | ||
| 55 | @Override | 50 | @Override |
| 56 | public void validateInputs() { | 51 | public void validateInputs() { |
| 57 | vc.setActiveElement(ipField); | 52 | vc.setActiveElement(ipField); |
| 53 | |||
| 58 | if (StandardValidation.notBlank(vc, ipField.getText())) { | 54 | if (StandardValidation.notBlank(vc, ipField.getText())) { |
| 59 | if (ServerAddress.from(ipField.getText(), EnigmaServer.DEFAULT_PORT) == null) { | 55 | if (ServerAddress.from(ipField.getText(), EnigmaServer.DEFAULT_PORT) == null) { |
| 60 | vc.raise(Message.INVALID_IP); | 56 | vc.raise(Message.INVALID_IP); |
| @@ -63,16 +59,18 @@ public class ConnectToServerDialog extends AbstractDialog { | |||
| 63 | } | 59 | } |
| 64 | 60 | ||
| 65 | public Result getResult() { | 61 | public Result getResult() { |
| 66 | if (!isActionConfirm()) return null; | 62 | if (!isActionConfirm()) { |
| 63 | return null; | ||
| 64 | } | ||
| 65 | |||
| 67 | vc.reset(); | 66 | vc.reset(); |
| 68 | validateInputs(); | 67 | validateInputs(); |
| 69 | if (!vc.canProceed()) return null; | 68 | |
| 70 | return new Result( | 69 | if (!vc.canProceed()) { |
| 71 | usernameField.getText(), | 70 | return null; |
| 72 | ipField.getText(), | 71 | } |
| 73 | Objects.requireNonNull(ServerAddress.from(ipField.getText(), EnigmaServer.DEFAULT_PORT)), | 72 | |
| 74 | passwordField.getPassword() | 73 | return new Result(usernameField.getText(), ipField.getText(), Objects.requireNonNull(ServerAddress.from(ipField.getText(), EnigmaServer.DEFAULT_PORT)), passwordField.getPassword()); |
| 75 | ); | ||
| 76 | } | 74 | } |
| 77 | 75 | ||
| 78 | public static Result show(Frame parent) { | 76 | public static Result show(Frame parent) { |
| @@ -114,5 +112,4 @@ public class ConnectToServerDialog extends AbstractDialog { | |||
| 114 | return password; | 112 | return password; |
| 115 | } | 113 | } |
| 116 | } | 114 | } |
| 117 | |||
| 118 | } | 115 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java index c2a93fa..a84e977 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CrashDialog.java | |||
| @@ -1,31 +1,42 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.dialog; | 12 | package cuchaz.enigma.gui.dialog; |
| 13 | 13 | ||
| 14 | import java.awt.BorderLayout; | ||
| 15 | import java.awt.Container; | ||
| 16 | import java.io.File; | ||
| 17 | import java.io.FileWriter; | ||
| 18 | import java.io.IOException; | ||
| 19 | import java.io.PrintWriter; | ||
| 20 | import java.io.StringWriter; | ||
| 21 | |||
| 22 | import javax.swing.BorderFactory; | ||
| 23 | import javax.swing.Box; | ||
| 24 | import javax.swing.BoxLayout; | ||
| 25 | import javax.swing.JButton; | ||
| 26 | import javax.swing.JFileChooser; | ||
| 27 | import javax.swing.JFrame; | ||
| 28 | import javax.swing.JLabel; | ||
| 29 | import javax.swing.JPanel; | ||
| 30 | import javax.swing.JScrollPane; | ||
| 31 | import javax.swing.JTextArea; | ||
| 32 | import javax.swing.WindowConstants; | ||
| 33 | |||
| 14 | import cuchaz.enigma.Enigma; | 34 | import cuchaz.enigma.Enigma; |
| 15 | import cuchaz.enigma.gui.util.GuiUtil; | 35 | import cuchaz.enigma.gui.util.GuiUtil; |
| 16 | import cuchaz.enigma.utils.I18n; | ||
| 17 | import cuchaz.enigma.gui.util.ScaleUtil; | 36 | import cuchaz.enigma.gui.util.ScaleUtil; |
| 18 | 37 | import cuchaz.enigma.utils.I18n; | |
| 19 | import javax.swing.*; | ||
| 20 | import java.awt.*; | ||
| 21 | import java.io.PrintWriter; | ||
| 22 | import java.io.StringWriter; | ||
| 23 | import java.io.FileWriter; | ||
| 24 | import java.io.File; | ||
| 25 | import java.io.IOException; | ||
| 26 | 38 | ||
| 27 | public class CrashDialog { | 39 | public class CrashDialog { |
| 28 | |||
| 29 | private static CrashDialog instance = null; | 40 | private static CrashDialog instance = null; |
| 30 | 41 | ||
| 31 | private JFrame frame; | 42 | private JFrame frame; |
| @@ -53,6 +64,7 @@ public class CrashDialog { | |||
| 53 | exportButton.addActionListener(event -> { | 64 | exportButton.addActionListener(event -> { |
| 54 | JFileChooser chooser = new JFileChooser(); | 65 | JFileChooser chooser = new JFileChooser(); |
| 55 | chooser.setSelectedFile(new File("enigma_crash.log")); | 66 | chooser.setSelectedFile(new File("enigma_crash.log")); |
| 67 | |||
| 56 | if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { | 68 | if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { |
| 57 | try { | 69 | try { |
| 58 | File file = chooser.getSelectedFile(); | 70 | File file = chooser.getSelectedFile(); |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java index 07daf6d..35999e2 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/CreateServerDialog.java | |||
| @@ -16,7 +16,6 @@ import cuchaz.enigma.utils.validation.Message; | |||
| 16 | import cuchaz.enigma.utils.validation.StandardValidation; | 16 | import cuchaz.enigma.utils.validation.StandardValidation; |
| 17 | 17 | ||
| 18 | public class CreateServerDialog extends AbstractDialog { | 18 | public class CreateServerDialog extends AbstractDialog { |
| 19 | |||
| 20 | private ValidatableTextField portField; | 19 | private ValidatableTextField portField; |
| 21 | private ValidatablePasswordField passwordField; | 20 | private ValidatablePasswordField passwordField; |
| 22 | 21 | ||
| @@ -38,10 +37,7 @@ public class CreateServerDialog extends AbstractDialog { | |||
| 38 | portField.addActionListener(event -> confirm()); | 37 | portField.addActionListener(event -> confirm()); |
| 39 | passwordField.addActionListener(event -> confirm()); | 38 | passwordField.addActionListener(event -> confirm()); |
| 40 | 39 | ||
| 41 | return Arrays.asList( | 40 | return Arrays.asList(new Pair<>("prompt.create_server.port", portField), new Pair<>("prompt.password", passwordField)); |
| 42 | new Pair<>("prompt.create_server.port", portField), | ||
| 43 | new Pair<>("prompt.password", passwordField) | ||
| 44 | ); | ||
| 45 | } | 41 | } |
| 46 | 42 | ||
| 47 | @Override | 43 | @Override |
| @@ -49,20 +45,25 @@ public class CreateServerDialog extends AbstractDialog { | |||
| 49 | vc.setActiveElement(portField); | 45 | vc.setActiveElement(portField); |
| 50 | StandardValidation.isIntInRange(vc, portField.getText(), 0, 65535); | 46 | StandardValidation.isIntInRange(vc, portField.getText(), 0, 65535); |
| 51 | vc.setActiveElement(passwordField); | 47 | vc.setActiveElement(passwordField); |
| 48 | |||
| 52 | if (passwordField.getPassword().length > EnigmaServer.MAX_PASSWORD_LENGTH) { | 49 | if (passwordField.getPassword().length > EnigmaServer.MAX_PASSWORD_LENGTH) { |
| 53 | vc.raise(Message.FIELD_LENGTH_OUT_OF_RANGE, EnigmaServer.MAX_PASSWORD_LENGTH); | 50 | vc.raise(Message.FIELD_LENGTH_OUT_OF_RANGE, EnigmaServer.MAX_PASSWORD_LENGTH); |
| 54 | } | 51 | } |
| 55 | } | 52 | } |
| 56 | 53 | ||
| 57 | public Result getResult() { | 54 | public Result getResult() { |
| 58 | if (!isActionConfirm()) return null; | 55 | if (!isActionConfirm()) { |
| 56 | return null; | ||
| 57 | } | ||
| 58 | |||
| 59 | vc.reset(); | 59 | vc.reset(); |
| 60 | validateInputs(); | 60 | validateInputs(); |
| 61 | if (!vc.canProceed()) return null; | 61 | |
| 62 | return new Result( | 62 | if (!vc.canProceed()) { |
| 63 | Integer.parseInt(portField.getText()), | 63 | return null; |
| 64 | passwordField.getPassword() | 64 | } |
| 65 | ); | 65 | |
| 66 | return new Result(Integer.parseInt(portField.getText()), passwordField.getPassword()); | ||
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | public static Result show(Frame parent) { | 69 | public static Result show(Frame parent) { |
| @@ -92,5 +93,4 @@ public class CreateServerDialog extends AbstractDialog { | |||
| 92 | return password; | 93 | return password; |
| 93 | } | 94 | } |
| 94 | } | 95 | } |
| 95 | |||
| 96 | } | 96 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/FontDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/FontDialog.java index 4e02a66..f0bae17 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/FontDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/FontDialog.java | |||
| @@ -1,6 +1,11 @@ | |||
| 1 | package cuchaz.enigma.gui.dialog; | 1 | package cuchaz.enigma.gui.dialog; |
| 2 | 2 | ||
| 3 | import java.awt.*; | 3 | import java.awt.Component; |
| 4 | import java.awt.Container; | ||
| 5 | import java.awt.Font; | ||
| 6 | import java.awt.Frame; | ||
| 7 | import java.awt.GridBagConstraints; | ||
| 8 | import java.awt.GridBagLayout; | ||
| 4 | import java.util.List; | 9 | import java.util.List; |
| 5 | 10 | ||
| 6 | import javax.swing.JButton; | 11 | import javax.swing.JButton; |
| @@ -16,20 +21,9 @@ import cuchaz.enigma.gui.util.ScaleUtil; | |||
| 16 | import cuchaz.enigma.utils.I18n; | 21 | import cuchaz.enigma.utils.I18n; |
| 17 | 22 | ||
| 18 | public class FontDialog extends JDialog { | 23 | public class FontDialog extends JDialog { |
| 24 | private static final List<String> CATEGORIES = List.of("Default", "Default 2", "Small", "Editor"); | ||
| 19 | 25 | ||
| 20 | private static final List<String> CATEGORIES = List.of( | 26 | private static final List<String> CATEGORY_TEXTS = List.of("fonts.cat.default", "fonts.cat.default2", "fonts.cat.small", "fonts.cat.editor"); |
| 21 | "Default", | ||
| 22 | "Default 2", | ||
| 23 | "Small", | ||
| 24 | "Editor" | ||
| 25 | ); | ||
| 26 | |||
| 27 | private static final List<String> CATEGORY_TEXTS = List.of( | ||
| 28 | "fonts.cat.default", | ||
| 29 | "fonts.cat.default2", | ||
| 30 | "fonts.cat.small", | ||
| 31 | "fonts.cat.editor" | ||
| 32 | ); | ||
| 33 | 27 | ||
| 34 | private final JList<String> entries = new JList<>(CATEGORY_TEXTS.stream().map(I18n::translate).toArray(String[]::new)); | 28 | private final JList<String> entries = new JList<>(CATEGORY_TEXTS.stream().map(I18n::translate).toArray(String[]::new)); |
| 35 | private final FontChooser chooser = new FontChooser(Font.decode(Font.DIALOG)); | 29 | private final FontChooser chooser = new FontChooser(Font.decode(Font.DIALOG)); |
| @@ -55,8 +49,7 @@ public class FontDialog extends JDialog { | |||
| 55 | Container contentPane = this.getContentPane(); | 49 | Container contentPane = this.getContentPane(); |
| 56 | contentPane.setLayout(new GridBagLayout()); | 50 | contentPane.setLayout(new GridBagLayout()); |
| 57 | 51 | ||
| 58 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create() | 52 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2); |
| 59 | .insets(2); | ||
| 60 | 53 | ||
| 61 | contentPane.add(this.entries, cb.pos(0, 0).weight(0.0, 1.0).fill(GridBagConstraints.BOTH).build()); | 54 | contentPane.add(this.entries, cb.pos(0, 0).weight(0.0, 1.0).fill(GridBagConstraints.BOTH).build()); |
| 62 | contentPane.add(this.chooser, cb.pos(1, 0).weight(1.0, 1.0).fill(GridBagConstraints.BOTH).size(2, 1).build()); | 55 | contentPane.add(this.chooser, cb.pos(1, 0).weight(1.0, 1.0).fill(GridBagConstraints.BOTH).size(2, 1).build()); |
| @@ -77,6 +70,7 @@ public class FontDialog extends JDialog { | |||
| 77 | private void categoryChanged() { | 70 | private void categoryChanged() { |
| 78 | this.updateUiState(); | 71 | this.updateUiState(); |
| 79 | int selectedIndex = this.entries.getSelectedIndex(); | 72 | int selectedIndex = this.entries.getSelectedIndex(); |
| 73 | |||
| 80 | if (selectedIndex != -1) { | 74 | if (selectedIndex != -1) { |
| 81 | this.chooser.setSelectedFont(this.fonts[selectedIndex]); | 75 | this.chooser.setSelectedFont(this.fonts[selectedIndex]); |
| 82 | } | 76 | } |
| @@ -84,6 +78,7 @@ public class FontDialog extends JDialog { | |||
| 84 | 78 | ||
| 85 | private void selectedFontChanged() { | 79 | private void selectedFontChanged() { |
| 86 | int selectedIndex = this.entries.getSelectedIndex(); | 80 | int selectedIndex = this.entries.getSelectedIndex(); |
| 81 | |||
| 87 | if (selectedIndex != -1) { | 82 | if (selectedIndex != -1) { |
| 88 | this.fonts[selectedIndex] = this.chooser.getSelectedFont(); | 83 | this.fonts[selectedIndex] = this.chooser.getSelectedFont(); |
| 89 | } | 84 | } |
| @@ -98,6 +93,7 @@ public class FontDialog extends JDialog { | |||
| 98 | for (int i = 0; i < CATEGORIES.size(); i++) { | 93 | for (int i = 0; i < CATEGORIES.size(); i++) { |
| 99 | UiConfig.setFont(CATEGORIES.get(i), this.fonts[i]); | 94 | UiConfig.setFont(CATEGORIES.get(i), this.fonts[i]); |
| 100 | } | 95 | } |
| 96 | |||
| 101 | UiConfig.setUseCustomFonts(this.customCheckBox.isSelected()); | 97 | UiConfig.setUseCustomFonts(this.customCheckBox.isSelected()); |
| 102 | UiConfig.save(); | 98 | UiConfig.save(); |
| 103 | ChangeDialog.show(this); | 99 | ChangeDialog.show(this); |
| @@ -118,8 +114,8 @@ public class FontDialog extends JDialog { | |||
| 118 | for (Component component : ((Container) self).getComponents()) { | 114 | for (Component component : ((Container) self).getComponents()) { |
| 119 | recursiveSetEnabled(component, enabled); | 115 | recursiveSetEnabled(component, enabled); |
| 120 | } | 116 | } |
| 117 | |||
| 121 | self.setEnabled(enabled); | 118 | self.setEnabled(enabled); |
| 122 | } | 119 | } |
| 123 | } | 120 | } |
| 124 | |||
| 125 | } | 121 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java index 9470e11..d6e544d 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/JavadocDialog.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.dialog; | 12 | package cuchaz.enigma.gui.dialog; |
| 13 | 13 | ||
| @@ -18,7 +18,15 @@ import java.awt.FlowLayout; | |||
| 18 | import java.awt.event.KeyAdapter; | 18 | import java.awt.event.KeyAdapter; |
| 19 | import java.awt.event.KeyEvent; | 19 | import java.awt.event.KeyEvent; |
| 20 | 20 | ||
| 21 | import javax.swing.*; | 21 | import javax.swing.JButton; |
| 22 | import javax.swing.JComboBox; | ||
| 23 | import javax.swing.JDialog; | ||
| 24 | import javax.swing.JFrame; | ||
| 25 | import javax.swing.JLabel; | ||
| 26 | import javax.swing.JMenuBar; | ||
| 27 | import javax.swing.JPanel; | ||
| 28 | import javax.swing.JScrollPane; | ||
| 29 | import javax.swing.WindowConstants; | ||
| 22 | import javax.swing.text.html.HTML; | 30 | import javax.swing.text.html.HTML; |
| 23 | 31 | ||
| 24 | import com.google.common.base.Strings; | 32 | import com.google.common.base.Strings; |
| @@ -35,7 +43,6 @@ import cuchaz.enigma.utils.I18n; | |||
| 35 | import cuchaz.enigma.utils.validation.ValidationContext; | 43 | import cuchaz.enigma.utils.validation.ValidationContext; |
| 36 | 44 | ||
| 37 | public class JavadocDialog { | 45 | public class JavadocDialog { |
| 38 | |||
| 39 | private final JDialog ui; | 46 | private final JDialog ui; |
| 40 | private final GuiController controller; | 47 | private final GuiController controller; |
| 41 | private final Entry<?> entry; | 48 | private final Entry<?> entry; |
| @@ -62,19 +69,21 @@ public class JavadocDialog { | |||
| 62 | @Override | 69 | @Override |
| 63 | public void keyPressed(KeyEvent event) { | 70 | public void keyPressed(KeyEvent event) { |
| 64 | switch (event.getKeyCode()) { | 71 | switch (event.getKeyCode()) { |
| 65 | case KeyEvent.VK_ENTER: | 72 | case KeyEvent.VK_ENTER: |
| 66 | if (event.isControlDown()) { | 73 | if (event.isControlDown()) { |
| 67 | doSave(); | 74 | doSave(); |
| 68 | if (vc.canProceed()) { | 75 | |
| 69 | close(); | 76 | if (vc.canProceed()) { |
| 70 | } | 77 | close(); |
| 71 | } | 78 | } |
| 72 | break; | 79 | } |
| 73 | case KeyEvent.VK_ESCAPE: | 80 | |
| 74 | close(); | 81 | break; |
| 75 | break; | 82 | case KeyEvent.VK_ESCAPE: |
| 76 | default: | 83 | close(); |
| 77 | break; | 84 | break; |
| 85 | default: | ||
| 86 | break; | ||
| 78 | } | 87 | } |
| 79 | } | 88 | } |
| 80 | }); | 89 | }); |
| @@ -108,6 +117,7 @@ public class JavadocDialog { | |||
| 108 | } else { | 117 | } else { |
| 109 | tagText = tag.getText() + " " + text.getSelectedText(); | 118 | tagText = tag.getText() + " " + text.getSelectedText(); |
| 110 | } | 119 | } |
| 120 | |||
| 111 | text.replaceSelection(tagText); | 121 | text.replaceSelection(tagText); |
| 112 | } else { | 122 | } else { |
| 113 | text.insert(tagText, text.getCaretPosition()); | 123 | text.insert(tagText, text.getCaretPosition()); |
| @@ -116,6 +126,7 @@ public class JavadocDialog { | |||
| 116 | if (tag.isInline()) { | 126 | if (tag.isInline()) { |
| 117 | text.setCaretPosition(text.getCaretPosition() - 1); | 127 | text.setCaretPosition(text.getCaretPosition() - 1); |
| 118 | } | 128 | } |
| 129 | |||
| 119 | text.grabFocus(); | 130 | text.grabFocus(); |
| 120 | }); | 131 | }); |
| 121 | tagsMenu.add(tagButton); | 132 | tagsMenu.add(tagButton); |
| @@ -124,9 +135,11 @@ public class JavadocDialog { | |||
| 124 | // add html tags | 135 | // add html tags |
| 125 | JComboBox<String> htmlList = new JComboBox<String>(); | 136 | JComboBox<String> htmlList = new JComboBox<String>(); |
| 126 | htmlList.setPreferredSize(new Dimension()); | 137 | htmlList.setPreferredSize(new Dimension()); |
| 138 | |||
| 127 | for (HTML.Tag htmlTag : HTML.getAllTags()) { | 139 | for (HTML.Tag htmlTag : HTML.getAllTags()) { |
| 128 | htmlList.addItem(htmlTag.toString()); | 140 | htmlList.addItem(htmlTag.toString()); |
| 129 | } | 141 | } |
| 142 | |||
| 130 | htmlList.addActionListener(action -> { | 143 | htmlList.addActionListener(action -> { |
| 131 | String tagText = "<" + htmlList.getSelectedItem().toString() + ">"; | 144 | String tagText = "<" + htmlList.getSelectedItem().toString() + ">"; |
| 132 | text.insert(tagText, text.getCaretPosition()); | 145 | text.insert(tagText, text.getCaretPosition()); |
| @@ -146,9 +159,17 @@ public class JavadocDialog { | |||
| 146 | public void doSave() { | 159 | public void doSave() { |
| 147 | vc.reset(); | 160 | vc.reset(); |
| 148 | validate(); | 161 | validate(); |
| 149 | if (!vc.canProceed()) return; | 162 | |
| 163 | if (!vc.canProceed()) { | ||
| 164 | return; | ||
| 165 | } | ||
| 166 | |||
| 150 | save(); | 167 | save(); |
| 151 | if (!vc.canProceed()) return; | 168 | |
| 169 | if (!vc.canProceed()) { | ||
| 170 | return; | ||
| 171 | } | ||
| 172 | |||
| 152 | close(); | 173 | close(); |
| 153 | } | 174 | } |
| 154 | 175 | ||
| @@ -189,7 +210,7 @@ public class JavadocDialog { | |||
| 189 | 210 | ||
| 190 | private boolean inline; | 211 | private boolean inline; |
| 191 | 212 | ||
| 192 | private JavadocTag(boolean inline) { | 213 | JavadocTag(boolean inline) { |
| 193 | this.inline = inline; | 214 | this.inline = inline; |
| 194 | } | 215 | } |
| 195 | 216 | ||
| @@ -201,5 +222,4 @@ public class JavadocDialog { | |||
| 201 | return this.inline; | 222 | return this.inline; |
| 202 | } | 223 | } |
| 203 | } | 224 | } |
| 204 | |||
| 205 | } | 225 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java index d76ddea..3beae21 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/ProgressDialog.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.dialog; | 12 | package cuchaz.enigma.gui.dialog; |
| 13 | 13 | ||
| @@ -17,7 +17,12 @@ import java.awt.GridBagConstraints; | |||
| 17 | import java.awt.GridBagLayout; | 17 | import java.awt.GridBagLayout; |
| 18 | import java.util.concurrent.CompletableFuture; | 18 | import java.util.concurrent.CompletableFuture; |
| 19 | 19 | ||
| 20 | import javax.swing.*; | 20 | import javax.swing.JDialog; |
| 21 | import javax.swing.JFrame; | ||
| 22 | import javax.swing.JLabel; | ||
| 23 | import javax.swing.JProgressBar; | ||
| 24 | import javax.swing.SwingUtilities; | ||
| 25 | import javax.swing.WindowConstants; | ||
| 21 | 26 | ||
| 22 | import cuchaz.enigma.Enigma; | 27 | import cuchaz.enigma.Enigma; |
| 23 | import cuchaz.enigma.ProgressListener; | 28 | import cuchaz.enigma.ProgressListener; |
| @@ -27,7 +32,6 @@ import cuchaz.enigma.gui.util.ScaleUtil; | |||
| 27 | import cuchaz.enigma.utils.I18n; | 32 | import cuchaz.enigma.utils.I18n; |
| 28 | 33 | ||
| 29 | public class ProgressDialog implements ProgressListener, AutoCloseable { | 34 | public class ProgressDialog implements ProgressListener, AutoCloseable { |
| 30 | |||
| 31 | private final JDialog dialog; | 35 | private final JDialog dialog; |
| 32 | private final JLabel labelTitle = new JLabel(); | 36 | private final JLabel labelTitle = new JLabel(); |
| 33 | private final JLabel labelText = GuiUtil.unboldLabel(new JLabel()); | 37 | private final JLabel labelText = GuiUtil.unboldLabel(new JLabel()); |
| @@ -39,11 +43,7 @@ public class ProgressDialog implements ProgressListener, AutoCloseable { | |||
| 39 | Container pane = this.dialog.getContentPane(); | 43 | Container pane = this.dialog.getContentPane(); |
| 40 | pane.setLayout(new GridBagLayout()); | 44 | pane.setLayout(new GridBagLayout()); |
| 41 | 45 | ||
| 42 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create() | 46 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2).anchor(GridBagConstraints.WEST).fill(GridBagConstraints.BOTH).weight(1.0, 0.0); |
| 43 | .insets(2) | ||
| 44 | .anchor(GridBagConstraints.WEST) | ||
| 45 | .fill(GridBagConstraints.BOTH) | ||
| 46 | .weight(1.0, 0.0); | ||
| 47 | 47 | ||
| 48 | pane.add(this.labelTitle, cb.pos(0, 0).build()); | 48 | pane.add(this.labelTitle, cb.pos(0, 0).build()); |
| 49 | pane.add(this.labelText, cb.pos(0, 1).build()); | 49 | pane.add(this.labelText, cb.pos(0, 1).build()); |
| @@ -121,6 +121,7 @@ public class ProgressDialog implements ProgressListener, AutoCloseable { | |||
| 121 | public void step(int numDone, String message) { | 121 | public void step(int numDone, String message) { |
| 122 | SwingUtilities.invokeLater(() -> { | 122 | SwingUtilities.invokeLater(() -> { |
| 123 | this.labelText.setText(message); | 123 | this.labelText.setText(message); |
| 124 | |||
| 124 | if (numDone != -1) { | 125 | if (numDone != -1) { |
| 125 | this.progress.setValue(numDone); | 126 | this.progress.setValue(numDone); |
| 126 | this.progress.setIndeterminate(false); | 127 | this.progress.setIndeterminate(false); |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java index e65b661..7814dd8 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/SearchDialog.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.dialog; | 12 | package cuchaz.enigma.gui.dialog; |
| 13 | 13 | ||
| @@ -15,17 +15,36 @@ import java.awt.BorderLayout; | |||
| 15 | import java.awt.Color; | 15 | import java.awt.Color; |
| 16 | import java.awt.FlowLayout; | 16 | import java.awt.FlowLayout; |
| 17 | import java.awt.Font; | 17 | import java.awt.Font; |
| 18 | import java.awt.event.*; | 18 | import java.awt.event.ComponentAdapter; |
| 19 | import java.util.*; | 19 | import java.awt.event.ComponentEvent; |
| 20 | import java.awt.event.KeyAdapter; | ||
| 21 | import java.awt.event.KeyEvent; | ||
| 22 | import java.awt.event.MouseAdapter; | ||
| 23 | import java.awt.event.MouseEvent; | ||
| 24 | import java.util.Arrays; | ||
| 25 | import java.util.Collections; | ||
| 26 | import java.util.List; | ||
| 27 | import java.util.Queue; | ||
| 20 | import java.util.concurrent.ConcurrentLinkedQueue; | 28 | import java.util.concurrent.ConcurrentLinkedQueue; |
| 21 | 29 | ||
| 22 | import javax.swing.*; | 30 | import javax.swing.DefaultListModel; |
| 31 | import javax.swing.JButton; | ||
| 32 | import javax.swing.JDialog; | ||
| 33 | import javax.swing.JLabel; | ||
| 34 | import javax.swing.JList; | ||
| 35 | import javax.swing.JPanel; | ||
| 36 | import javax.swing.JScrollPane; | ||
| 37 | import javax.swing.JTextField; | ||
| 38 | import javax.swing.ListSelectionModel; | ||
| 39 | import javax.swing.SwingUtilities; | ||
| 23 | import javax.swing.event.DocumentEvent; | 40 | import javax.swing.event.DocumentEvent; |
| 24 | import javax.swing.event.DocumentListener; | 41 | import javax.swing.event.DocumentListener; |
| 25 | 42 | ||
| 26 | import cuchaz.enigma.analysis.index.EntryIndex; | 43 | import cuchaz.enigma.analysis.index.EntryIndex; |
| 27 | import cuchaz.enigma.gui.Gui; | 44 | import cuchaz.enigma.gui.Gui; |
| 28 | import cuchaz.enigma.gui.GuiController; | 45 | import cuchaz.enigma.gui.GuiController; |
| 46 | import cuchaz.enigma.gui.search.SearchEntry; | ||
| 47 | import cuchaz.enigma.gui.search.SearchUtil; | ||
| 29 | import cuchaz.enigma.gui.util.AbstractListCellRenderer; | 48 | import cuchaz.enigma.gui.util.AbstractListCellRenderer; |
| 30 | import cuchaz.enigma.gui.util.GuiUtil; | 49 | import cuchaz.enigma.gui.util.GuiUtil; |
| 31 | import cuchaz.enigma.gui.util.ScaleUtil; | 50 | import cuchaz.enigma.gui.util.ScaleUtil; |
| @@ -34,11 +53,8 @@ import cuchaz.enigma.translation.representation.entry.FieldEntry; | |||
| 34 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | 53 | import cuchaz.enigma.translation.representation.entry.MethodEntry; |
| 35 | import cuchaz.enigma.translation.representation.entry.ParentedEntry; | 54 | import cuchaz.enigma.translation.representation.entry.ParentedEntry; |
| 36 | import cuchaz.enigma.utils.I18n; | 55 | import cuchaz.enigma.utils.I18n; |
| 37 | import cuchaz.enigma.gui.search.SearchEntry; | ||
| 38 | import cuchaz.enigma.gui.search.SearchUtil; | ||
| 39 | 56 | ||
| 40 | public class SearchDialog { | 57 | public class SearchDialog { |
| 41 | |||
| 42 | private final JTextField searchField; | 58 | private final JTextField searchField; |
| 43 | private DefaultListModel<SearchEntryImpl> classListModel; | 59 | private DefaultListModel<SearchEntryImpl> classListModel; |
| 44 | private final JList<SearchEntryImpl> classList; | 60 | private final JList<SearchEntryImpl> classList; |
| @@ -60,7 +76,6 @@ public class SearchDialog { | |||
| 60 | 76 | ||
| 61 | searchField = new JTextField(); | 77 | searchField = new JTextField(); |
| 62 | searchField.getDocument().addDocumentListener(new DocumentListener() { | 78 | searchField.getDocument().addDocumentListener(new DocumentListener() { |
| 63 | |||
| 64 | @Override | 79 | @Override |
| 65 | public void insertUpdate(DocumentEvent e) { | 80 | public void insertUpdate(DocumentEvent e) { |
| 66 | updateList(); | 81 | updateList(); |
| @@ -75,7 +90,6 @@ public class SearchDialog { | |||
| 75 | public void changedUpdate(DocumentEvent e) { | 90 | public void changedUpdate(DocumentEvent e) { |
| 76 | updateList(); | 91 | updateList(); |
| 77 | } | 92 | } |
| 78 | |||
| 79 | }); | 93 | }); |
| 80 | searchField.addKeyListener(new KeyAdapter() { | 94 | searchField.addKeyListener(new KeyAdapter() { |
| 81 | @Override | 95 | @Override |
| @@ -143,23 +157,9 @@ public class SearchDialog { | |||
| 143 | final EntryIndex entryIndex = parent.getController().project.getJarIndex().getEntryIndex(); | 157 | final EntryIndex entryIndex = parent.getController().project.getJarIndex().getEntryIndex(); |
| 144 | 158 | ||
| 145 | switch (type) { | 159 | switch (type) { |
| 146 | case CLASS -> entryIndex.getClasses().parallelStream() | 160 | case CLASS -> entryIndex.getClasses().parallelStream().filter(e -> !e.isInnerClass()).map(e -> SearchEntryImpl.from(e, parent.getController())).map(SearchUtil.Entry::from).sequential().forEach(su::add); |
| 147 | .filter(e -> !e.isInnerClass()) | 161 | case METHOD -> entryIndex.getMethods().parallelStream().filter(e -> !e.isConstructor() && !entryIndex.getMethodAccess(e).isSynthetic()).map(e -> SearchEntryImpl.from(e, parent.getController())).map(SearchUtil.Entry::from).sequential().forEach(su::add); |
| 148 | .map(e -> SearchEntryImpl.from(e, parent.getController())) | 162 | case FIELD -> entryIndex.getFields().parallelStream().map(e -> SearchEntryImpl.from(e, parent.getController())).map(SearchUtil.Entry::from).sequential().forEach(su::add); |
| 149 | .map(SearchUtil.Entry::from) | ||
| 150 | .sequential() | ||
| 151 | .forEach(su::add); | ||
| 152 | case METHOD -> entryIndex.getMethods().parallelStream() | ||
| 153 | .filter(e -> !e.isConstructor() && !entryIndex.getMethodAccess(e).isSynthetic()) | ||
| 154 | .map(e -> SearchEntryImpl.from(e, parent.getController())) | ||
| 155 | .map(SearchUtil.Entry::from) | ||
| 156 | .sequential() | ||
| 157 | .forEach(su::add); | ||
| 158 | case FIELD -> entryIndex.getFields().parallelStream() | ||
| 159 | .map(e -> SearchEntryImpl.from(e, parent.getController())) | ||
| 160 | .map(SearchUtil.Entry::from) | ||
| 161 | .sequential() | ||
| 162 | .forEach(su::add); | ||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | updateList(); | 165 | updateList(); |
| @@ -172,6 +172,7 @@ public class SearchDialog { | |||
| 172 | 172 | ||
| 173 | private void openSelected() { | 173 | private void openSelected() { |
| 174 | SearchEntryImpl selectedValue = classList.getSelectedValue(); | 174 | SearchEntryImpl selectedValue = classList.getSelectedValue(); |
| 175 | |||
| 175 | if (selectedValue != null) { | 176 | if (selectedValue != null) { |
| 176 | openEntry(selectedValue); | 177 | openEntry(selectedValue); |
| 177 | } | 178 | } |
| @@ -181,6 +182,7 @@ public class SearchDialog { | |||
| 181 | close(); | 182 | close(); |
| 182 | su.hit(e); | 183 | su.hit(e); |
| 183 | parent.getController().navigateTo(e.obf); | 184 | parent.getController().navigateTo(e.obf); |
| 185 | |||
| 184 | if (e.obf instanceof ClassEntry) { | 186 | if (e.obf instanceof ClassEntry) { |
| 185 | if (e.deobf != null) { | 187 | if (e.deobf != null) { |
| 186 | parent.getDeobfPanel().deobfClasses.setSelectionClass((ClassEntry) e.deobf); | 188 | parent.getDeobfPanel().deobfClasses.setSelectionClass((ClassEntry) e.deobf); |
| @@ -202,7 +204,9 @@ public class SearchDialog { | |||
| 202 | 204 | ||
| 203 | // Updates the list of class names | 205 | // Updates the list of class names |
| 204 | private void updateList() { | 206 | private void updateList() { |
| 205 | if (currentSearch != null) currentSearch.stop(); | 207 | if (currentSearch != null) { |
| 208 | currentSearch.stop(); | ||
| 209 | } | ||
| 206 | 210 | ||
| 207 | DefaultListModel<SearchEntryImpl> classListModel = new DefaultListModel<>(); | 211 | DefaultListModel<SearchEntryImpl> classListModel = new DefaultListModel<>(); |
| 208 | this.classListModel = classListModel; | 212 | this.classListModel = classListModel; |
| @@ -210,7 +214,9 @@ public class SearchDialog { | |||
| 210 | 214 | ||
| 211 | // handle these search result like minecraft scheduled tasks to prevent | 215 | // handle these search result like minecraft scheduled tasks to prevent |
| 212 | // flooding swing buttons inputs etc with tons of (possibly outdated) invocations | 216 | // flooding swing buttons inputs etc with tons of (possibly outdated) invocations |
| 213 | record Order(int idx, SearchEntryImpl e) {} | 217 | record Order(int idx, SearchEntryImpl e) { |
| 218 | } | ||
| 219 | |||
| 214 | Queue<Order> queue = new ConcurrentLinkedQueue<>(); | 220 | Queue<Order> queue = new ConcurrentLinkedQueue<>(); |
| 215 | Runnable updater = new Runnable() { | 221 | Runnable updater = new Runnable() { |
| 216 | @Override | 222 | @Override |
| @@ -221,8 +227,9 @@ public class SearchDialog { | |||
| 221 | 227 | ||
| 222 | // too large count may increase delay for key and input handling, etc. | 228 | // too large count may increase delay for key and input handling, etc. |
| 223 | int count = 100; | 229 | int count = 100; |
| 230 | |||
| 224 | while (count > 0 && !queue.isEmpty()) { | 231 | while (count > 0 && !queue.isEmpty()) { |
| 225 | var o = queue.remove(); | 232 | Order o = queue.remove(); |
| 226 | classListModel.insertElementAt(o.e, o.idx); | 233 | classListModel.insertElementAt(o.e, o.idx); |
| 227 | count--; | 234 | count--; |
| 228 | } | 235 | } |
| @@ -240,7 +247,6 @@ public class SearchDialog { | |||
| 240 | } | 247 | } |
| 241 | 248 | ||
| 242 | private static final class SearchEntryImpl implements SearchEntry { | 249 | private static final class SearchEntryImpl implements SearchEntry { |
| 243 | |||
| 244 | public final ParentedEntry<?> obf; | 250 | public final ParentedEntry<?> obf; |
| 245 | public final ParentedEntry<?> deobf; | 251 | public final ParentedEntry<?> deobf; |
| 246 | 252 | ||
| @@ -270,10 +276,13 @@ public class SearchDialog { | |||
| 270 | 276 | ||
| 271 | public static SearchEntryImpl from(ParentedEntry<?> e, GuiController controller) { | 277 | public static SearchEntryImpl from(ParentedEntry<?> e, GuiController controller) { |
| 272 | ParentedEntry<?> deobf = controller.project.getMapper().deobfuscate(e); | 278 | ParentedEntry<?> deobf = controller.project.getMapper().deobfuscate(e); |
| 273 | if (deobf.equals(e)) deobf = null; | 279 | |
| 280 | if (deobf.equals(e)) { | ||
| 281 | deobf = null; | ||
| 282 | } | ||
| 283 | |||
| 274 | return new SearchEntryImpl(e, deobf); | 284 | return new SearchEntryImpl(e, deobf); |
| 275 | } | 285 | } |
| 276 | |||
| 277 | } | 286 | } |
| 278 | 287 | ||
| 279 | private static final class ListCellRendererImpl extends AbstractListCellRenderer<SearchEntryImpl> { | 288 | private static final class ListCellRendererImpl extends AbstractListCellRenderer<SearchEntryImpl> { |
| @@ -281,7 +290,7 @@ public class SearchDialog { | |||
| 281 | private final JLabel mainName; | 290 | private final JLabel mainName; |
| 282 | private final JLabel secondaryName; | 291 | private final JLabel secondaryName; |
| 283 | 292 | ||
| 284 | public ListCellRendererImpl(Gui gui) { | 293 | ListCellRendererImpl(Gui gui) { |
| 285 | this.setLayout(new BorderLayout()); | 294 | this.setLayout(new BorderLayout()); |
| 286 | this.gui = gui; | 295 | this.gui = gui; |
| 287 | 296 | ||
| @@ -316,7 +325,6 @@ public class SearchDialog { | |||
| 316 | mainName.setIcon(GuiUtil.FIELD_ICON); | 325 | mainName.setIcon(GuiUtil.FIELD_ICON); |
| 317 | } | 326 | } |
| 318 | } | 327 | } |
| 319 | |||
| 320 | } | 328 | } |
| 321 | 329 | ||
| 322 | public enum Type { | 330 | public enum Type { |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java index 0398093..1ab66ef 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/dialog/StatsDialog.java | |||
| @@ -4,10 +4,19 @@ import java.awt.Container; | |||
| 4 | import java.awt.Dimension; | 4 | import java.awt.Dimension; |
| 5 | import java.awt.GridBagConstraints; | 5 | import java.awt.GridBagConstraints; |
| 6 | import java.awt.GridBagLayout; | 6 | import java.awt.GridBagLayout; |
| 7 | import java.util.*; | 7 | import java.util.Collections; |
| 8 | import java.util.HashMap; | ||
| 9 | import java.util.Locale; | ||
| 10 | import java.util.Map; | ||
| 11 | import java.util.Set; | ||
| 8 | import java.util.stream.Collectors; | 12 | import java.util.stream.Collectors; |
| 9 | 13 | ||
| 10 | import javax.swing.*; | 14 | import javax.swing.JButton; |
| 15 | import javax.swing.JCheckBox; | ||
| 16 | import javax.swing.JDialog; | ||
| 17 | import javax.swing.JLabel; | ||
| 18 | import javax.swing.JTextField; | ||
| 19 | import javax.swing.SwingUtilities; | ||
| 11 | 20 | ||
| 12 | import cuchaz.enigma.gui.Gui; | 21 | import cuchaz.enigma.gui.Gui; |
| 13 | import cuchaz.enigma.gui.config.UiConfig; | 22 | import cuchaz.enigma.gui.config.UiConfig; |
| @@ -19,14 +28,15 @@ import cuchaz.enigma.gui.util.ScaleUtil; | |||
| 19 | import cuchaz.enigma.utils.I18n; | 28 | import cuchaz.enigma.utils.I18n; |
| 20 | 29 | ||
| 21 | public class StatsDialog { | 30 | public class StatsDialog { |
| 22 | |||
| 23 | public static void show(Gui gui) { | 31 | public static void show(Gui gui) { |
| 24 | ProgressDialog.runOffThread(gui.getFrame(), listener -> { | 32 | ProgressDialog.runOffThread(gui.getFrame(), listener -> { |
| 25 | final StatsGenerator statsGenerator = new StatsGenerator(gui.getController().project); | 33 | final StatsGenerator statsGenerator = new StatsGenerator(gui.getController().project); |
| 26 | final Map<StatsMember, StatsResult> results = new HashMap<>(); | 34 | final Map<StatsMember, StatsResult> results = new HashMap<>(); |
| 35 | |||
| 27 | for (StatsMember member : StatsMember.values()) { | 36 | for (StatsMember member : StatsMember.values()) { |
| 28 | results.put(member, statsGenerator.generate(listener, Collections.singleton(member), "", false)); | 37 | results.put(member, statsGenerator.generate(listener, Collections.singleton(member), "", false)); |
| 29 | } | 38 | } |
| 39 | |||
| 30 | SwingUtilities.invokeLater(() -> show(gui, results)); | 40 | SwingUtilities.invokeLater(() -> show(gui, results)); |
| 31 | }); | 41 | }); |
| 32 | } | 42 | } |
| @@ -111,12 +121,7 @@ public class StatsDialog { | |||
| 111 | 121 | ||
| 112 | private static void generateStats(Gui gui, Map<StatsMember, JCheckBox> checkboxes, String topLevelPackage, boolean includeSynthetic) { | 122 | private static void generateStats(Gui gui, Map<StatsMember, JCheckBox> checkboxes, String topLevelPackage, boolean includeSynthetic) { |
| 113 | // get members from selected checkboxes | 123 | // get members from selected checkboxes |
| 114 | Set<StatsMember> includedMembers = checkboxes | 124 | Set<StatsMember> includedMembers = checkboxes.entrySet().stream().filter(entry -> entry.getValue().isSelected()).map(Map.Entry::getKey).collect(Collectors.toSet()); |
| 115 | .entrySet() | ||
| 116 | .stream() | ||
| 117 | .filter(entry -> entry.getValue().isSelected()) | ||
| 118 | .map(Map.Entry::getKey) | ||
| 119 | .collect(Collectors.toSet()); | ||
| 120 | 125 | ||
| 121 | // checks if a project is open | 126 | // checks if a project is open |
| 122 | if (gui.getController().project != null) { | 127 | if (gui.getController().project != null) { |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/AbstractInheritanceTree.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/AbstractInheritanceTree.java index 39aa212..3f1625d 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/AbstractInheritanceTree.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/AbstractInheritanceTree.java | |||
| @@ -7,7 +7,11 @@ import javax.annotation.Nullable; | |||
| 7 | import javax.swing.JPanel; | 7 | import javax.swing.JPanel; |
| 8 | import javax.swing.JScrollPane; | 8 | import javax.swing.JScrollPane; |
| 9 | import javax.swing.JTree; | 9 | import javax.swing.JTree; |
| 10 | import javax.swing.tree.*; | 10 | import javax.swing.tree.DefaultMutableTreeNode; |
| 11 | import javax.swing.tree.DefaultTreeModel; | ||
| 12 | import javax.swing.tree.TreeCellRenderer; | ||
| 13 | import javax.swing.tree.TreeNode; | ||
| 14 | import javax.swing.tree.TreePath; | ||
| 11 | 15 | ||
| 12 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; | 16 | import cuchaz.enigma.analysis.ClassInheritanceTreeNode; |
| 13 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; | 17 | import cuchaz.enigma.analysis.MethodInheritanceTreeNode; |
| @@ -40,11 +44,13 @@ public abstract class AbstractInheritanceTree { | |||
| 40 | if (event.getClickCount() >= 2 && event.getButton() == MouseEvent.BUTTON1) { | 44 | if (event.getClickCount() >= 2 && event.getButton() == MouseEvent.BUTTON1) { |
| 41 | // get the selected node | 45 | // get the selected node |
| 42 | TreePath path = tree.getSelectionPath(); | 46 | TreePath path = tree.getSelectionPath(); |
| 47 | |||
| 43 | if (path == null) { | 48 | if (path == null) { |
| 44 | return; | 49 | return; |
| 45 | } | 50 | } |
| 46 | 51 | ||
| 47 | Object node = path.getLastPathComponent(); | 52 | Object node = path.getLastPathComponent(); |
| 53 | |||
| 48 | if (node instanceof ClassInheritanceTreeNode classNode) { | 54 | if (node instanceof ClassInheritanceTreeNode classNode) { |
| 49 | gui.getController().navigateTo(new ClassEntry(classNode.getObfClassName())); | 55 | gui.getController().navigateTo(new ClassEntry(classNode.getObfClassName())); |
| 50 | } else if (node instanceof MethodInheritanceTreeNode methodNode) { | 56 | } else if (node instanceof MethodInheritanceTreeNode methodNode) { |
| @@ -72,7 +78,6 @@ public abstract class AbstractInheritanceTree { | |||
| 72 | } | 78 | } |
| 73 | 79 | ||
| 74 | public void retranslateUi() { | 80 | public void retranslateUi() { |
| 75 | |||
| 76 | } | 81 | } |
| 77 | 82 | ||
| 78 | @Nullable | 83 | @Nullable |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CallsTree.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CallsTree.java index c92534f..5671188 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CallsTree.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CallsTree.java | |||
| @@ -5,7 +5,12 @@ import java.awt.event.MouseEvent; | |||
| 5 | import java.util.Collection; | 5 | import java.util.Collection; |
| 6 | import java.util.Vector; | 6 | import java.util.Vector; |
| 7 | 7 | ||
| 8 | import javax.swing.*; | 8 | import javax.swing.JList; |
| 9 | import javax.swing.JPanel; | ||
| 10 | import javax.swing.JScrollPane; | ||
| 11 | import javax.swing.JSplitPane; | ||
| 12 | import javax.swing.JTree; | ||
| 13 | import javax.swing.ListSelectionModel; | ||
| 9 | import javax.swing.tree.DefaultTreeModel; | 14 | import javax.swing.tree.DefaultTreeModel; |
| 10 | import javax.swing.tree.TreeNode; | 15 | import javax.swing.tree.TreeNode; |
| 11 | import javax.swing.tree.TreePath; | 16 | import javax.swing.tree.TreePath; |
| @@ -47,12 +52,7 @@ public class CallsTree { | |||
| 47 | this.tokens.setPreferredSize(ScaleUtil.getDimension(0, 200)); | 52 | this.tokens.setPreferredSize(ScaleUtil.getDimension(0, 200)); |
| 48 | this.tokens.setMinimumSize(ScaleUtil.getDimension(0, 200)); | 53 | this.tokens.setMinimumSize(ScaleUtil.getDimension(0, 200)); |
| 49 | 54 | ||
| 50 | JSplitPane contentPane = new JSplitPane( | 55 | JSplitPane contentPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, new JScrollPane(this.callsTree), new JScrollPane(this.tokens)); |
| 51 | JSplitPane.VERTICAL_SPLIT, | ||
| 52 | true, | ||
| 53 | new JScrollPane(this.callsTree), | ||
| 54 | new JScrollPane(this.tokens) | ||
| 55 | ); | ||
| 56 | 56 | ||
| 57 | contentPane.setResizeWeight(1); // let the top side take all the slack | 57 | contentPane.setResizeWeight(1); // let the top side take all the slack |
| 58 | contentPane.resetToPreferredSizes(); | 58 | contentPane.resetToPreferredSizes(); |
| @@ -109,6 +109,7 @@ public class CallsTree { | |||
| 109 | private void onTokenClicked(MouseEvent event) { | 109 | private void onTokenClicked(MouseEvent event) { |
| 110 | if (event.getClickCount() == 2) { | 110 | if (event.getClickCount() == 2) { |
| 111 | Token selected = this.tokens.getSelectedValue(); | 111 | Token selected = this.tokens.getSelectedValue(); |
| 112 | |||
| 112 | if (selected != null) { | 113 | if (selected != null) { |
| 113 | this.gui.openClass(this.gui.getController().getTokenHandle().getRef()).navigateToToken(selected); | 114 | this.gui.openClass(this.gui.getController().getTokenHandle().getRef()).navigateToToken(selected); |
| 114 | } | 115 | } |
| @@ -116,7 +117,6 @@ public class CallsTree { | |||
| 116 | } | 117 | } |
| 117 | 118 | ||
| 118 | public void retranslateUi() { | 119 | public void retranslateUi() { |
| 119 | |||
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | public JPanel getPanel() { | 122 | public JPanel getPanel() { |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CollapsibleTabbedPane.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CollapsibleTabbedPane.java index fb497b1..e05ab45 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CollapsibleTabbedPane.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/CollapsibleTabbedPane.java | |||
| @@ -5,7 +5,6 @@ import java.awt.event.MouseEvent; | |||
| 5 | import javax.swing.JTabbedPane; | 5 | import javax.swing.JTabbedPane; |
| 6 | 6 | ||
| 7 | public class CollapsibleTabbedPane extends JTabbedPane { | 7 | public class CollapsibleTabbedPane extends JTabbedPane { |
| 8 | |||
| 9 | public CollapsibleTabbedPane() { | 8 | public CollapsibleTabbedPane() { |
| 10 | } | 9 | } |
| 11 | 10 | ||
| @@ -20,9 +19,14 @@ public class CollapsibleTabbedPane extends JTabbedPane { | |||
| 20 | @Override | 19 | @Override |
| 21 | protected void processMouseEvent(MouseEvent e) { | 20 | protected void processMouseEvent(MouseEvent e) { |
| 22 | int id = e.getID(); | 21 | int id = e.getID(); |
| 22 | |||
| 23 | if (id == MouseEvent.MOUSE_PRESSED) { | 23 | if (id == MouseEvent.MOUSE_PRESSED) { |
| 24 | if (!isEnabled()) return; | 24 | if (!isEnabled()) { |
| 25 | return; | ||
| 26 | } | ||
| 27 | |||
| 25 | int tabIndex = getUI().tabForCoordinate(this, e.getX(), e.getY()); | 28 | int tabIndex = getUI().tabForCoordinate(this, e.getX(), e.getY()); |
| 29 | |||
| 26 | if (tabIndex >= 0 && isEnabledAt(tabIndex)) { | 30 | if (tabIndex >= 0 && isEnabledAt(tabIndex)) { |
| 27 | if (tabIndex == getSelectedIndex()) { | 31 | if (tabIndex == getSelectedIndex()) { |
| 28 | if (isFocusOwner() && isRequestFocusEnabled()) { | 32 | if (isFocusOwner() && isRequestFocusEnabled()) { |
| @@ -30,11 +34,12 @@ public class CollapsibleTabbedPane extends JTabbedPane { | |||
| 30 | } else { | 34 | } else { |
| 31 | setSelectedIndex(-1); | 35 | setSelectedIndex(-1); |
| 32 | } | 36 | } |
| 37 | |||
| 33 | return; | 38 | return; |
| 34 | } | 39 | } |
| 35 | } | 40 | } |
| 36 | } | 41 | } |
| 42 | |||
| 37 | super.processMouseEvent(e); | 43 | super.processMouseEvent(e); |
| 38 | } | 44 | } |
| 39 | |||
| 40 | } | 45 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java index 9a6ea09..301ae7f 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ConvertingTextField.java | |||
| @@ -1,7 +1,12 @@ | |||
| 1 | package cuchaz.enigma.gui.elements; | 1 | package cuchaz.enigma.gui.elements; |
| 2 | 2 | ||
| 3 | import java.awt.GridLayout; | 3 | import java.awt.GridLayout; |
| 4 | import java.awt.event.*; | 4 | import java.awt.event.FocusAdapter; |
| 5 | import java.awt.event.FocusEvent; | ||
| 6 | import java.awt.event.KeyAdapter; | ||
| 7 | import java.awt.event.KeyEvent; | ||
| 8 | import java.awt.event.MouseAdapter; | ||
| 9 | import java.awt.event.MouseEvent; | ||
| 5 | import java.util.HashSet; | 10 | import java.util.HashSet; |
| 6 | import java.util.Set; | 11 | import java.util.Set; |
| 7 | 12 | ||
| @@ -21,7 +26,6 @@ import cuchaz.enigma.utils.validation.Validatable; | |||
| 21 | * A label that converts into an editable text field when you click it. | 26 | * A label that converts into an editable text field when you click it. |
| 22 | */ | 27 | */ |
| 23 | public class ConvertingTextField implements Validatable { | 28 | public class ConvertingTextField implements Validatable { |
| 24 | |||
| 25 | private final JPanel ui; | 29 | private final JPanel ui; |
| 26 | private final ValidatableTextField textField; | 30 | private final ValidatableTextField textField; |
| 27 | private final JLabel label; | 31 | private final JLabel label; |
| @@ -69,7 +73,9 @@ public class ConvertingTextField implements Validatable { | |||
| 69 | } | 73 | } |
| 70 | 74 | ||
| 71 | public void startEditing() { | 75 | public void startEditing() { |
| 72 | if (this.editing || !this.editable) return; | 76 | if (this.editing || !this.editable) { |
| 77 | return; | ||
| 78 | } | ||
| 73 | 79 | ||
| 74 | this.ui.removeAll(); | 80 | this.ui.removeAll(); |
| 75 | this.ui.add(this.textField); | 81 | this.ui.add(this.textField); |
| @@ -82,9 +88,13 @@ public class ConvertingTextField implements Validatable { | |||
| 82 | } | 88 | } |
| 83 | 89 | ||
| 84 | public void stopEditing(boolean abort) { | 90 | public void stopEditing(boolean abort) { |
| 85 | if (!editing) return; | 91 | if (!editing) { |
| 92 | return; | ||
| 93 | } | ||
| 86 | 94 | ||
| 87 | if (!listeners.stream().allMatch(l -> l.tryStopEditing(this, abort))) return; | 95 | if (!listeners.stream().allMatch(l -> l.tryStopEditing(this, abort))) { |
| 96 | return; | ||
| 97 | } | ||
| 88 | 98 | ||
| 89 | if (abort) { | 99 | if (abort) { |
| 90 | this.textField.setText(this.label.getText()); | 100 | this.textField.setText(this.label.getText()); |
| @@ -107,7 +117,9 @@ public class ConvertingTextField implements Validatable { | |||
| 107 | } | 117 | } |
| 108 | 118 | ||
| 109 | public void setEditText(String text) { | 119 | public void setEditText(String text) { |
| 110 | if (!editing) return; | 120 | if (!editing) { |
| 121 | return; | ||
| 122 | } | ||
| 111 | 123 | ||
| 112 | this.textField.setText(text); | 124 | this.textField.setText(text); |
| 113 | } | 125 | } |
| @@ -122,22 +134,29 @@ public class ConvertingTextField implements Validatable { | |||
| 122 | } | 134 | } |
| 123 | 135 | ||
| 124 | public void selectAll() { | 136 | public void selectAll() { |
| 125 | if (!editing) return; | 137 | if (!editing) { |
| 138 | return; | ||
| 139 | } | ||
| 126 | 140 | ||
| 127 | this.textField.selectAll(); | 141 | this.textField.selectAll(); |
| 128 | } | 142 | } |
| 129 | 143 | ||
| 130 | public void selectSubstring(int startIndex) { | 144 | public void selectSubstring(int startIndex) { |
| 131 | if (!editing) return; | 145 | if (!editing) { |
| 146 | return; | ||
| 147 | } | ||
| 132 | 148 | ||
| 133 | Document doc = this.textField.getDocument(); | 149 | Document doc = this.textField.getDocument(); |
| 150 | |||
| 134 | if (doc != null) { | 151 | if (doc != null) { |
| 135 | this.selectSubstring(startIndex, doc.getLength()); | 152 | this.selectSubstring(startIndex, doc.getLength()); |
| 136 | } | 153 | } |
| 137 | } | 154 | } |
| 138 | 155 | ||
| 139 | public void selectSubstring(int startIndex, int endIndex) { | 156 | public void selectSubstring(int startIndex, int endIndex) { |
| 140 | if (!editing) return; | 157 | if (!editing) { |
| 158 | return; | ||
| 159 | } | ||
| 141 | 160 | ||
| 142 | this.textField.select(startIndex, endIndex); | 161 | this.textField.select(startIndex, endIndex); |
| 143 | } | 162 | } |
| @@ -155,7 +174,10 @@ public class ConvertingTextField implements Validatable { | |||
| 155 | } | 174 | } |
| 156 | 175 | ||
| 157 | public boolean hasChanges() { | 176 | public boolean hasChanges() { |
| 158 | if (!editing) return false; | 177 | if (!editing) { |
| 178 | return false; | ||
| 179 | } | ||
| 180 | |||
| 159 | return !this.textField.getText().equals(this.label.getText()); | 181 | return !this.textField.getText().equals(this.label.getText()); |
| 160 | } | 182 | } |
| 161 | 183 | ||
| @@ -180,5 +202,4 @@ public class ConvertingTextField implements Validatable { | |||
| 180 | public JPanel getUi() { | 202 | public JPanel getUi() { |
| 181 | return ui; | 203 | return ui; |
| 182 | } | 204 | } |
| 183 | |||
| 184 | } | 205 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/DeobfPanelPopupMenu.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/DeobfPanelPopupMenu.java index 0b44881..bcc6dc6 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/DeobfPanelPopupMenu.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/DeobfPanelPopupMenu.java | |||
| @@ -9,55 +9,54 @@ import cuchaz.enigma.gui.panels.DeobfPanel; | |||
| 9 | import cuchaz.enigma.utils.I18n; | 9 | import cuchaz.enigma.utils.I18n; |
| 10 | 10 | ||
| 11 | public class DeobfPanelPopupMenu { | 11 | public class DeobfPanelPopupMenu { |
| 12 | 12 | private final JPopupMenu ui; | |
| 13 | private final JPopupMenu ui; | 13 | private final JMenuItem renamePackage = new JMenuItem(); |
| 14 | private final JMenuItem renamePackage = new JMenuItem(); | 14 | private final JMenuItem renameClass = new JMenuItem(); |
| 15 | private final JMenuItem renameClass = new JMenuItem(); | 15 | private final JMenuItem expandAll = new JMenuItem(); |
| 16 | private final JMenuItem expandAll = new JMenuItem(); | 16 | private final JMenuItem collapseAll = new JMenuItem(); |
| 17 | private final JMenuItem collapseAll = new JMenuItem(); | 17 | |
| 18 | 18 | public DeobfPanelPopupMenu(DeobfPanel panel) { | |
| 19 | public DeobfPanelPopupMenu(DeobfPanel panel) { | 19 | this.ui = new JPopupMenu(); |
| 20 | this.ui = new JPopupMenu(); | 20 | |
| 21 | 21 | this.ui.add(this.renamePackage); | |
| 22 | this.ui.add(this.renamePackage); | 22 | this.ui.add(this.renameClass); |
| 23 | this.ui.add(this.renameClass); | 23 | this.ui.addSeparator(); |
| 24 | this.ui.addSeparator(); | 24 | this.ui.add(this.expandAll); |
| 25 | this.ui.add(this.expandAll); | 25 | this.ui.add(this.collapseAll); |
| 26 | this.ui.add(this.collapseAll); | 26 | |
| 27 | 27 | ClassSelector deobfClasses = panel.deobfClasses; | |
| 28 | ClassSelector deobfClasses = panel.deobfClasses; | 28 | |
| 29 | 29 | this.renamePackage.addActionListener(a -> { | |
| 30 | this.renamePackage.addActionListener(a -> { | 30 | TreePath path; |
| 31 | TreePath path; | 31 | |
| 32 | 32 | if (deobfClasses.getSelectedClass() != null) { | |
| 33 | if (deobfClasses.getSelectedClass() != null) { | 33 | // Rename parent package if selected path is a class |
| 34 | // Rename parent package if selected path is a class | 34 | path = deobfClasses.getSelectionPath().getParentPath(); |
| 35 | path = deobfClasses.getSelectionPath().getParentPath(); | 35 | } else { |
| 36 | } else { | 36 | // Rename selected path if it's already a package |
| 37 | // Rename selected path if it's already a package | 37 | path = deobfClasses.getSelectionPath(); |
| 38 | path = deobfClasses.getSelectionPath(); | 38 | } |
| 39 | } | 39 | |
| 40 | 40 | deobfClasses.getUI().startEditingAtPath(deobfClasses, path); | |
| 41 | deobfClasses.getUI().startEditingAtPath(deobfClasses, path); | 41 | }); |
| 42 | }); | 42 | this.renameClass.addActionListener(a -> deobfClasses.getUI().startEditingAtPath(deobfClasses, deobfClasses.getSelectionPath())); |
| 43 | this.renameClass.addActionListener(a -> deobfClasses.getUI().startEditingAtPath(deobfClasses, deobfClasses.getSelectionPath())); | 43 | this.expandAll.addActionListener(a -> deobfClasses.expandAll()); |
| 44 | this.expandAll.addActionListener(a -> deobfClasses.expandAll()); | 44 | this.collapseAll.addActionListener(a -> deobfClasses.collapseAll()); |
| 45 | this.collapseAll.addActionListener(a -> deobfClasses.collapseAll()); | 45 | |
| 46 | 46 | this.retranslateUi(); | |
| 47 | this.retranslateUi(); | 47 | } |
| 48 | } | 48 | |
| 49 | 49 | public void show(ClassSelector deobfClasses, int x, int y) { | |
| 50 | public void show(ClassSelector deobfClasses, int x, int y) { | 50 | // Only enable rename class if selected path is a class |
| 51 | // Only enable rename class if selected path is a class | 51 | this.renameClass.setEnabled(deobfClasses.getSelectedClass() != null); |
| 52 | this.renameClass.setEnabled(deobfClasses.getSelectedClass() != null); | 52 | |
| 53 | 53 | this.ui.show(deobfClasses, x, y); | |
| 54 | this.ui.show(deobfClasses, x, y); | 54 | } |
| 55 | } | 55 | |
| 56 | 56 | public void retranslateUi() { | |
| 57 | public void retranslateUi() { | 57 | this.renamePackage.setText(I18n.translate("popup_menu.deobf_panel.rename_package")); |
| 58 | this.renamePackage.setText(I18n.translate("popup_menu.deobf_panel.rename_package")); | 58 | this.renameClass.setText(I18n.translate("popup_menu.deobf_panel.rename_class")); |
| 59 | this.renameClass.setText(I18n.translate("popup_menu.deobf_panel.rename_class")); | 59 | this.expandAll.setText(I18n.translate("popup_menu.deobf_panel.expand_all")); |
| 60 | this.expandAll.setText(I18n.translate("popup_menu.deobf_panel.expand_all")); | 60 | this.collapseAll.setText(I18n.translate("popup_menu.deobf_panel.collapse_all")); |
| 61 | this.collapseAll.setText(I18n.translate("popup_menu.deobf_panel.collapse_all")); | 61 | } |
| 62 | } | ||
| 63 | } | 62 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java index 2ce6ed9..d128bf5 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorPopupMenu.java | |||
| @@ -19,7 +19,6 @@ import cuchaz.enigma.translation.representation.entry.MethodEntry; | |||
| 19 | import cuchaz.enigma.utils.I18n; | 19 | import cuchaz.enigma.utils.I18n; |
| 20 | 20 | ||
| 21 | public class EditorPopupMenu { | 21 | public class EditorPopupMenu { |
| 22 | |||
| 23 | private final JPopupMenu ui = new JPopupMenu(); | 22 | private final JPopupMenu ui = new JPopupMenu(); |
| 24 | 23 | ||
| 25 | private final JMenuItem renameItem = new JMenuItem(); | 24 | private final JMenuItem renameItem = new JMenuItem(); |
| @@ -105,39 +104,41 @@ public class EditorPopupMenu { | |||
| 105 | public boolean handleKeyEvent(KeyEvent event) { | 104 | public boolean handleKeyEvent(KeyEvent event) { |
| 106 | if (event.isControlDown()) { | 105 | if (event.isControlDown()) { |
| 107 | switch (event.getKeyCode()) { | 106 | switch (event.getKeyCode()) { |
| 108 | case KeyEvent.VK_I: | 107 | case KeyEvent.VK_I: |
| 109 | this.showInheritanceItem.doClick(); | 108 | this.showInheritanceItem.doClick(); |
| 110 | return true; | 109 | return true; |
| 111 | case KeyEvent.VK_M: | 110 | case KeyEvent.VK_M: |
| 112 | this.showImplementationsItem.doClick(); | 111 | this.showImplementationsItem.doClick(); |
| 113 | return true; | 112 | return true; |
| 114 | case KeyEvent.VK_N: | 113 | case KeyEvent.VK_N: |
| 115 | this.openEntryItem.doClick(); | 114 | this.openEntryItem.doClick(); |
| 116 | return true; | 115 | return true; |
| 117 | case KeyEvent.VK_P: | 116 | case KeyEvent.VK_P: |
| 118 | this.openPreviousItem.doClick(); | 117 | this.openPreviousItem.doClick(); |
| 119 | return true; | 118 | return true; |
| 120 | case KeyEvent.VK_E: | 119 | case KeyEvent.VK_E: |
| 121 | this.openNextItem.doClick(); | 120 | this.openNextItem.doClick(); |
| 122 | return true; | 121 | return true; |
| 123 | case KeyEvent.VK_C: | 122 | case KeyEvent.VK_C: |
| 124 | if (event.isShiftDown()) { | 123 | if (event.isShiftDown()) { |
| 125 | this.showCallsSpecificItem.doClick(); | 124 | this.showCallsSpecificItem.doClick(); |
| 126 | } else { | 125 | } else { |
| 127 | this.showCallsItem.doClick(); | 126 | this.showCallsItem.doClick(); |
| 128 | } | 127 | } |
| 129 | return true; | 128 | |
| 130 | case KeyEvent.VK_O: | 129 | return true; |
| 131 | this.toggleMappingItem.doClick(); | 130 | case KeyEvent.VK_O: |
| 132 | return true; | 131 | this.toggleMappingItem.doClick(); |
| 133 | case KeyEvent.VK_R: | 132 | return true; |
| 134 | this.renameItem.doClick(); | 133 | case KeyEvent.VK_R: |
| 135 | return true; | 134 | this.renameItem.doClick(); |
| 136 | case KeyEvent.VK_D: | 135 | return true; |
| 137 | this.editJavadocItem.doClick(); | 136 | case KeyEvent.VK_D: |
| 138 | return true; | 137 | this.editJavadocItem.doClick(); |
| 138 | return true; | ||
| 139 | } | 139 | } |
| 140 | } | 140 | } |
| 141 | |||
| 141 | return false; | 142 | return false; |
| 142 | } | 143 | } |
| 143 | 144 | ||
| @@ -191,5 +192,4 @@ public class EditorPopupMenu { | |||
| 191 | public JPopupMenu getUi() { | 192 | public JPopupMenu getUi() { |
| 192 | return ui; | 193 | return ui; |
| 193 | } | 194 | } |
| 194 | |||
| 195 | } | 195 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorTabPopupMenu.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorTabPopupMenu.java index 0b4926e..9385481 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorTabPopupMenu.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorTabPopupMenu.java | |||
| @@ -11,7 +11,6 @@ import cuchaz.enigma.gui.panels.EditorPanel; | |||
| 11 | import cuchaz.enigma.utils.I18n; | 11 | import cuchaz.enigma.utils.I18n; |
| 12 | 12 | ||
| 13 | public class EditorTabPopupMenu { | 13 | public class EditorTabPopupMenu { |
| 14 | |||
| 15 | private final JPopupMenu ui; | 14 | private final JPopupMenu ui; |
| 16 | private final JMenuItem close; | 15 | private final JMenuItem close; |
| 17 | private final JMenuItem closeAll; | 16 | private final JMenuItem closeAll; |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorTabbedPane.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorTabbedPane.java index ff0bba3..7a6290e 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorTabbedPane.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/EditorTabbedPane.java | |||
| @@ -39,7 +39,11 @@ public class EditorTabbedPane { | |||
| 39 | public EditorPanel openClass(ClassEntry entry) { | 39 | public EditorPanel openClass(ClassEntry entry) { |
| 40 | EditorPanel editorPanel = this.editors.computeIfAbsent(entry, e -> { | 40 | EditorPanel editorPanel = this.editors.computeIfAbsent(entry, e -> { |
| 41 | ClassHandle ch = this.gui.getController().getClassHandleProvider().openClass(entry); | 41 | ClassHandle ch = this.gui.getController().getClassHandleProvider().openClass(entry); |
| 42 | if (ch == null) return null; | 42 | |
| 43 | if (ch == null) { | ||
| 44 | return null; | ||
| 45 | } | ||
| 46 | |||
| 43 | EditorPanel ed = new EditorPanel(this.gui); | 47 | EditorPanel ed = new EditorPanel(this.gui); |
| 44 | ed.setup(); | 48 | ed.setup(); |
| 45 | ed.setClassHandle(ch); | 49 | ed.setClassHandle(ch); |
| @@ -125,7 +129,10 @@ public class EditorTabbedPane { | |||
| 125 | int index = this.openFiles.indexOfComponent(ed.getUi()); | 129 | int index = this.openFiles.indexOfComponent(ed.getUi()); |
| 126 | 130 | ||
| 127 | for (int i = this.openFiles.getTabCount() - 1; i >= 0; i--) { | 131 | for (int i = this.openFiles.getTabCount() - 1; i >= 0; i--) { |
| 128 | if (i == index) continue; | 132 | if (i == index) { |
| 133 | continue; | ||
| 134 | } | ||
| 135 | |||
| 129 | closeEditor(EditorPanel.byUi(this.openFiles.getComponentAt(i))); | 136 | closeEditor(EditorPanel.byUi(this.openFiles.getComponentAt(i))); |
| 130 | } | 137 | } |
| 131 | } | 138 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/JMultiLineToolTip.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/JMultiLineToolTip.java index 533d1b3..9e632d9 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/JMultiLineToolTip.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/JMultiLineToolTip.java | |||
| @@ -12,13 +12,12 @@ import javax.swing.plaf.ComponentUI; | |||
| 12 | import javax.swing.plaf.basic.BasicToolTipUI; | 12 | import javax.swing.plaf.basic.BasicToolTipUI; |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| 15 | * Implements a multi line tooltip for GUI components | 15 | * Implements a multi line tooltip for GUI components. |
| 16 | * Copied from http://www.codeguru.com/java/articles/122.shtml | 16 | * Copied from http://www.codeguru.com/java/articles/122.shtml |
| 17 | * | 17 | * |
| 18 | * @author Zafir Anjum | 18 | * @author Zafir Anjum |
| 19 | */ | 19 | */ |
| 20 | public class JMultiLineToolTip extends JToolTip { | 20 | public class JMultiLineToolTip extends JToolTip { |
| 21 | |||
| 22 | private static final long serialVersionUID = 7813662474312183098L; | 21 | private static final long serialVersionUID = 7813662474312183098L; |
| 23 | 22 | ||
| 24 | public JMultiLineToolTip() { | 23 | public JMultiLineToolTip() { |
| @@ -52,10 +51,9 @@ public class JMultiLineToolTip extends JToolTip { | |||
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | /** | 53 | /** |
| 55 | * UI for multi line tool tip | 54 | * UI for multi line tool tip. |
| 56 | */ | 55 | */ |
| 57 | class MultiLineToolTipUI extends BasicToolTipUI { | 56 | class MultiLineToolTipUI extends BasicToolTipUI { |
| 58 | |||
| 59 | static MultiLineToolTipUI sharedInstance = new MultiLineToolTipUI(); | 57 | static MultiLineToolTipUI sharedInstance = new MultiLineToolTipUI(); |
| 60 | Font smallFont; | 58 | Font smallFont; |
| 61 | static JToolTip tip; | 59 | static JToolTip tip; |
| @@ -67,7 +65,7 @@ class MultiLineToolTipUI extends BasicToolTipUI { | |||
| 67 | return sharedInstance; | 65 | return sharedInstance; |
| 68 | } | 66 | } |
| 69 | 67 | ||
| 70 | public MultiLineToolTipUI() { | 68 | MultiLineToolTipUI() { |
| 71 | super(); | 69 | super(); |
| 72 | } | 70 | } |
| 73 | 71 | ||
| @@ -93,7 +91,11 @@ class MultiLineToolTipUI extends BasicToolTipUI { | |||
| 93 | 91 | ||
| 94 | public Dimension getPreferredSize(JComponent c) { | 92 | public Dimension getPreferredSize(JComponent c) { |
| 95 | String tipText = ((JToolTip) c).getTipText(); | 93 | String tipText = ((JToolTip) c).getTipText(); |
| 96 | if (tipText == null) return new Dimension(0, 0); | 94 | |
| 95 | if (tipText == null) { | ||
| 96 | return new Dimension(0, 0); | ||
| 97 | } | ||
| 98 | |||
| 97 | textArea = new JTextArea(tipText); | 99 | textArea = new JTextArea(tipText); |
| 98 | rendererPane.removeAll(); | 100 | rendererPane.removeAll(); |
| 99 | rendererPane.add(textArea); | 101 | rendererPane.add(textArea); |
| @@ -112,8 +114,9 @@ class MultiLineToolTipUI extends BasicToolTipUI { | |||
| 112 | d.width = width; | 114 | d.width = width; |
| 113 | d.height++; | 115 | d.height++; |
| 114 | textArea.setSize(d); | 116 | textArea.setSize(d); |
| 115 | } else | 117 | } else { |
| 116 | textArea.setLineWrap(false); | 118 | textArea.setLineWrap(false); |
| 119 | } | ||
| 117 | 120 | ||
| 118 | Dimension dim = textArea.getPreferredSize(); | 121 | Dimension dim = textArea.getPreferredSize(); |
| 119 | 122 | ||
| @@ -129,4 +132,4 @@ class MultiLineToolTipUI extends BasicToolTipUI { | |||
| 129 | public Dimension getMaximumSize(JComponent c) { | 132 | public Dimension getMaximumSize(JComponent c) { |
| 130 | return getPreferredSize(c); | 133 | return getPreferredSize(c); |
| 131 | } | 134 | } |
| 132 | } \ No newline at end of file | 135 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index eeb52cc..24a69b6 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java | |||
| @@ -12,7 +12,14 @@ import java.util.Map; | |||
| 12 | import java.util.stream.Collectors; | 12 | import java.util.stream.Collectors; |
| 13 | import java.util.stream.IntStream; | 13 | import java.util.stream.IntStream; |
| 14 | 14 | ||
| 15 | import javax.swing.*; | 15 | import javax.swing.ButtonGroup; |
| 16 | import javax.swing.JFileChooser; | ||
| 17 | import javax.swing.JMenu; | ||
| 18 | import javax.swing.JMenuBar; | ||
| 19 | import javax.swing.JMenuItem; | ||
| 20 | import javax.swing.JOptionPane; | ||
| 21 | import javax.swing.JRadioButtonMenuItem; | ||
| 22 | import javax.swing.KeyStroke; | ||
| 16 | 23 | ||
| 17 | import cuchaz.enigma.gui.ConnectionState; | 24 | import cuchaz.enigma.gui.ConnectionState; |
| 18 | import cuchaz.enigma.gui.Gui; | 25 | import cuchaz.enigma.gui.Gui; |
| @@ -20,7 +27,13 @@ import cuchaz.enigma.gui.config.Decompiler; | |||
| 20 | import cuchaz.enigma.gui.config.LookAndFeel; | 27 | import cuchaz.enigma.gui.config.LookAndFeel; |
| 21 | import cuchaz.enigma.gui.config.NetConfig; | 28 | import cuchaz.enigma.gui.config.NetConfig; |
| 22 | import cuchaz.enigma.gui.config.UiConfig; | 29 | import cuchaz.enigma.gui.config.UiConfig; |
| 23 | import cuchaz.enigma.gui.dialog.*; | 30 | import cuchaz.enigma.gui.dialog.AboutDialog; |
| 31 | import cuchaz.enigma.gui.dialog.ChangeDialog; | ||
| 32 | import cuchaz.enigma.gui.dialog.ConnectToServerDialog; | ||
| 33 | import cuchaz.enigma.gui.dialog.CreateServerDialog; | ||
| 34 | import cuchaz.enigma.gui.dialog.FontDialog; | ||
| 35 | import cuchaz.enigma.gui.dialog.SearchDialog; | ||
| 36 | import cuchaz.enigma.gui.dialog.StatsDialog; | ||
| 24 | import cuchaz.enigma.gui.util.GuiUtil; | 37 | import cuchaz.enigma.gui.util.GuiUtil; |
| 25 | import cuchaz.enigma.gui.util.LanguageUtil; | 38 | import cuchaz.enigma.gui.util.LanguageUtil; |
| 26 | import cuchaz.enigma.gui.util.ScaleUtil; | 39 | import cuchaz.enigma.gui.util.ScaleUtil; |
| @@ -29,7 +42,6 @@ import cuchaz.enigma.utils.I18n; | |||
| 29 | import cuchaz.enigma.utils.Pair; | 42 | import cuchaz.enigma.utils.Pair; |
| 30 | 43 | ||
| 31 | public class MenuBar { | 44 | public class MenuBar { |
| 32 | |||
| 33 | private final JMenu fileMenu = new JMenu(); | 45 | private final JMenu fileMenu = new JMenu(); |
| 34 | private final JMenuItem jarOpenItem = new JMenuItem(); | 46 | private final JMenuItem jarOpenItem = new JMenuItem(); |
| 35 | private final JMenuItem jarCloseItem = new JMenuItem(); | 47 | private final JMenuItem jarCloseItem = new JMenuItem(); |
| @@ -221,13 +233,16 @@ public class MenuBar { | |||
| 221 | } | 233 | } |
| 222 | 234 | ||
| 223 | File file = d.getSelectedFile(); | 235 | File file = d.getSelectedFile(); |
| 236 | |||
| 224 | // checks if the file name is not empty | 237 | // checks if the file name is not empty |
| 225 | if (file != null) { | 238 | if (file != null) { |
| 226 | Path path = file.toPath(); | 239 | Path path = file.toPath(); |
| 240 | |||
| 227 | // checks if the file name corresponds to an existing file | 241 | // checks if the file name corresponds to an existing file |
| 228 | if (Files.exists(path)) { | 242 | if (Files.exists(path)) { |
| 229 | this.gui.getController().openJar(path); | 243 | this.gui.getController().openJar(path); |
| 230 | } | 244 | } |
| 245 | |||
| 231 | UiConfig.setLastSelectedDir(d.getCurrentDirectory().getAbsolutePath()); | 246 | UiConfig.setLastSelectedDir(d.getCurrentDirectory().getAbsolutePath()); |
| 232 | } | 247 | } |
| 233 | } | 248 | } |
| @@ -241,8 +256,10 @@ public class MenuBar { | |||
| 241 | this.gui.showDiscardDiag((response -> { | 256 | this.gui.showDiscardDiag((response -> { |
| 242 | if (response == JOptionPane.YES_OPTION) { | 257 | if (response == JOptionPane.YES_OPTION) { |
| 243 | this.gui.saveMapping().thenRun(then); | 258 | this.gui.saveMapping().thenRun(then); |
| 244 | } else if (response == JOptionPane.NO_OPTION) | 259 | } else if (response == JOptionPane.NO_OPTION) { |
| 245 | then.run(); | 260 | then.run(); |
| 261 | } | ||
| 262 | |||
| 246 | return null; | 263 | return null; |
| 247 | }), I18n.translate("prompt.close.save"), I18n.translate("prompt.close.discard"), I18n.translate("prompt.cancel")); | 264 | }), I18n.translate("prompt.close.save"), I18n.translate("prompt.close.discard"), I18n.translate("prompt.cancel")); |
| 248 | } else { | 265 | } else { |
| @@ -264,6 +281,7 @@ public class MenuBar { | |||
| 264 | 281 | ||
| 265 | private void onExportSourceClicked() { | 282 | private void onExportSourceClicked() { |
| 266 | this.gui.exportSourceFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir())); | 283 | this.gui.exportSourceFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir())); |
| 284 | |||
| 267 | if (this.gui.exportSourceFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | 285 | if (this.gui.exportSourceFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { |
| 268 | UiConfig.setLastSelectedDir(this.gui.exportSourceFileChooser.getCurrentDirectory().toString()); | 286 | UiConfig.setLastSelectedDir(this.gui.exportSourceFileChooser.getCurrentDirectory().toString()); |
| 269 | this.gui.getController().exportSource(this.gui.exportSourceFileChooser.getSelectedFile().toPath()); | 287 | this.gui.getController().exportSource(this.gui.exportSourceFileChooser.getSelectedFile().toPath()); |
| @@ -287,29 +305,35 @@ public class MenuBar { | |||
| 287 | } | 305 | } |
| 288 | 306 | ||
| 289 | private void onCustomScaleClicked() { | 307 | private void onCustomScaleClicked() { |
| 290 | String answer = (String) JOptionPane.showInputDialog(this.gui.getFrame(), I18n.translate("menu.view.scale.custom.title"), I18n.translate("menu.view.scale.custom.title"), | 308 | String answer = (String) JOptionPane.showInputDialog(this.gui.getFrame(), I18n.translate("menu.view.scale.custom.title"), I18n.translate("menu.view.scale.custom.title"), JOptionPane.QUESTION_MESSAGE, null, null, Float.toString(UiConfig.getScaleFactor() * 100)); |
| 291 | JOptionPane.QUESTION_MESSAGE, null, null, Float.toString(UiConfig.getScaleFactor() * 100)); | 309 | |
| 292 | if (answer == null) return; | 310 | if (answer == null) { |
| 311 | return; | ||
| 312 | } | ||
| 313 | |||
| 293 | float newScale = 1.0f; | 314 | float newScale = 1.0f; |
| 315 | |||
| 294 | try { | 316 | try { |
| 295 | newScale = Float.parseFloat(answer) / 100f; | 317 | newScale = Float.parseFloat(answer) / 100f; |
| 296 | } catch (NumberFormatException ignored) { | 318 | } catch (NumberFormatException ignored) { |
| 319 | // ignored | ||
| 297 | } | 320 | } |
| 321 | |||
| 298 | ScaleUtil.setScaleFactor(newScale); | 322 | ScaleUtil.setScaleFactor(newScale); |
| 299 | ChangeDialog.show(this.gui.getFrame()); | 323 | ChangeDialog.show(this.gui.getFrame()); |
| 300 | } | 324 | } |
| 301 | 325 | ||
| 302 | private void onFontClicked(Gui gui) { | 326 | private void onFontClicked(Gui gui) { |
| 303 | // FontDialog fd = new FontDialog(gui.getFrame(), "Choose Font", true); | 327 | // FontDialog fd = new FontDialog(gui.getFrame(), "Choose Font", true); |
| 304 | // fd.setLocationRelativeTo(gui.getFrame()); | 328 | // fd.setLocationRelativeTo(gui.getFrame()); |
| 305 | // fd.setSelectedFont(UiConfig.getEditorFont()); | 329 | // fd.setSelectedFont(UiConfig.getEditorFont()); |
| 306 | // fd.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); | 330 | // fd.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); |
| 307 | // fd.setVisible(true); | 331 | // fd.setVisible(true); |
| 308 | // | 332 | // |
| 309 | // if (!fd.isCancelSelected()) { | 333 | // if (!fd.isCancelSelected()) { |
| 310 | // UiConfig.setEditorFont(fd.getSelectedFont()); | 334 | // UiConfig.setEditorFont(fd.getSelectedFont()); |
| 311 | // UiConfig.save(); | 335 | // UiConfig.save(); |
| 312 | // } | 336 | // } |
| 313 | FontDialog.display(gui.getFrame()); | 337 | FontDialog.display(gui.getFrame()); |
| 314 | } | 338 | } |
| 315 | 339 | ||
| @@ -324,11 +348,15 @@ public class MenuBar { | |||
| 324 | this.gui.getController().disconnectIfConnected(null); | 348 | this.gui.getController().disconnectIfConnected(null); |
| 325 | return; | 349 | return; |
| 326 | } | 350 | } |
| 351 | |||
| 327 | ConnectToServerDialog.Result result = ConnectToServerDialog.show(this.gui.getFrame()); | 352 | ConnectToServerDialog.Result result = ConnectToServerDialog.show(this.gui.getFrame()); |
| 353 | |||
| 328 | if (result == null) { | 354 | if (result == null) { |
| 329 | return; | 355 | return; |
| 330 | } | 356 | } |
| 357 | |||
| 331 | this.gui.getController().disconnectIfConnected(null); | 358 | this.gui.getController().disconnectIfConnected(null); |
| 359 | |||
| 332 | try { | 360 | try { |
| 333 | this.gui.getController().createClient(result.getUsername(), result.getAddress().address, result.getAddress().port, result.getPassword()); | 361 | this.gui.getController().createClient(result.getUsername(), result.getAddress().address, result.getAddress().port, result.getPassword()); |
| 334 | NetConfig.setUsername(result.getUsername()); | 362 | NetConfig.setUsername(result.getUsername()); |
| @@ -339,6 +367,7 @@ public class MenuBar { | |||
| 339 | JOptionPane.showMessageDialog(this.gui.getFrame(), e.toString(), I18n.translate("menu.collab.connect.error"), JOptionPane.ERROR_MESSAGE); | 367 | JOptionPane.showMessageDialog(this.gui.getFrame(), e.toString(), I18n.translate("menu.collab.connect.error"), JOptionPane.ERROR_MESSAGE); |
| 340 | this.gui.getController().disconnectIfConnected(null); | 368 | this.gui.getController().disconnectIfConnected(null); |
| 341 | } | 369 | } |
| 370 | |||
| 342 | Arrays.fill(result.getPassword(), (char) 0); | 371 | Arrays.fill(result.getPassword(), (char) 0); |
| 343 | } | 372 | } |
| 344 | 373 | ||
| @@ -347,11 +376,15 @@ public class MenuBar { | |||
| 347 | this.gui.getController().disconnectIfConnected(null); | 376 | this.gui.getController().disconnectIfConnected(null); |
| 348 | return; | 377 | return; |
| 349 | } | 378 | } |
| 379 | |||
| 350 | CreateServerDialog.Result result = CreateServerDialog.show(this.gui.getFrame()); | 380 | CreateServerDialog.Result result = CreateServerDialog.show(this.gui.getFrame()); |
| 381 | |||
| 351 | if (result == null) { | 382 | if (result == null) { |
| 352 | return; | 383 | return; |
| 353 | } | 384 | } |
| 385 | |||
| 354 | this.gui.getController().disconnectIfConnected(null); | 386 | this.gui.getController().disconnectIfConnected(null); |
| 387 | |||
| 355 | try { | 388 | try { |
| 356 | this.gui.getController().createServer(result.getPort(), result.getPassword()); | 389 | this.gui.getController().createServer(result.getPort(), result.getPassword()); |
| 357 | NetConfig.setServerPort(result.getPort()); | 390 | NetConfig.setServerPort(result.getPort()); |
| @@ -373,6 +406,7 @@ public class MenuBar { | |||
| 373 | JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT))); | 406 | JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT))); |
| 374 | item.addActionListener(event -> { | 407 | item.addActionListener(event -> { |
| 375 | gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir())); | 408 | gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir())); |
| 409 | |||
| 376 | if (gui.enigmaMappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { | 410 | if (gui.enigmaMappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { |
| 377 | File selectedFile = gui.enigmaMappingsFileChooser.getSelectedFile(); | 411 | File selectedFile = gui.enigmaMappingsFileChooser.getSelectedFile(); |
| 378 | gui.getController().openMappings(format, selectedFile.toPath()); | 412 | gui.getController().openMappings(format, selectedFile.toPath()); |
| @@ -411,9 +445,11 @@ public class MenuBar { | |||
| 411 | for (Decompiler decompiler : Decompiler.values()) { | 445 | for (Decompiler decompiler : Decompiler.values()) { |
| 412 | JRadioButtonMenuItem decompilerButton = new JRadioButtonMenuItem(decompiler.name); | 446 | JRadioButtonMenuItem decompilerButton = new JRadioButtonMenuItem(decompiler.name); |
| 413 | decompilerGroup.add(decompilerButton); | 447 | decompilerGroup.add(decompilerButton); |
| 448 | |||
| 414 | if (decompiler.equals(UiConfig.getDecompiler())) { | 449 | if (decompiler.equals(UiConfig.getDecompiler())) { |
| 415 | decompilerButton.setSelected(true); | 450 | decompilerButton.setSelected(true); |
| 416 | } | 451 | } |
| 452 | |||
| 417 | decompilerButton.addActionListener(event -> { | 453 | decompilerButton.addActionListener(event -> { |
| 418 | gui.getController().setDecompiler(decompiler.service); | 454 | gui.getController().setDecompiler(decompiler.service); |
| 419 | 455 | ||
| @@ -426,12 +462,15 @@ public class MenuBar { | |||
| 426 | 462 | ||
| 427 | private static void prepareThemesMenu(JMenu themesMenu, Gui gui) { | 463 | private static void prepareThemesMenu(JMenu themesMenu, Gui gui) { |
| 428 | ButtonGroup themeGroup = new ButtonGroup(); | 464 | ButtonGroup themeGroup = new ButtonGroup(); |
| 465 | |||
| 429 | for (LookAndFeel lookAndFeel : LookAndFeel.values()) { | 466 | for (LookAndFeel lookAndFeel : LookAndFeel.values()) { |
| 430 | JRadioButtonMenuItem themeButton = new JRadioButtonMenuItem(I18n.translate("menu.view.themes." + lookAndFeel.name().toLowerCase(Locale.ROOT))); | 467 | JRadioButtonMenuItem themeButton = new JRadioButtonMenuItem(I18n.translate("menu.view.themes." + lookAndFeel.name().toLowerCase(Locale.ROOT))); |
| 431 | themeGroup.add(themeButton); | 468 | themeGroup.add(themeButton); |
| 469 | |||
| 432 | if (lookAndFeel.equals(UiConfig.getLookAndFeel())) { | 470 | if (lookAndFeel.equals(UiConfig.getLookAndFeel())) { |
| 433 | themeButton.setSelected(true); | 471 | themeButton.setSelected(true); |
| 434 | } | 472 | } |
| 473 | |||
| 435 | themeButton.addActionListener(_e -> { | 474 | themeButton.addActionListener(_e -> { |
| 436 | UiConfig.setLookAndFeel(lookAndFeel); | 475 | UiConfig.setLookAndFeel(lookAndFeel); |
| 437 | UiConfig.save(); | 476 | UiConfig.save(); |
| @@ -443,12 +482,15 @@ public class MenuBar { | |||
| 443 | 482 | ||
| 444 | private static void prepareLanguagesMenu(JMenu languagesMenu) { | 483 | private static void prepareLanguagesMenu(JMenu languagesMenu) { |
| 445 | ButtonGroup languageGroup = new ButtonGroup(); | 484 | ButtonGroup languageGroup = new ButtonGroup(); |
| 485 | |||
| 446 | for (String lang : I18n.getAvailableLanguages()) { | 486 | for (String lang : I18n.getAvailableLanguages()) { |
| 447 | JRadioButtonMenuItem languageButton = new JRadioButtonMenuItem(I18n.getLanguageName(lang)); | 487 | JRadioButtonMenuItem languageButton = new JRadioButtonMenuItem(I18n.getLanguageName(lang)); |
| 448 | languageGroup.add(languageButton); | 488 | languageGroup.add(languageButton); |
| 489 | |||
| 449 | if (lang.equals(UiConfig.getLanguage())) { | 490 | if (lang.equals(UiConfig.getLanguage())) { |
| 450 | languageButton.setSelected(true); | 491 | languageButton.setSelected(true); |
| 451 | } | 492 | } |
| 493 | |||
| 452 | languageButton.addActionListener(event -> { | 494 | languageButton.addActionListener(event -> { |
| 453 | UiConfig.setLanguage(lang); | 495 | UiConfig.setLanguage(lang); |
| 454 | I18n.setLanguage(lang); | 496 | I18n.setLanguage(lang); |
| @@ -461,25 +503,25 @@ public class MenuBar { | |||
| 461 | 503 | ||
| 462 | private static void prepareScaleMenu(JMenu scaleMenu, Gui gui) { | 504 | private static void prepareScaleMenu(JMenu scaleMenu, Gui gui) { |
| 463 | ButtonGroup scaleGroup = new ButtonGroup(); | 505 | ButtonGroup scaleGroup = new ButtonGroup(); |
| 464 | Map<Float, JRadioButtonMenuItem> scaleButtons = IntStream.of(100, 125, 150, 175, 200) | 506 | Map<Float, JRadioButtonMenuItem> scaleButtons = IntStream.of(100, 125, 150, 175, 200).mapToObj(scaleFactor -> { |
| 465 | .mapToObj(scaleFactor -> { | 507 | float realScaleFactor = scaleFactor / 100f; |
| 466 | float realScaleFactor = scaleFactor / 100f; | 508 | JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(String.format("%d%%", scaleFactor)); |
| 467 | JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(String.format("%d%%", scaleFactor)); | 509 | menuItem.addActionListener(event -> ScaleUtil.setScaleFactor(realScaleFactor)); |
| 468 | menuItem.addActionListener(event -> ScaleUtil.setScaleFactor(realScaleFactor)); | 510 | menuItem.addActionListener(event -> ChangeDialog.show(gui.getFrame())); |
| 469 | menuItem.addActionListener(event -> ChangeDialog.show(gui.getFrame())); | 511 | scaleGroup.add(menuItem); |
| 470 | scaleGroup.add(menuItem); | 512 | scaleMenu.add(menuItem); |
| 471 | scaleMenu.add(menuItem); | 513 | return new Pair<>(realScaleFactor, menuItem); |
| 472 | return new Pair<>(realScaleFactor, menuItem); | 514 | }).collect(Collectors.toMap(x -> x.a, x -> x.b)); |
| 473 | }) | ||
| 474 | .collect(Collectors.toMap(x -> x.a, x -> x.b)); | ||
| 475 | 515 | ||
| 476 | JRadioButtonMenuItem currentScaleButton = scaleButtons.get(UiConfig.getScaleFactor()); | 516 | JRadioButtonMenuItem currentScaleButton = scaleButtons.get(UiConfig.getScaleFactor()); |
| 517 | |||
| 477 | if (currentScaleButton != null) { | 518 | if (currentScaleButton != null) { |
| 478 | currentScaleButton.setSelected(true); | 519 | currentScaleButton.setSelected(true); |
| 479 | } | 520 | } |
| 480 | 521 | ||
| 481 | ScaleUtil.addListener((newScale, _oldScale) -> { | 522 | ScaleUtil.addListener((newScale, _oldScale) -> { |
| 482 | JRadioButtonMenuItem mi = scaleButtons.get(newScale); | 523 | JRadioButtonMenuItem mi = scaleButtons.get(newScale); |
| 524 | |||
| 483 | if (mi != null) { | 525 | if (mi != null) { |
| 484 | mi.setSelected(true); | 526 | mi.setSelected(true); |
| 485 | } else { | 527 | } else { |
| @@ -487,5 +529,4 @@ public class MenuBar { | |||
| 487 | } | 529 | } |
| 488 | }); | 530 | }); |
| 489 | } | 531 | } |
| 490 | |||
| 491 | } | 532 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/StatusBar.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/StatusBar.java index 0c667c0..48404a1 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/StatusBar.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/StatusBar.java | |||
| @@ -54,7 +54,7 @@ public class StatusBar { | |||
| 54 | * | 54 | * |
| 55 | * @param message the message to display | 55 | * @param message the message to display |
| 56 | * @param timeout the timeout in milliseconds to wait until clearing the | 56 | * @param timeout the timeout in milliseconds to wait until clearing the |
| 57 | * message; if 0, the message is not automatically cleared | 57 | * message; if 0, the message is not automatically cleared |
| 58 | */ | 58 | */ |
| 59 | public void showMessage(String message, int timeout) { | 59 | public void showMessage(String message, int timeout) { |
| 60 | this.timer.stop(); | 60 | this.timer.stop(); |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatablePasswordField.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatablePasswordField.java index 02e1bc3..4329cae 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatablePasswordField.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatablePasswordField.java | |||
| @@ -14,7 +14,6 @@ import cuchaz.enigma.utils.validation.ParameterizedMessage; | |||
| 14 | import cuchaz.enigma.utils.validation.Validatable; | 14 | import cuchaz.enigma.utils.validation.Validatable; |
| 15 | 15 | ||
| 16 | public class ValidatablePasswordField extends JPasswordField implements Validatable { | 16 | public class ValidatablePasswordField extends JPasswordField implements Validatable { |
| 17 | |||
| 18 | private List<ParameterizedMessage> messages = new ArrayList<>(); | 17 | private List<ParameterizedMessage> messages = new ArrayList<>(); |
| 19 | private String tooltipText = null; | 18 | private String tooltipText = null; |
| 20 | 19 | ||
| @@ -92,5 +91,4 @@ public class ValidatablePasswordField extends JPasswordField implements Validata | |||
| 92 | super.paint(g); | 91 | super.paint(g); |
| 93 | ValidatableUi.drawMarker(this, g, messages); | 92 | ValidatableUi.drawMarker(this, g, messages); |
| 94 | } | 93 | } |
| 95 | |||
| 96 | } | 94 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableTextArea.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableTextArea.java index 7d1f866..2d5e229 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableTextArea.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableTextArea.java | |||
| @@ -14,7 +14,6 @@ import cuchaz.enigma.utils.validation.ParameterizedMessage; | |||
| 14 | import cuchaz.enigma.utils.validation.Validatable; | 14 | import cuchaz.enigma.utils.validation.Validatable; |
| 15 | 15 | ||
| 16 | public class ValidatableTextArea extends JTextArea implements Validatable { | 16 | public class ValidatableTextArea extends JTextArea implements Validatable { |
| 17 | |||
| 18 | private List<ParameterizedMessage> messages = new ArrayList<>(); | 17 | private List<ParameterizedMessage> messages = new ArrayList<>(); |
| 19 | private String tooltipText = null; | 18 | private String tooltipText = null; |
| 20 | 19 | ||
| @@ -96,5 +95,4 @@ public class ValidatableTextArea extends JTextArea implements Validatable { | |||
| 96 | super.paint(g); | 95 | super.paint(g); |
| 97 | ValidatableUi.drawMarker(this, g, messages); | 96 | ValidatableUi.drawMarker(this, g, messages); |
| 98 | } | 97 | } |
| 99 | |||
| 100 | } | 98 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableTextField.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableTextField.java index c114dc1..be658d5 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableTextField.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableTextField.java | |||
| @@ -14,7 +14,6 @@ import cuchaz.enigma.utils.validation.ParameterizedMessage; | |||
| 14 | import cuchaz.enigma.utils.validation.Validatable; | 14 | import cuchaz.enigma.utils.validation.Validatable; |
| 15 | 15 | ||
| 16 | public class ValidatableTextField extends JTextField implements Validatable { | 16 | public class ValidatableTextField extends JTextField implements Validatable { |
| 17 | |||
| 18 | private List<ParameterizedMessage> messages = new ArrayList<>(); | 17 | private List<ParameterizedMessage> messages = new ArrayList<>(); |
| 19 | private String tooltipText = null; | 18 | private String tooltipText = null; |
| 20 | 19 | ||
| @@ -92,5 +91,4 @@ public class ValidatableTextField extends JTextField implements Validatable { | |||
| 92 | super.paint(g); | 91 | super.paint(g); |
| 93 | ValidatableUi.drawMarker(this, g, messages); | 92 | ValidatableUi.drawMarker(this, g, messages); |
| 94 | } | 93 | } |
| 95 | |||
| 96 | } | 94 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableUi.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableUi.java index 5df6348..b8b8431 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableUi.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/ValidatableUi.java | |||
| @@ -13,26 +13,29 @@ import cuchaz.enigma.gui.util.ScaleUtil; | |||
| 13 | import cuchaz.enigma.utils.validation.ParameterizedMessage; | 13 | import cuchaz.enigma.utils.validation.ParameterizedMessage; |
| 14 | 14 | ||
| 15 | public final class ValidatableUi { | 15 | public final class ValidatableUi { |
| 16 | |||
| 17 | private ValidatableUi() { | 16 | private ValidatableUi() { |
| 18 | } | 17 | } |
| 19 | 18 | ||
| 20 | public static String getTooltipText(String tooltipText, List<ParameterizedMessage> messages) { | 19 | public static String getTooltipText(String tooltipText, List<ParameterizedMessage> messages) { |
| 21 | List<String> strings = new ArrayList<>(); | 20 | List<String> strings = new ArrayList<>(); |
| 21 | |||
| 22 | if (tooltipText != null) { | 22 | if (tooltipText != null) { |
| 23 | strings.add(tooltipText); | 23 | strings.add(tooltipText); |
| 24 | } | 24 | } |
| 25 | |||
| 25 | if (!messages.isEmpty()) { | 26 | if (!messages.isEmpty()) { |
| 26 | strings.add("Error(s): "); | 27 | strings.add("Error(s): "); |
| 27 | 28 | ||
| 28 | messages.forEach(msg -> { | 29 | messages.forEach(msg -> { |
| 29 | strings.add(String.format(" - %s", msg.getText())); | 30 | strings.add(String.format(" - %s", msg.getText())); |
| 30 | String longDesc = msg.getLongText(); | 31 | String longDesc = msg.getLongText(); |
| 32 | |||
| 31 | if (!longDesc.isEmpty()) { | 33 | if (!longDesc.isEmpty()) { |
| 32 | Arrays.stream(longDesc.split("\n")).map(s -> String.format(" %s", s)).forEach(strings::add); | 34 | Arrays.stream(longDesc.split("\n")).map(s -> String.format(" %s", s)).forEach(strings::add); |
| 33 | } | 35 | } |
| 34 | }); | 36 | }); |
| 35 | } | 37 | } |
| 38 | |||
| 36 | if (strings.isEmpty()) { | 39 | if (strings.isEmpty()) { |
| 37 | return null; | 40 | return null; |
| 38 | } else { | 41 | } else { |
| @@ -49,11 +52,13 @@ public final class ValidatableUi { | |||
| 49 | messages.forEach(msg -> { | 52 | messages.forEach(msg -> { |
| 50 | strings.add(String.format(" - %s", msg.getText())); | 53 | strings.add(String.format(" - %s", msg.getText())); |
| 51 | String longDesc = msg.getLongText(); | 54 | String longDesc = msg.getLongText(); |
| 55 | |||
| 52 | if (!longDesc.isEmpty()) { | 56 | if (!longDesc.isEmpty()) { |
| 53 | Arrays.stream(longDesc.split("\n")).map(s -> String.format(" %s", s)).forEach(strings::add); | 57 | Arrays.stream(longDesc.split("\n")).map(s -> String.format(" %s", s)).forEach(strings::add); |
| 54 | } | 58 | } |
| 55 | }); | 59 | }); |
| 56 | } | 60 | } |
| 61 | |||
| 57 | if (strings.isEmpty()) { | 62 | if (strings.isEmpty()) { |
| 58 | return null; | 63 | return null; |
| 59 | } else { | 64 | } else { |
| @@ -63,6 +68,7 @@ public final class ValidatableUi { | |||
| 63 | 68 | ||
| 64 | public static void drawMarker(Component self, Graphics g, List<ParameterizedMessage> messages) { | 69 | public static void drawMarker(Component self, Graphics g, List<ParameterizedMessage> messages) { |
| 65 | Color color = ValidatableUi.getMarkerColor(messages); | 70 | Color color = ValidatableUi.getMarkerColor(messages); |
| 71 | |||
| 66 | if (color != null) { | 72 | if (color != null) { |
| 67 | g.setColor(color); | 73 | g.setColor(color); |
| 68 | int x1 = self.getWidth() - ScaleUtil.scale(8) - 1; | 74 | int x1 = self.getWidth() - ScaleUtil.scale(8) - 1; |
| @@ -75,33 +81,32 @@ public final class ValidatableUi { | |||
| 75 | 81 | ||
| 76 | @Nullable | 82 | @Nullable |
| 77 | public static Color getMarkerColor(List<ParameterizedMessage> messages) { | 83 | public static Color getMarkerColor(List<ParameterizedMessage> messages) { |
| 78 | int level = messages.stream() | 84 | int level = messages.stream().mapToInt(ValidatableUi::getMessageLevel).max().orElse(0); |
| 79 | .mapToInt(ValidatableUi::getMessageLevel) | ||
| 80 | .max().orElse(0); | ||
| 81 | 85 | ||
| 82 | switch (level) { | 86 | switch (level) { |
| 83 | case 0: | 87 | case 0: |
| 84 | return null; | 88 | return null; |
| 85 | case 1: | 89 | case 1: |
| 86 | return Color.BLUE; | 90 | return Color.BLUE; |
| 87 | case 2: | 91 | case 2: |
| 88 | return Color.ORANGE; | 92 | return Color.ORANGE; |
| 89 | case 3: | 93 | case 3: |
| 90 | return Color.RED; | 94 | return Color.RED; |
| 91 | } | 95 | } |
| 96 | |||
| 92 | throw new IllegalStateException("unreachable"); | 97 | throw new IllegalStateException("unreachable"); |
| 93 | } | 98 | } |
| 94 | 99 | ||
| 95 | private static int getMessageLevel(ParameterizedMessage message) { | 100 | private static int getMessageLevel(ParameterizedMessage message) { |
| 96 | switch (message.message.type) { | 101 | switch (message.message.type) { |
| 97 | case INFO: | 102 | case INFO: |
| 98 | return 1; | 103 | return 1; |
| 99 | case WARNING: | 104 | case WARNING: |
| 100 | return 2; | 105 | return 2; |
| 101 | case ERROR: | 106 | case ERROR: |
| 102 | return 3; | 107 | return 3; |
| 103 | } | 108 | } |
| 109 | |||
| 104 | throw new IllegalStateException("unreachable"); | 110 | throw new IllegalStateException("unreachable"); |
| 105 | } | 111 | } |
| 106 | |||
| 107 | } | 112 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ConvertingTextFieldListener.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ConvertingTextFieldListener.java index 6e17fec..d9ec95c 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ConvertingTextFieldListener.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ConvertingTextFieldListener.java | |||
| @@ -3,7 +3,6 @@ package cuchaz.enigma.gui.events; | |||
| 3 | import cuchaz.enigma.gui.elements.ConvertingTextField; | 3 | import cuchaz.enigma.gui.elements.ConvertingTextField; |
| 4 | 4 | ||
| 5 | public interface ConvertingTextFieldListener { | 5 | public interface ConvertingTextFieldListener { |
| 6 | |||
| 7 | default void onStartEditing(ConvertingTextField field) { | 6 | default void onStartEditing(ConvertingTextField field) { |
| 8 | } | 7 | } |
| 9 | 8 | ||
| @@ -13,5 +12,4 @@ public interface ConvertingTextFieldListener { | |||
| 13 | 12 | ||
| 14 | default void onStopEditing(ConvertingTextField field, boolean abort) { | 13 | default void onStopEditing(ConvertingTextField field, boolean abort) { |
| 15 | } | 14 | } |
| 16 | |||
| 17 | } | 15 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/events/EditorActionListener.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/events/EditorActionListener.java index 48c9ec4..1651abf 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/events/EditorActionListener.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/events/EditorActionListener.java | |||
| @@ -7,7 +7,6 @@ import cuchaz.enigma.translation.representation.entry.ClassEntry; | |||
| 7 | import cuchaz.enigma.translation.representation.entry.Entry; | 7 | import cuchaz.enigma.translation.representation.entry.Entry; |
| 8 | 8 | ||
| 9 | public interface EditorActionListener { | 9 | public interface EditorActionListener { |
| 10 | |||
| 11 | default void onCursorReferenceChanged(EditorPanel editor, EntryReference<Entry<?>, Entry<?>> ref) { | 10 | default void onCursorReferenceChanged(EditorPanel editor, EntryReference<Entry<?>, Entry<?>> ref) { |
| 12 | } | 11 | } |
| 13 | 12 | ||
| @@ -16,5 +15,4 @@ public interface EditorActionListener { | |||
| 16 | 15 | ||
| 17 | default void onTitleChanged(EditorPanel editor, String title) { | 16 | default void onTitleChanged(EditorPanel editor, String title) { |
| 18 | } | 17 | } |
| 19 | |||
| 20 | } | 18 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ThemeChangeListener.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ThemeChangeListener.java index 10d7ce1..e2054b2 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ThemeChangeListener.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/events/ThemeChangeListener.java | |||
| @@ -7,7 +7,5 @@ import cuchaz.enigma.gui.highlight.BoxHighlightPainter; | |||
| 7 | import cuchaz.enigma.source.RenamableTokenType; | 7 | import cuchaz.enigma.source.RenamableTokenType; |
| 8 | 8 | ||
| 9 | public interface ThemeChangeListener { | 9 | public interface ThemeChangeListener { |
| 10 | |||
| 11 | void onThemeChanged(LookAndFeel lookAndFeel, Map<RenamableTokenType, BoxHighlightPainter> boxHighlightPainters); | 10 | void onThemeChanged(LookAndFeel lookAndFeel, Map<RenamableTokenType, BoxHighlightPainter> boxHighlightPainters); |
| 12 | |||
| 13 | } | 11 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/highlight/BoxHighlightPainter.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/highlight/BoxHighlightPainter.java index 2d8d76a..a97b377 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/highlight/BoxHighlightPainter.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/highlight/BoxHighlightPainter.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.highlight; | 12 | package cuchaz.enigma.gui.highlight; |
| 13 | 13 | ||
| @@ -67,5 +67,4 @@ public class BoxHighlightPainter implements Highlighter.HighlightPainter { | |||
| 67 | g.setColor(this.borderColor); | 67 | g.setColor(this.borderColor); |
| 68 | g.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); | 68 | g.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); |
| 69 | } | 69 | } |
| 70 | |||
| 71 | } | 70 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/highlight/SelectionHighlightPainter.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/highlight/SelectionHighlightPainter.java index 22d6420..a807802 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/highlight/SelectionHighlightPainter.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/highlight/SelectionHighlightPainter.java | |||
| @@ -1,17 +1,21 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.highlight; | 12 | package cuchaz.enigma.gui.highlight; |
| 13 | 13 | ||
| 14 | import java.awt.*; | 14 | import java.awt.BasicStroke; |
| 15 | import java.awt.Graphics; | ||
| 16 | import java.awt.Graphics2D; | ||
| 17 | import java.awt.Rectangle; | ||
| 18 | import java.awt.Shape; | ||
| 15 | 19 | ||
| 16 | import javax.swing.text.Highlighter; | 20 | import javax.swing.text.Highlighter; |
| 17 | import javax.swing.text.JTextComponent; | 21 | import javax.swing.text.JTextComponent; |
| @@ -19,7 +23,6 @@ import javax.swing.text.JTextComponent; | |||
| 19 | import cuchaz.enigma.gui.config.UiConfig; | 23 | import cuchaz.enigma.gui.config.UiConfig; |
| 20 | 24 | ||
| 21 | public class SelectionHighlightPainter implements Highlighter.HighlightPainter { | 25 | public class SelectionHighlightPainter implements Highlighter.HighlightPainter { |
| 22 | |||
| 23 | public static final SelectionHighlightPainter INSTANCE = new SelectionHighlightPainter(); | 26 | public static final SelectionHighlightPainter INSTANCE = new SelectionHighlightPainter(); |
| 24 | 27 | ||
| 25 | @Override | 28 | @Override |
| @@ -31,5 +34,4 @@ public class SelectionHighlightPainter implements Highlighter.HighlightPainter { | |||
| 31 | g2d.setStroke(new BasicStroke(2.0f)); | 34 | g2d.setStroke(new BasicStroke(2.0f)); |
| 32 | g2d.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); | 35 | g2d.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, 4, 4); |
| 33 | } | 36 | } |
| 34 | |||
| 35 | } | 37 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/newabstraction/EntryValidation.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/newabstraction/EntryValidation.java index 898529a..1dcdeab 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/newabstraction/EntryValidation.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/newabstraction/EntryValidation.java | |||
| @@ -6,17 +6,16 @@ import cuchaz.enigma.utils.validation.Message; | |||
| 6 | import cuchaz.enigma.utils.validation.ValidationContext; | 6 | import cuchaz.enigma.utils.validation.ValidationContext; |
| 7 | 7 | ||
| 8 | public class EntryValidation { | 8 | public class EntryValidation { |
| 9 | |||
| 10 | public static boolean validateJavadoc(ValidationContext vc, String javadoc) { | 9 | public static boolean validateJavadoc(ValidationContext vc, String javadoc) { |
| 11 | if (javadoc.contains("*/")) { | 10 | if (javadoc.contains("*/")) { |
| 12 | vc.raise(Message.ILLEGAL_DOC_COMMENT_END); | 11 | vc.raise(Message.ILLEGAL_DOC_COMMENT_END); |
| 13 | return false; | 12 | return false; |
| 14 | } | 13 | } |
| 14 | |||
| 15 | return true; | 15 | return true; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | public static boolean validateRename(ValidationContext vc, EnigmaProject p, Entry<?> entry, String newName) { | 18 | public static boolean validateRename(ValidationContext vc, EnigmaProject p, Entry<?> entry, String newName) { |
| 19 | return p.getMapper().getValidator().validateRename(vc, entry, newName); | 19 | return p.getMapper().getValidator().validateRename(vc, entry, newName); |
| 20 | } | 20 | } |
| 21 | |||
| 22 | } | 21 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java index 922f8f2..f931a93 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/node/ClassSelectorClassNode.java | |||
| @@ -1,22 +1,21 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.node; | 12 | package cuchaz.enigma.gui.node; |
| 13 | 13 | ||
| 14 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 15 | |||
| 16 | import javax.swing.tree.DefaultMutableTreeNode; | 14 | import javax.swing.tree.DefaultMutableTreeNode; |
| 17 | 15 | ||
| 18 | public class ClassSelectorClassNode extends DefaultMutableTreeNode { | 16 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 19 | 17 | ||
| 18 | public class ClassSelectorClassNode extends DefaultMutableTreeNode { | ||
| 20 | private final ClassEntry obfEntry; | 19 | private final ClassEntry obfEntry; |
| 21 | private ClassEntry classEntry; | 20 | private ClassEntry classEntry; |
| 22 | 21 | ||
| @@ -57,12 +56,17 @@ public class ClassSelectorClassNode extends DefaultMutableTreeNode { | |||
| 57 | @Override | 56 | @Override |
| 58 | public void setUserObject(Object userObject) { | 57 | public void setUserObject(Object userObject) { |
| 59 | String packageName = ""; | 58 | String packageName = ""; |
| 60 | if (classEntry.getPackageName() != null) | 59 | |
| 60 | if (classEntry.getPackageName() != null) { | ||
| 61 | packageName = classEntry.getPackageName() + "/"; | 61 | packageName = classEntry.getPackageName() + "/"; |
| 62 | if (userObject instanceof String) | 62 | } |
| 63 | |||
| 64 | if (userObject instanceof String) { | ||
| 63 | this.classEntry = new ClassEntry(packageName + userObject); | 65 | this.classEntry = new ClassEntry(packageName + userObject); |
| 64 | else if (userObject instanceof ClassEntry) | 66 | } else if (userObject instanceof ClassEntry) { |
| 65 | this.classEntry = (ClassEntry) userObject; | 67 | this.classEntry = (ClassEntry) userObject; |
| 68 | } | ||
| 69 | |||
| 66 | super.setUserObject(classEntry); | 70 | super.setUserObject(classEntry); |
| 67 | } | 71 | } |
| 68 | 72 | ||
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java index c1c7d38..dfcbd8c 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/node/ClassSelectorPackageNode.java | |||
| @@ -1,22 +1,21 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.node; | 12 | package cuchaz.enigma.gui.node; |
| 13 | 13 | ||
| 14 | import cuchaz.enigma.translation.representation.entry.ClassEntry; | ||
| 15 | |||
| 16 | import javax.swing.tree.DefaultMutableTreeNode; | 14 | import javax.swing.tree.DefaultMutableTreeNode; |
| 17 | 15 | ||
| 18 | public class ClassSelectorPackageNode extends DefaultMutableTreeNode { | 16 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 19 | 17 | ||
| 18 | public class ClassSelectorPackageNode extends DefaultMutableTreeNode { | ||
| 20 | private String packageName; | 19 | private String packageName; |
| 21 | 20 | ||
| 22 | public ClassSelectorPackageNode(String packageName) { | 21 | public ClassSelectorPackageNode(String packageName) { |
| @@ -34,8 +33,10 @@ public class ClassSelectorPackageNode extends DefaultMutableTreeNode { | |||
| 34 | 33 | ||
| 35 | @Override | 34 | @Override |
| 36 | public void setUserObject(Object userObject) { | 35 | public void setUserObject(Object userObject) { |
| 37 | if (userObject instanceof String) | 36 | if (userObject instanceof String) { |
| 38 | this.packageName = (String) userObject; | 37 | this.packageName = (String) userObject; |
| 38 | } | ||
| 39 | |||
| 39 | super.setUserObject(userObject); | 40 | super.setUserObject(userObject); |
| 40 | } | 41 | } |
| 41 | 42 | ||
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/ClosableTabTitlePane.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/ClosableTabTitlePane.java index fe5c857..dca714d 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/ClosableTabTitlePane.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/ClosableTabTitlePane.java | |||
| @@ -9,12 +9,17 @@ import java.awt.event.MouseEvent; | |||
| 9 | 9 | ||
| 10 | import javax.accessibility.AccessibleContext; | 10 | import javax.accessibility.AccessibleContext; |
| 11 | import javax.annotation.Nullable; | 11 | import javax.annotation.Nullable; |
| 12 | import javax.swing.*; | 12 | import javax.swing.JButton; |
| 13 | import javax.swing.JComponent; | ||
| 14 | import javax.swing.JLabel; | ||
| 15 | import javax.swing.JPanel; | ||
| 16 | import javax.swing.JTabbedPane; | ||
| 17 | import javax.swing.SwingUtilities; | ||
| 18 | import javax.swing.UIManager; | ||
| 13 | import javax.swing.border.EmptyBorder; | 19 | import javax.swing.border.EmptyBorder; |
| 14 | import javax.swing.event.ChangeListener; | 20 | import javax.swing.event.ChangeListener; |
| 15 | 21 | ||
| 16 | public class ClosableTabTitlePane { | 22 | public class ClosableTabTitlePane { |
| 17 | |||
| 18 | private final JPanel ui; | 23 | private final JPanel ui; |
| 19 | private final JButton closeButton; | 24 | private final JButton closeButton; |
| 20 | private final JLabel label; | 25 | private final JLabel label; |
| @@ -66,19 +71,7 @@ public class ClosableTabTitlePane { | |||
| 66 | if (parent != null) { | 71 | if (parent != null) { |
| 67 | Point pt = new Point(e.getXOnScreen(), e.getYOnScreen()); | 72 | Point pt = new Point(e.getXOnScreen(), e.getYOnScreen()); |
| 68 | SwingUtilities.convertPointFromScreen(pt, parent); | 73 | SwingUtilities.convertPointFromScreen(pt, parent); |
| 69 | MouseEvent e1 = new MouseEvent( | 74 | MouseEvent e1 = new MouseEvent(parent, e.getID(), e.getWhen(), e.getModifiersEx(), (int) pt.getX(), (int) pt.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e.getButton()); |
| 70 | parent, | ||
| 71 | e.getID(), | ||
| 72 | e.getWhen(), | ||
| 73 | e.getModifiersEx(), | ||
| 74 | (int) pt.getX(), | ||
| 75 | (int) pt.getY(), | ||
| 76 | e.getXOnScreen(), | ||
| 77 | e.getYOnScreen(), | ||
| 78 | e.getClickCount(), | ||
| 79 | e.isPopupTrigger(), | ||
| 80 | e.getButton() | ||
| 81 | ); | ||
| 82 | parent.dispatchEvent(e1); | 75 | parent.dispatchEvent(e1); |
| 83 | } | 76 | } |
| 84 | } | 77 | } |
| @@ -91,11 +84,13 @@ public class ClosableTabTitlePane { | |||
| 91 | if (this.parent != null) { | 84 | if (this.parent != null) { |
| 92 | pane.removeChangeListener(cachedChangeListener); | 85 | pane.removeChangeListener(cachedChangeListener); |
| 93 | } | 86 | } |
| 87 | |||
| 94 | if (pane != null) { | 88 | if (pane != null) { |
| 95 | updateState(pane); | 89 | updateState(pane); |
| 96 | cachedChangeListener = e -> updateState(pane); | 90 | cachedChangeListener = e -> updateState(pane); |
| 97 | pane.addChangeListener(cachedChangeListener); | 91 | pane.addChangeListener(cachedChangeListener); |
| 98 | } | 92 | } |
| 93 | |||
| 99 | this.parent = pane; | 94 | this.parent = pane; |
| 100 | } | 95 | } |
| 101 | 96 | ||
| @@ -123,11 +118,12 @@ public class ClosableTabTitlePane { | |||
| 123 | public static ClosableTabTitlePane byUi(Component c) { | 118 | public static ClosableTabTitlePane byUi(Component c) { |
| 124 | if (c instanceof JComponent) { | 119 | if (c instanceof JComponent) { |
| 125 | Object prop = ((JComponent) c).getClientProperty(ClosableTabTitlePane.class); | 120 | Object prop = ((JComponent) c).getClientProperty(ClosableTabTitlePane.class); |
| 121 | |||
| 126 | if (prop instanceof ClosableTabTitlePane) { | 122 | if (prop instanceof ClosableTabTitlePane) { |
| 127 | return (ClosableTabTitlePane) prop; | 123 | return (ClosableTabTitlePane) prop; |
| 128 | } | 124 | } |
| 129 | } | 125 | } |
| 126 | |||
| 130 | return null; | 127 | return null; |
| 131 | } | 128 | } |
| 132 | |||
| 133 | } | 129 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/DeobfPanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/DeobfPanel.java index 10fc5e1..5d1d0f2 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/DeobfPanel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/DeobfPanel.java | |||
| @@ -15,7 +15,6 @@ import cuchaz.enigma.gui.util.GuiUtil; | |||
| 15 | import cuchaz.enigma.utils.I18n; | 15 | import cuchaz.enigma.utils.I18n; |
| 16 | 16 | ||
| 17 | public class DeobfPanel extends JPanel { | 17 | public class DeobfPanel extends JPanel { |
| 18 | |||
| 19 | public final ClassSelector deobfClasses; | 18 | public final ClassSelector deobfClasses; |
| 20 | private final JLabel title = new JLabel(); | 19 | private final JLabel title = new JLabel(); |
| 21 | 20 | ||
| @@ -44,6 +43,7 @@ public class DeobfPanel extends JPanel { | |||
| 44 | if (SwingUtilities.isRightMouseButton(e)) { | 43 | if (SwingUtilities.isRightMouseButton(e)) { |
| 45 | deobfClasses.setSelectionRow(deobfClasses.getClosestRowForLocation(e.getX(), e.getY())); | 44 | deobfClasses.setSelectionRow(deobfClasses.getClosestRowForLocation(e.getX(), e.getY())); |
| 46 | int i = deobfClasses.getRowForPath(deobfClasses.getSelectionPath()); | 45 | int i = deobfClasses.getRowForPath(deobfClasses.getSelectionPath()); |
| 46 | |||
| 47 | if (i != -1) { | 47 | if (i != -1) { |
| 48 | deobfPanelPopupMenu.show(deobfClasses, e.getX(), e.getY()); | 48 | deobfPanelPopupMenu.show(deobfClasses, e.getX(), e.getY()); |
| 49 | } | 49 | } |
| @@ -54,5 +54,4 @@ public class DeobfPanel extends JPanel { | |||
| 54 | this.title.setText(I18n.translate(gui.isSingleClassTree() ? "info_panel.classes" : "info_panel.classes.deobfuscated")); | 54 | this.title.setText(I18n.translate(gui.isSingleClassTree() ? "info_panel.classes" : "info_panel.classes.deobfuscated")); |
| 55 | this.deobfPanelPopupMenu.retranslateUi(); | 55 | this.deobfPanelPopupMenu.retranslateUi(); |
| 56 | } | 56 | } |
| 57 | |||
| 58 | } | 57 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java index f4b190b..cb74cec 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/EditorPanel.java | |||
| @@ -1,14 +1,35 @@ | |||
| 1 | package cuchaz.enigma.gui.panels; | 1 | package cuchaz.enigma.gui.panels; |
| 2 | 2 | ||
| 3 | import java.awt.*; | 3 | import java.awt.Color; |
| 4 | import java.awt.event.*; | 4 | import java.awt.Component; |
| 5 | import java.awt.Font; | ||
| 6 | import java.awt.GridBagConstraints; | ||
| 7 | import java.awt.GridBagLayout; | ||
| 8 | import java.awt.GridLayout; | ||
| 9 | import java.awt.Rectangle; | ||
| 10 | import java.awt.event.ActionEvent; | ||
| 11 | import java.awt.event.ActionListener; | ||
| 12 | import java.awt.event.KeyAdapter; | ||
| 13 | import java.awt.event.KeyEvent; | ||
| 14 | import java.awt.event.MouseAdapter; | ||
| 15 | import java.awt.event.MouseEvent; | ||
| 5 | import java.util.ArrayList; | 16 | import java.util.ArrayList; |
| 6 | import java.util.Collection; | 17 | import java.util.Collection; |
| 7 | import java.util.List; | 18 | import java.util.List; |
| 8 | import java.util.Map; | 19 | import java.util.Map; |
| 9 | 20 | ||
| 10 | import javax.annotation.Nullable; | 21 | import javax.annotation.Nullable; |
| 11 | import javax.swing.*; | 22 | import javax.swing.JButton; |
| 23 | import javax.swing.JComponent; | ||
| 24 | import javax.swing.JEditorPane; | ||
| 25 | import javax.swing.JLabel; | ||
| 26 | import javax.swing.JPanel; | ||
| 27 | import javax.swing.JProgressBar; | ||
| 28 | import javax.swing.JScrollPane; | ||
| 29 | import javax.swing.JSeparator; | ||
| 30 | import javax.swing.JTextArea; | ||
| 31 | import javax.swing.SwingUtilities; | ||
| 32 | import javax.swing.Timer; | ||
| 12 | import javax.swing.text.BadLocationException; | 33 | import javax.swing.text.BadLocationException; |
| 13 | import javax.swing.text.Document; | 34 | import javax.swing.text.Document; |
| 14 | import javax.swing.text.Highlighter.HighlightPainter; | 35 | import javax.swing.text.Highlighter.HighlightPainter; |
| @@ -46,7 +67,6 @@ import cuchaz.enigma.utils.I18n; | |||
| 46 | import cuchaz.enigma.utils.Result; | 67 | import cuchaz.enigma.utils.Result; |
| 47 | 68 | ||
| 48 | public class EditorPanel { | 69 | public class EditorPanel { |
| 49 | |||
| 50 | private final JPanel ui = new JPanel(); | 70 | private final JPanel ui = new JPanel(); |
| 51 | private final JEditorPane editor = new JEditorPane(); | 71 | private final JEditorPane editor = new JEditorPane(); |
| 52 | private final JScrollPane editorScrollPane = new JScrollPane(this.editor); | 72 | private final JScrollPane editorScrollPane = new JScrollPane(this.editor); |
| @@ -123,18 +143,19 @@ public class EditorPanel { | |||
| 123 | @Override | 143 | @Override |
| 124 | public void mouseReleased(MouseEvent e) { | 144 | public void mouseReleased(MouseEvent e) { |
| 125 | switch (e.getButton()) { | 145 | switch (e.getButton()) { |
| 126 | case MouseEvent.BUTTON3: // Right click | 146 | case MouseEvent.BUTTON3: // Right click |
| 127 | EditorPanel.this.editor.setCaretPosition(EditorPanel.this.editor.viewToModel(e.getPoint())); | 147 | EditorPanel.this.editor.setCaretPosition(EditorPanel.this.editor.viewToModel(e.getPoint())); |
| 128 | break; | 148 | break; |
| 129 | 149 | ||
| 130 | case 4: // Back navigation | 150 | case 4: // Back navigation |
| 131 | gui.getController().openPreviousReference(); | 151 | gui.getController().openPreviousReference(); |
| 132 | break; | 152 | break; |
| 133 | 153 | ||
| 134 | case 5: // Forward navigation | 154 | case 5: // Forward navigation |
| 135 | gui.getController().openNextReference(); | 155 | gui.getController().openNextReference(); |
| 136 | break; | 156 | break; |
| 137 | } | 157 | } |
| 158 | |||
| 138 | EditorPanel.this.mouseIsPressed = false; | 159 | EditorPanel.this.mouseIsPressed = false; |
| 139 | } | 160 | } |
| 140 | }); | 161 | }); |
| @@ -143,31 +164,36 @@ public class EditorPanel { | |||
| 143 | public void keyPressed(KeyEvent event) { | 164 | public void keyPressed(KeyEvent event) { |
| 144 | if (event.isControlDown()) { | 165 | if (event.isControlDown()) { |
| 145 | EditorPanel.this.shouldNavigateOnClick = false; | 166 | EditorPanel.this.shouldNavigateOnClick = false; |
| 146 | if (EditorPanel.this.popupMenu.handleKeyEvent(event)) return; | 167 | |
| 168 | if (EditorPanel.this.popupMenu.handleKeyEvent(event)) { | ||
| 169 | return; | ||
| 170 | } | ||
| 171 | |||
| 147 | switch (event.getKeyCode()) { | 172 | switch (event.getKeyCode()) { |
| 148 | case KeyEvent.VK_F5: | 173 | case KeyEvent.VK_F5: |
| 149 | if (EditorPanel.this.classHandle != null) { | 174 | if (EditorPanel.this.classHandle != null) { |
| 150 | EditorPanel.this.classHandle.invalidate(); | 175 | EditorPanel.this.classHandle.invalidate(); |
| 151 | } | 176 | } |
| 152 | break; | 177 | |
| 153 | 178 | break; | |
| 154 | case KeyEvent.VK_F: | 179 | |
| 155 | // prevent navigating on click when quick find activated | 180 | case KeyEvent.VK_F: |
| 156 | break; | 181 | // prevent navigating on click when quick find activated |
| 157 | 182 | break; | |
| 158 | case KeyEvent.VK_ADD: | 183 | |
| 159 | case KeyEvent.VK_EQUALS: | 184 | case KeyEvent.VK_ADD: |
| 160 | case KeyEvent.VK_PLUS: | 185 | case KeyEvent.VK_EQUALS: |
| 161 | offsetEditorZoom(2); | 186 | case KeyEvent.VK_PLUS: |
| 162 | break; | 187 | offsetEditorZoom(2); |
| 163 | case KeyEvent.VK_SUBTRACT: | 188 | break; |
| 164 | case KeyEvent.VK_MINUS: | 189 | case KeyEvent.VK_SUBTRACT: |
| 165 | offsetEditorZoom(-2); | 190 | case KeyEvent.VK_MINUS: |
| 166 | break; | 191 | offsetEditorZoom(-2); |
| 167 | 192 | break; | |
| 168 | default: | 193 | |
| 169 | EditorPanel.this.shouldNavigateOnClick = true; // CTRL | 194 | default: |
| 170 | break; | 195 | EditorPanel.this.shouldNavigateOnClick = true; // CTRL |
| 196 | break; | ||
| 171 | } | 197 | } |
| 172 | } | 198 | } |
| 173 | } | 199 | } |
| @@ -175,8 +201,14 @@ public class EditorPanel { | |||
| 175 | @Override | 201 | @Override |
| 176 | public void keyTyped(KeyEvent event) { | 202 | public void keyTyped(KeyEvent event) { |
| 177 | EntryReference<Entry<?>, Entry<?>> ref = EditorPanel.this.getCursorReference(); | 203 | EntryReference<Entry<?>, Entry<?>> ref = EditorPanel.this.getCursorReference(); |
| 178 | if (ref == null) return; | 204 | |
| 179 | if (!EditorPanel.this.controller.project.isRenamable(ref)) return; | 205 | if (ref == null) { |
| 206 | return; | ||
| 207 | } | ||
| 208 | |||
| 209 | if (!EditorPanel.this.controller.project.isRenamable(ref)) { | ||
| 210 | return; | ||
| 211 | } | ||
| 180 | 212 | ||
| 181 | if (!event.isControlDown() && !event.isAltDown() && Character.isJavaIdentifierPart(event.getKeyChar())) { | 213 | if (!event.isControlDown() && !event.isAltDown() && Character.isJavaIdentifierPart(event.getKeyChar())) { |
| 182 | EnigmaProject project = gui.getController().project; | 214 | EnigmaProject project = gui.getController().project; |
| @@ -184,8 +216,10 @@ public class EditorPanel { | |||
| 184 | Entry<?> entry = reference.getNameableEntry(); | 216 | Entry<?> entry = reference.getNameableEntry(); |
| 185 | 217 | ||
| 186 | String name = String.valueOf(event.getKeyChar()); | 218 | String name = String.valueOf(event.getKeyChar()); |
| 219 | |||
| 187 | if (entry instanceof ClassEntry && ((ClassEntry) entry).getParent() == null) { | 220 | if (entry instanceof ClassEntry && ((ClassEntry) entry).getParent() == null) { |
| 188 | String packageName = ((ClassEntry) entry).getPackageName(); | 221 | String packageName = ((ClassEntry) entry).getPackageName(); |
| 222 | |||
| 189 | if (packageName != null) { | 223 | if (packageName != null) { |
| 190 | name = packageName + "/" + name; | 224 | name = packageName + "/" + name; |
| 191 | } | 225 | } |
| @@ -207,12 +241,14 @@ public class EditorPanel { | |||
| 207 | if ((this.editorLaf == null || this.editorLaf != laf)) { | 241 | if ((this.editorLaf == null || this.editorLaf != laf)) { |
| 208 | this.editor.updateUI(); | 242 | this.editor.updateUI(); |
| 209 | this.editor.setBackground(UiConfig.getEditorBackgroundColor()); | 243 | this.editor.setBackground(UiConfig.getEditorBackgroundColor()); |
| 244 | |||
| 210 | if (this.editorLaf != null) { | 245 | if (this.editorLaf != null) { |
| 211 | this.classHandle.invalidateMapped(); | 246 | this.classHandle.invalidateMapped(); |
| 212 | } | 247 | } |
| 213 | 248 | ||
| 214 | this.editorLaf = laf; | 249 | this.editorLaf = laf; |
| 215 | } | 250 | } |
| 251 | |||
| 216 | this.boxHighlightPainters = boxHighlightPainters; | 252 | this.boxHighlightPainters = boxHighlightPainters; |
| 217 | }; | 253 | }; |
| 218 | 254 | ||
| @@ -223,19 +259,23 @@ public class EditorPanel { | |||
| 223 | public static EditorPanel byUi(Component ui) { | 259 | public static EditorPanel byUi(Component ui) { |
| 224 | if (ui instanceof JComponent) { | 260 | if (ui instanceof JComponent) { |
| 225 | Object prop = ((JComponent) ui).getClientProperty(EditorPanel.class); | 261 | Object prop = ((JComponent) ui).getClientProperty(EditorPanel.class); |
| 262 | |||
| 226 | if (prop instanceof EditorPanel) { | 263 | if (prop instanceof EditorPanel) { |
| 227 | return (EditorPanel) prop; | 264 | return (EditorPanel) prop; |
| 228 | } | 265 | } |
| 229 | } | 266 | } |
| 267 | |||
| 230 | return null; | 268 | return null; |
| 231 | } | 269 | } |
| 232 | 270 | ||
| 233 | public void setClassHandle(ClassHandle handle) { | 271 | public void setClassHandle(ClassHandle handle) { |
| 234 | ClassEntry old = null; | 272 | ClassEntry old = null; |
| 273 | |||
| 235 | if (this.classHandle != null) { | 274 | if (this.classHandle != null) { |
| 236 | old = this.classHandle.getRef(); | 275 | old = this.classHandle.getRef(); |
| 237 | this.classHandle.close(); | 276 | this.classHandle.close(); |
| 238 | } | 277 | } |
| 278 | |||
| 239 | setClassHandle0(old, handle); | 279 | setClassHandle0(old, handle); |
| 240 | } | 280 | } |
| 241 | 281 | ||
| @@ -299,53 +339,61 @@ public class EditorPanel { | |||
| 299 | } else { | 339 | } else { |
| 300 | this.displayError(res.unwrapErr()); | 340 | this.displayError(res.unwrapErr()); |
| 301 | } | 341 | } |
| 342 | |||
| 302 | this.nextReference = null; | 343 | this.nextReference = null; |
| 303 | }); | 344 | }); |
| 304 | } | 345 | } |
| 305 | 346 | ||
| 306 | public void displayError(ClassHandleError t) { | 347 | public void displayError(ClassHandleError t) { |
| 307 | this.setDisplayMode(DisplayMode.ERRORED); | 348 | this.setDisplayMode(DisplayMode.ERRORED); |
| 349 | |||
| 308 | String str = switch (t.type) { | 350 | String str = switch (t.type) { |
| 309 | case DECOMPILE -> "editor.decompile_error"; | 351 | case DECOMPILE -> "editor.decompile_error"; |
| 310 | case REMAP -> "editor.remap_error"; | 352 | case REMAP -> "editor.remap_error"; |
| 311 | }; | 353 | }; |
| 354 | |||
| 312 | this.errorLabel.setText(I18n.translate(str)); | 355 | this.errorLabel.setText(I18n.translate(str)); |
| 313 | this.errorTextArea.setText(t.getStackTrace()); | 356 | this.errorTextArea.setText(t.getStackTrace()); |
| 314 | this.errorTextArea.setCaretPosition(0); | 357 | this.errorTextArea.setCaretPosition(0); |
| 315 | } | 358 | } |
| 316 | 359 | ||
| 317 | public void setDisplayMode(DisplayMode mode) { | 360 | public void setDisplayMode(DisplayMode mode) { |
| 318 | if (this.mode == mode) return; | 361 | if (this.mode == mode) { |
| 362 | return; | ||
| 363 | } | ||
| 364 | |||
| 319 | this.ui.removeAll(); | 365 | this.ui.removeAll(); |
| 366 | |||
| 320 | switch (mode) { | 367 | switch (mode) { |
| 321 | case INACTIVE: | 368 | case INACTIVE: |
| 322 | break; | 369 | break; |
| 323 | case IN_PROGRESS: { | 370 | case IN_PROGRESS: { |
| 324 | // make progress bar start from the left every time | 371 | // make progress bar start from the left every time |
| 325 | this.decompilingProgressBar.setIndeterminate(false); | 372 | this.decompilingProgressBar.setIndeterminate(false); |
| 326 | this.decompilingProgressBar.setIndeterminate(true); | 373 | this.decompilingProgressBar.setIndeterminate(true); |
| 327 | 374 | ||
| 328 | this.ui.setLayout(new GridBagLayout()); | 375 | this.ui.setLayout(new GridBagLayout()); |
| 329 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2); | 376 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2); |
| 330 | this.ui.add(this.decompilingLabel, cb.pos(0, 0).anchor(GridBagConstraints.SOUTH).build()); | 377 | this.ui.add(this.decompilingLabel, cb.pos(0, 0).anchor(GridBagConstraints.SOUTH).build()); |
| 331 | this.ui.add(this.decompilingProgressBar, cb.pos(0, 1).anchor(GridBagConstraints.NORTH).build()); | 378 | this.ui.add(this.decompilingProgressBar, cb.pos(0, 1).anchor(GridBagConstraints.NORTH).build()); |
| 332 | break; | 379 | break; |
| 333 | } | 380 | } |
| 334 | case SUCCESS: { | 381 | case SUCCESS: { |
| 335 | this.ui.setLayout(new GridLayout(1, 1, 0, 0)); | 382 | this.ui.setLayout(new GridLayout(1, 1, 0, 0)); |
| 336 | this.ui.add(this.editorScrollPane); | 383 | this.ui.add(this.editorScrollPane); |
| 337 | break; | 384 | break; |
| 338 | } | 385 | } |
| 339 | case ERRORED: { | 386 | case ERRORED: { |
| 340 | this.ui.setLayout(new GridBagLayout()); | 387 | this.ui.setLayout(new GridBagLayout()); |
| 341 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2).weight(1.0, 0.0).anchor(GridBagConstraints.WEST); | 388 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2).weight(1.0, 0.0).anchor(GridBagConstraints.WEST); |
| 342 | this.ui.add(this.errorLabel, cb.pos(0, 0).build()); | 389 | this.ui.add(this.errorLabel, cb.pos(0, 0).build()); |
| 343 | this.ui.add(new JSeparator(JSeparator.HORIZONTAL), cb.pos(0, 1).fill(GridBagConstraints.HORIZONTAL).build()); | 390 | this.ui.add(new JSeparator(JSeparator.HORIZONTAL), cb.pos(0, 1).fill(GridBagConstraints.HORIZONTAL).build()); |
| 344 | this.ui.add(this.errorScrollPane, cb.pos(0, 2).weight(1.0, 1.0).fill(GridBagConstraints.BOTH).build()); | 391 | this.ui.add(this.errorScrollPane, cb.pos(0, 2).weight(1.0, 1.0).fill(GridBagConstraints.BOTH).build()); |
| 345 | this.ui.add(this.retryButton, cb.pos(0, 3).weight(0.0, 0.0).anchor(GridBagConstraints.EAST).build()); | 392 | this.ui.add(this.retryButton, cb.pos(0, 3).weight(0.0, 0.0).anchor(GridBagConstraints.EAST).build()); |
| 346 | break; | 393 | break; |
| 347 | } | 394 | } |
| 348 | } | 395 | } |
| 396 | |||
| 349 | this.ui.validate(); | 397 | this.ui.validate(); |
| 350 | this.ui.repaint(); | 398 | this.ui.repaint(); |
| 351 | this.mode = mode; | 399 | this.mode = mode; |
| @@ -353,6 +401,7 @@ public class EditorPanel { | |||
| 353 | 401 | ||
| 354 | public void offsetEditorZoom(int zoomAmount) { | 402 | public void offsetEditorZoom(int zoomAmount) { |
| 355 | int newResult = this.fontSize + zoomAmount; | 403 | int newResult = this.fontSize + zoomAmount; |
| 404 | |||
| 356 | if (newResult > 8 && newResult < 72) { | 405 | if (newResult > 8 && newResult < 72) { |
| 357 | this.fontSize = newResult; | 406 | this.fontSize = newResult; |
| 358 | this.editor.setFont(ScaleUtil.getFont(this.editor.getFont().getFontName(), Font.PLAIN, this.fontSize)); | 407 | this.editor.setFont(ScaleUtil.getFont(this.editor.getFont().getFontName(), Font.PLAIN, this.fontSize)); |
| @@ -365,8 +414,13 @@ public class EditorPanel { | |||
| 365 | } | 414 | } |
| 366 | 415 | ||
| 367 | public void onCaretMove(int pos, boolean fromClick) { | 416 | public void onCaretMove(int pos, boolean fromClick) { |
| 368 | if (this.settingSource) return; | 417 | if (this.settingSource) { |
| 369 | if (this.controller.project == null) return; | 418 | return; |
| 419 | } | ||
| 420 | |||
| 421 | if (this.controller.project == null) { | ||
| 422 | return; | ||
| 423 | } | ||
| 370 | 424 | ||
| 371 | EntryRemapper mapper = this.controller.project.getMapper(); | 425 | EntryRemapper mapper = this.controller.project.getMapper(); |
| 372 | Token token = getToken(pos); | 426 | Token token = getToken(pos); |
| @@ -378,10 +432,12 @@ public class EditorPanel { | |||
| 378 | if (referenceEntry != null && this.shouldNavigateOnClick && fromClick) { | 432 | if (referenceEntry != null && this.shouldNavigateOnClick && fromClick) { |
| 379 | this.shouldNavigateOnClick = false; | 433 | this.shouldNavigateOnClick = false; |
| 380 | Entry<?> navigationEntry = referenceEntry; | 434 | Entry<?> navigationEntry = referenceEntry; |
| 435 | |||
| 381 | if (this.cursorReference.context == null) { | 436 | if (this.cursorReference.context == null) { |
| 382 | EntryResolver resolver = mapper.getObfResolver(); | 437 | EntryResolver resolver = mapper.getObfResolver(); |
| 383 | navigationEntry = resolver.resolveFirstEntry(referenceEntry, ResolutionStrategy.RESOLVE_ROOT); | 438 | navigationEntry = resolver.resolveFirstEntry(referenceEntry, ResolutionStrategy.RESOLVE_ROOT); |
| 384 | } | 439 | } |
| 440 | |||
| 385 | this.controller.navigateTo(navigationEntry); | 441 | this.controller.navigateTo(navigationEntry); |
| 386 | } | 442 | } |
| 387 | } | 443 | } |
| @@ -398,6 +454,7 @@ public class EditorPanel { | |||
| 398 | if (this.source == null) { | 454 | if (this.source == null) { |
| 399 | return null; | 455 | return null; |
| 400 | } | 456 | } |
| 457 | |||
| 401 | return this.source.getIndex().getReferenceToken(pos); | 458 | return this.source.getIndex().getReferenceToken(pos); |
| 402 | } | 459 | } |
| 403 | 460 | ||
| @@ -406,16 +463,22 @@ public class EditorPanel { | |||
| 406 | if (this.source == null) { | 463 | if (this.source == null) { |
| 407 | return null; | 464 | return null; |
| 408 | } | 465 | } |
| 466 | |||
| 409 | return this.source.getIndex().getReference(token); | 467 | return this.source.getIndex().getReference(token); |
| 410 | } | 468 | } |
| 411 | 469 | ||
| 412 | public void setSource(DecompiledClassSource source) { | 470 | public void setSource(DecompiledClassSource source) { |
| 413 | this.setDisplayMode(DisplayMode.SUCCESS); | 471 | this.setDisplayMode(DisplayMode.SUCCESS); |
| 414 | if (source == null) return; | 472 | |
| 473 | if (source == null) { | ||
| 474 | return; | ||
| 475 | } | ||
| 476 | |||
| 415 | try { | 477 | try { |
| 416 | this.settingSource = true; | 478 | this.settingSource = true; |
| 417 | 479 | ||
| 418 | int newCaretPos = 0; | 480 | int newCaretPos = 0; |
| 481 | |||
| 419 | if (this.source != null && this.source.getEntry().equals(source.getEntry())) { | 482 | if (this.source != null && this.source.getEntry().equals(source.getEntry())) { |
| 420 | int caretPos = this.editor.getCaretPosition(); | 483 | int caretPos = this.editor.getCaretPosition(); |
| 421 | 484 | ||
| @@ -441,9 +504,11 @@ public class EditorPanel { | |||
| 441 | this.source = source; | 504 | this.source = source; |
| 442 | this.editor.getHighlighter().removeAllHighlights(); | 505 | this.editor.getHighlighter().removeAllHighlights(); |
| 443 | this.editor.setText(source.toString()); | 506 | this.editor.setText(source.toString()); |
| 507 | |||
| 444 | if (this.source != null) { | 508 | if (this.source != null) { |
| 445 | this.editor.setCaretPosition(newCaretPos); | 509 | this.editor.setCaretPosition(newCaretPos); |
| 446 | } | 510 | } |
| 511 | |||
| 447 | setHighlightedTokens(source.getHighlightedTokens()); | 512 | setHighlightedTokens(source.getHighlightedTokens()); |
| 448 | setCursorReference(getReference(getToken(this.editor.getCaretPosition()))); | 513 | setCursorReference(getReference(getToken(this.editor.getCaretPosition()))); |
| 449 | } finally { | 514 | } finally { |
| @@ -515,10 +580,16 @@ public class EditorPanel { | |||
| 515 | * @param reference | 580 | * @param reference |
| 516 | */ | 581 | */ |
| 517 | private void showReference0(EntryReference<Entry<?>, Entry<?>> reference) { | 582 | private void showReference0(EntryReference<Entry<?>, Entry<?>> reference) { |
| 518 | if (this.source == null) return; | 583 | if (this.source == null) { |
| 519 | if (reference == null) return; | 584 | return; |
| 585 | } | ||
| 586 | |||
| 587 | if (reference == null) { | ||
| 588 | return; | ||
| 589 | } | ||
| 520 | 590 | ||
| 521 | List<Token> tokens = this.controller.getTokensForReference(this.source, reference); | 591 | List<Token> tokens = this.controller.getTokensForReference(this.source, reference); |
| 592 | |||
| 522 | if (tokens.isEmpty()) { | 593 | if (tokens.isEmpty()) { |
| 523 | // DEBUG | 594 | // DEBUG |
| 524 | System.err.println(String.format("WARNING: no tokens found for %s in %s", reference, this.classHandle.getRef())); | 595 | System.err.println(String.format("WARNING: no tokens found for %s in %s", reference, this.classHandle.getRef())); |
| @@ -531,6 +602,7 @@ public class EditorPanel { | |||
| 531 | if (token == null) { | 602 | if (token == null) { |
| 532 | throw new IllegalArgumentException("Token cannot be null!"); | 603 | throw new IllegalArgumentException("Token cannot be null!"); |
| 533 | } | 604 | } |
| 605 | |||
| 534 | navigateToToken(token, SelectionHighlightPainter.INSTANCE); | 606 | navigateToToken(token, SelectionHighlightPainter.INSTANCE); |
| 535 | } | 607 | } |
| 536 | 608 | ||
| @@ -546,9 +618,11 @@ public class EditorPanel { | |||
| 546 | // make sure the token is visible in the scroll window | 618 | // make sure the token is visible in the scroll window |
| 547 | Rectangle start = this.editor.modelToView(token.start); | 619 | Rectangle start = this.editor.modelToView(token.start); |
| 548 | Rectangle end = this.editor.modelToView(token.end); | 620 | Rectangle end = this.editor.modelToView(token.end); |
| 621 | |||
| 549 | if (start == null || end == null) { | 622 | if (start == null || end == null) { |
| 550 | return; | 623 | return; |
| 551 | } | 624 | } |
| 625 | |||
| 552 | Rectangle show = start.union(end); | 626 | Rectangle show = start.union(end); |
| 553 | show.grow(start.width * 10, start.height * 6); | 627 | show.grow(start.width * 10, start.height * 6); |
| 554 | SwingUtilities.invokeLater(() -> this.editor.scrollRectToVisible(show)); | 628 | SwingUtilities.invokeLater(() -> this.editor.scrollRectToVisible(show)); |
| @@ -625,5 +699,4 @@ public class EditorPanel { | |||
| 625 | SUCCESS, | 699 | SUCCESS, |
| 626 | ERRORED, | 700 | ERRORED, |
| 627 | } | 701 | } |
| 628 | |||
| 629 | } | 702 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java index e71894d..7b75f1a 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/IdentifierPanel.java | |||
| @@ -25,12 +25,15 @@ import cuchaz.enigma.gui.util.ScaleUtil; | |||
| 25 | import cuchaz.enigma.translation.mapping.AccessModifier; | 25 | import cuchaz.enigma.translation.mapping.AccessModifier; |
| 26 | import cuchaz.enigma.translation.mapping.EntryChange; | 26 | import cuchaz.enigma.translation.mapping.EntryChange; |
| 27 | import cuchaz.enigma.translation.mapping.EntryMapping; | 27 | import cuchaz.enigma.translation.mapping.EntryMapping; |
| 28 | import cuchaz.enigma.translation.representation.entry.*; | 28 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 29 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 30 | import cuchaz.enigma.translation.representation.entry.FieldEntry; | ||
| 31 | import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; | ||
| 32 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 29 | import cuchaz.enigma.utils.I18n; | 33 | import cuchaz.enigma.utils.I18n; |
| 30 | import cuchaz.enigma.utils.validation.ValidationContext; | 34 | import cuchaz.enigma.utils.validation.ValidationContext; |
| 31 | 35 | ||
| 32 | public class IdentifierPanel { | 36 | public class IdentifierPanel { |
| 33 | |||
| 34 | private final Gui gui; | 37 | private final Gui gui; |
| 35 | 38 | ||
| 36 | private final JPanel ui = new JPanel(); | 39 | private final JPanel ui = new JPanel(); |
| @@ -57,7 +60,9 @@ public class IdentifierPanel { | |||
| 57 | } | 60 | } |
| 58 | 61 | ||
| 59 | public boolean startRenaming() { | 62 | public boolean startRenaming() { |
| 60 | if (this.nameField == null) return false; | 63 | if (this.nameField == null) { |
| 64 | return false; | ||
| 65 | } | ||
| 61 | 66 | ||
| 62 | this.nameField.startEditing(); | 67 | this.nameField.startEditing(); |
| 63 | 68 | ||
| @@ -65,7 +70,9 @@ public class IdentifierPanel { | |||
| 65 | } | 70 | } |
| 66 | 71 | ||
| 67 | public boolean startRenaming(String text) { | 72 | public boolean startRenaming(String text) { |
| 68 | if (this.nameField == null) return false; | 73 | if (this.nameField == null) { |
| 74 | return false; | ||
| 75 | } | ||
| 69 | 76 | ||
| 70 | this.nameField.startEditing(); | 77 | this.nameField.startEditing(); |
| 71 | this.nameField.setEditText(text); | 78 | this.nameField.setEditText(text); |
| @@ -84,6 +91,7 @@ public class IdentifierPanel { | |||
| 84 | 91 | ||
| 85 | TableHelper th = new TableHelper(this.ui, this.entry, this.gui); | 92 | TableHelper th = new TableHelper(this.ui, this.entry, this.gui); |
| 86 | th.begin(); | 93 | th.begin(); |
| 94 | |||
| 87 | if (this.entry == null) { | 95 | if (this.entry == null) { |
| 88 | this.ui.setEnabled(false); | 96 | this.ui.setEnabled(false); |
| 89 | } else { | 97 | } else { |
| @@ -102,8 +110,10 @@ public class IdentifierPanel { | |||
| 102 | th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), EditableType.FIELD, this::onModifierChanged); | 110 | th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), EditableType.FIELD, this::onModifierChanged); |
| 103 | } else if (deobfEntry instanceof MethodEntry) { | 111 | } else if (deobfEntry instanceof MethodEntry) { |
| 104 | MethodEntry me = (MethodEntry) deobfEntry; | 112 | MethodEntry me = (MethodEntry) deobfEntry; |
| 113 | |||
| 105 | if (me.isConstructor()) { | 114 | if (me.isConstructor()) { |
| 106 | ClassEntry ce = me.getParent(); | 115 | ClassEntry ce = me.getParent(); |
| 116 | |||
| 107 | if (ce != null) { | 117 | if (ce != null) { |
| 108 | String name = ce.isInnerClass() ? ce.getName() : ce.getFullName(); | 118 | String name = ce.isInnerClass() ? ce.getName() : ce.getFullName(); |
| 109 | this.nameField = th.addRenameTextField(EditableType.CLASS, name); | 119 | this.nameField = th.addRenameTextField(EditableType.CLASS, name); |
| @@ -112,6 +122,7 @@ public class IdentifierPanel { | |||
| 112 | this.nameField = th.addRenameTextField(EditableType.METHOD, me.getName()); | 122 | this.nameField = th.addRenameTextField(EditableType.METHOD, me.getName()); |
| 113 | th.addStringRow(I18n.translate("info_panel.identifier.class"), me.getParent().getFullName()); | 123 | th.addStringRow(I18n.translate("info_panel.identifier.class"), me.getParent().getFullName()); |
| 114 | } | 124 | } |
| 125 | |||
| 115 | th.addCopiableStringRow(I18n.translate("info_panel.identifier.method_descriptor"), me.getDesc().toString()); | 126 | th.addCopiableStringRow(I18n.translate("info_panel.identifier.method_descriptor"), me.getDesc().toString()); |
| 116 | th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), EditableType.METHOD, this::onModifierChanged); | 127 | th.addModifierRow(I18n.translate("info_panel.identifier.modifier"), EditableType.METHOD, this::onModifierChanged); |
| 117 | } else if (deobfEntry instanceof LocalVariableEntry) { | 128 | } else if (deobfEntry instanceof LocalVariableEntry) { |
| @@ -132,6 +143,7 @@ public class IdentifierPanel { | |||
| 132 | throw new IllegalStateException("unreachable"); | 143 | throw new IllegalStateException("unreachable"); |
| 133 | } | 144 | } |
| 134 | } | 145 | } |
| 146 | |||
| 135 | th.end(); | 147 | th.end(); |
| 136 | 148 | ||
| 137 | if (this.nameField != null) { | 149 | if (this.nameField != null) { |
| @@ -139,6 +151,7 @@ public class IdentifierPanel { | |||
| 139 | @Override | 151 | @Override |
| 140 | public void onStartEditing(ConvertingTextField field) { | 152 | public void onStartEditing(ConvertingTextField field) { |
| 141 | int i = field.getText().lastIndexOf('/'); | 153 | int i = field.getText().lastIndexOf('/'); |
| 154 | |||
| 142 | if (i != -1) { | 155 | if (i != -1) { |
| 143 | field.selectSubstring(i + 1); | 156 | field.selectSubstring(i + 1); |
| 144 | } | 157 | } |
| @@ -146,7 +159,10 @@ public class IdentifierPanel { | |||
| 146 | 159 | ||
| 147 | @Override | 160 | @Override |
| 148 | public boolean tryStopEditing(ConvertingTextField field, boolean abort) { | 161 | public boolean tryStopEditing(ConvertingTextField field, boolean abort) { |
| 149 | if (abort) return true; | 162 | if (abort) { |
| 163 | return true; | ||
| 164 | } | ||
| 165 | |||
| 150 | vc.reset(); | 166 | vc.reset(); |
| 151 | vc.setActiveElement(field); | 167 | vc.setActiveElement(field); |
| 152 | validateRename(field.getText()); | 168 | validateRename(field.getText()); |
| @@ -162,6 +178,7 @@ public class IdentifierPanel { | |||
| 162 | } | 178 | } |
| 163 | 179 | ||
| 164 | EditorPanel e = gui.getActiveEditor(); | 180 | EditorPanel e = gui.getActiveEditor(); |
| 181 | |||
| 165 | if (e != null) { | 182 | if (e != null) { |
| 166 | e.getEditor().requestFocusInWindow(); | 183 | e.getEditor().requestFocusInWindow(); |
| 167 | } | 184 | } |
| @@ -192,13 +209,12 @@ public class IdentifierPanel { | |||
| 192 | } | 209 | } |
| 193 | 210 | ||
| 194 | private static final class TableHelper { | 211 | private static final class TableHelper { |
| 195 | |||
| 196 | private final Container c; | 212 | private final Container c; |
| 197 | private final Entry<?> e; | 213 | private final Entry<?> e; |
| 198 | private final Gui gui; | 214 | private final Gui gui; |
| 199 | private int row; | 215 | private int row; |
| 200 | 216 | ||
| 201 | public TableHelper(Container c, Entry<?> e, Gui gui) { | 217 | TableHelper(Container c, Entry<?> e, Gui gui) { |
| 202 | this.c = c; | 218 | this.c = c; |
| 203 | this.e = e; | 219 | this.e = e; |
| 204 | this.gui = gui; | 220 | this.gui = gui; |
| @@ -210,9 +226,7 @@ public class IdentifierPanel { | |||
| 210 | } | 226 | } |
| 211 | 227 | ||
| 212 | public void addRow(Component c1, Component c2) { | 228 | public void addRow(Component c1, Component c2) { |
| 213 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create() | 229 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(2).anchor(GridBagConstraints.WEST); |
| 214 | .insets(2) | ||
| 215 | .anchor(GridBagConstraints.WEST); | ||
| 216 | c.add(c1, cb.pos(0, this.row).build()); | 230 | c.add(c1, cb.pos(0, this.row).build()); |
| 217 | c.add(c2, cb.pos(1, this.row).weightX(1.0).fill(GridBagConstraints.HORIZONTAL).build()); | 231 | c.add(c2, cb.pos(1, this.row).weightX(1.0).fill(GridBagConstraints.HORIZONTAL).build()); |
| 218 | 232 | ||
| @@ -239,12 +253,12 @@ public class IdentifierPanel { | |||
| 239 | } | 253 | } |
| 240 | 254 | ||
| 241 | public ConvertingTextField addRenameTextField(EditableType type, String c2) { | 255 | public ConvertingTextField addRenameTextField(EditableType type, String c2) { |
| 242 | String description = switch(type) { | 256 | String description = switch (type) { |
| 243 | case CLASS -> I18n.translate("info_panel.identifier.class"); | 257 | case CLASS -> I18n.translate("info_panel.identifier.class"); |
| 244 | case METHOD -> I18n.translate("info_panel.identifier.method"); | 258 | case METHOD -> I18n.translate("info_panel.identifier.method"); |
| 245 | case FIELD -> I18n.translate("info_panel.identifier.field"); | 259 | case FIELD -> I18n.translate("info_panel.identifier.field"); |
| 246 | case PARAMETER, LOCAL_VARIABLE -> I18n.translate("info_panel.identifier.variable"); | 260 | case PARAMETER, LOCAL_VARIABLE -> I18n.translate("info_panel.identifier.variable"); |
| 247 | default -> throw new IllegalStateException("Unexpected value: " + type); | 261 | default -> throw new IllegalStateException("Unexpected value: " + type); |
| 248 | }; | 262 | }; |
| 249 | 263 | ||
| 250 | if (this.gui.getController().project.isRenamable(e)) { | 264 | if (this.gui.getController().project.isRenamable(e)) { |
| @@ -296,7 +310,5 @@ public class IdentifierPanel { | |||
| 296 | // Add an empty panel with y-weight=1 so that all the other elements get placed at the top edge | 310 | // Add an empty panel with y-weight=1 so that all the other elements get placed at the top edge |
| 297 | c.add(new JPanel(), GridBagConstraintsBuilder.create().pos(0, row).weight(0.0, 1.0).build()); | 311 | c.add(new JPanel(), GridBagConstraintsBuilder.create().pos(0, row).weight(0.0, 1.0).build()); |
| 298 | } | 312 | } |
| 299 | |||
| 300 | } | 313 | } |
| 301 | |||
| 302 | } | 314 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/ObfPanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/ObfPanel.java index 7783843..f82e666 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/ObfPanel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/ObfPanel.java | |||
| @@ -13,7 +13,6 @@ import cuchaz.enigma.translation.representation.entry.ClassEntry; | |||
| 13 | import cuchaz.enigma.utils.I18n; | 13 | import cuchaz.enigma.utils.I18n; |
| 14 | 14 | ||
| 15 | public class ObfPanel extends JPanel { | 15 | public class ObfPanel extends JPanel { |
| 16 | |||
| 17 | public final ClassSelector obfClasses; | 16 | public final ClassSelector obfClasses; |
| 18 | private final JLabel title = new JLabel(); | 17 | private final JLabel title = new JLabel(); |
| 19 | 18 | ||
| @@ -25,9 +24,11 @@ public class ObfPanel extends JPanel { | |||
| 25 | Comparator<ClassEntry> obfClassComparator = (a, b) -> { | 24 | Comparator<ClassEntry> obfClassComparator = (a, b) -> { |
| 26 | String aname = a.getFullName(); | 25 | String aname = a.getFullName(); |
| 27 | String bname = b.getFullName(); | 26 | String bname = b.getFullName(); |
| 27 | |||
| 28 | if (aname.length() != bname.length()) { | 28 | if (aname.length() != bname.length()) { |
| 29 | return aname.length() - bname.length(); | 29 | return aname.length() - bname.length(); |
| 30 | } | 30 | } |
| 31 | |||
| 31 | return aname.compareTo(bname); | 32 | return aname.compareTo(bname); |
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| @@ -45,5 +46,4 @@ public class ObfPanel extends JPanel { | |||
| 45 | public void retranslateUi() { | 46 | public void retranslateUi() { |
| 46 | this.title.setText(I18n.translate("info_panel.classes.obfuscated")); | 47 | this.title.setText(I18n.translate("info_panel.classes.obfuscated")); |
| 47 | } | 48 | } |
| 48 | |||
| 49 | } | 49 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/StructurePanel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/StructurePanel.java index ccded45..571c638 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/StructurePanel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/panels/StructurePanel.java | |||
| @@ -1,9 +1,16 @@ | |||
| 1 | package cuchaz.enigma.gui.panels; | 1 | package cuchaz.enigma.gui.panels; |
| 2 | 2 | ||
| 3 | import java.awt.*; | 3 | import java.awt.BorderLayout; |
| 4 | import java.awt.Component; | ||
| 5 | import java.awt.GridBagConstraints; | ||
| 6 | import java.awt.GridBagLayout; | ||
| 4 | import java.awt.event.MouseEvent; | 7 | import java.awt.event.MouseEvent; |
| 5 | 8 | ||
| 6 | import javax.swing.*; | 9 | import javax.swing.JComboBox; |
| 10 | import javax.swing.JLabel; | ||
| 11 | import javax.swing.JPanel; | ||
| 12 | import javax.swing.JScrollPane; | ||
| 13 | import javax.swing.JTree; | ||
| 7 | import javax.swing.tree.DefaultTreeCellRenderer; | 14 | import javax.swing.tree.DefaultTreeCellRenderer; |
| 8 | import javax.swing.tree.DefaultTreeModel; | 15 | import javax.swing.tree.DefaultTreeModel; |
| 9 | import javax.swing.tree.TreeNode; | 16 | import javax.swing.tree.TreeNode; |
| @@ -23,144 +30,144 @@ import cuchaz.enigma.translation.representation.entry.ParentedEntry; | |||
| 23 | import cuchaz.enigma.utils.I18n; | 30 | import cuchaz.enigma.utils.I18n; |
| 24 | 31 | ||
| 25 | public class StructurePanel { | 32 | public class StructurePanel { |
| 26 | private final Gui gui; | 33 | private final Gui gui; |
| 27 | 34 | ||
| 28 | private final JPanel panel = new JPanel(new BorderLayout()); | 35 | private final JPanel panel = new JPanel(new BorderLayout()); |
| 29 | 36 | ||
| 30 | private final JPanel optionsPanel; | 37 | private final JPanel optionsPanel; |
| 31 | 38 | ||
| 32 | private final JLabel obfuscationVisibilityLabel = new JLabel(); | 39 | private final JLabel obfuscationVisibilityLabel = new JLabel(); |
| 33 | private final JLabel documentationVisibilityLabel = new JLabel(); | 40 | private final JLabel documentationVisibilityLabel = new JLabel(); |
| 34 | private final JLabel sortingOrderLabel = new JLabel(); | 41 | private final JLabel sortingOrderLabel = new JLabel(); |
| 35 | 42 | ||
| 36 | private final JComboBox<StructureTreeOptions.ObfuscationVisibility> obfuscationVisibility; | 43 | private final JComboBox<StructureTreeOptions.ObfuscationVisibility> obfuscationVisibility; |
| 37 | private final JComboBox<StructureTreeOptions.DocumentationVisibility> documentationVisibility; | 44 | private final JComboBox<StructureTreeOptions.DocumentationVisibility> documentationVisibility; |
| 38 | private final JComboBox<StructureTreeOptions.SortingOrder> sortingOrder; | 45 | private final JComboBox<StructureTreeOptions.SortingOrder> sortingOrder; |
| 39 | 46 | ||
| 40 | private final JTree structureTree; | 47 | private final JTree structureTree; |
| 41 | 48 | ||
| 42 | public StructurePanel(Gui gui) { | 49 | public StructurePanel(Gui gui) { |
| 43 | this.gui = gui; | 50 | this.gui = gui; |
| 44 | 51 | ||
| 45 | this.optionsPanel = new JPanel(new GridBagLayout()); | 52 | this.optionsPanel = new JPanel(new GridBagLayout()); |
| 46 | this.optionsPanel.setVisible(false); | 53 | this.optionsPanel.setVisible(false); |
| 47 | 54 | ||
| 48 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(5).fill(GridBagConstraints.HORIZONTAL); | 55 | GridBagConstraintsBuilder cb = GridBagConstraintsBuilder.create().insets(5).fill(GridBagConstraints.HORIZONTAL); |
| 49 | 56 | ||
| 50 | this.optionsPanel.add(this.obfuscationVisibilityLabel, cb.pos(0, 0).build()); | 57 | this.optionsPanel.add(this.obfuscationVisibilityLabel, cb.pos(0, 0).build()); |
| 51 | this.obfuscationVisibility = new JComboBox<>(StructureTreeOptions.ObfuscationVisibility.values()); | 58 | this.obfuscationVisibility = new JComboBox<>(StructureTreeOptions.ObfuscationVisibility.values()); |
| 52 | this.obfuscationVisibility.setRenderer(new StructureOptionListCellRenderer()); | 59 | this.obfuscationVisibility.setRenderer(new StructureOptionListCellRenderer()); |
| 53 | this.obfuscationVisibility.addActionListener(event -> this.showStructure(gui.getActiveEditor())); | 60 | this.obfuscationVisibility.addActionListener(event -> this.showStructure(gui.getActiveEditor())); |
| 54 | this.optionsPanel.add(this.obfuscationVisibility, cb.pos(1, 0).build()); | 61 | this.optionsPanel.add(this.obfuscationVisibility, cb.pos(1, 0).build()); |
| 55 | 62 | ||
| 56 | this.optionsPanel.add(this.documentationVisibilityLabel, cb.pos(0, 1).build()); | 63 | this.optionsPanel.add(this.documentationVisibilityLabel, cb.pos(0, 1).build()); |
| 57 | this.documentationVisibility = new JComboBox<>(StructureTreeOptions.DocumentationVisibility.values()); | 64 | this.documentationVisibility = new JComboBox<>(StructureTreeOptions.DocumentationVisibility.values()); |
| 58 | this.documentationVisibility.setRenderer(new StructureOptionListCellRenderer()); | 65 | this.documentationVisibility.setRenderer(new StructureOptionListCellRenderer()); |
| 59 | this.documentationVisibility.addActionListener(event -> this.showStructure(gui.getActiveEditor())); | 66 | this.documentationVisibility.addActionListener(event -> this.showStructure(gui.getActiveEditor())); |
| 60 | this.optionsPanel.add(this.documentationVisibility, cb.pos(1, 1).build()); | 67 | this.optionsPanel.add(this.documentationVisibility, cb.pos(1, 1).build()); |
| 61 | 68 | ||
| 62 | this.optionsPanel.add(this.sortingOrderLabel, cb.pos(0, 2).build()); | 69 | this.optionsPanel.add(this.sortingOrderLabel, cb.pos(0, 2).build()); |
| 63 | this.sortingOrder = new JComboBox<>(StructureTreeOptions.SortingOrder.values()); | 70 | this.sortingOrder = new JComboBox<>(StructureTreeOptions.SortingOrder.values()); |
| 64 | this.sortingOrder.setRenderer(new StructureOptionListCellRenderer()); | 71 | this.sortingOrder.setRenderer(new StructureOptionListCellRenderer()); |
| 65 | this.sortingOrder.addActionListener(event -> this.showStructure(gui.getActiveEditor())); | 72 | this.sortingOrder.addActionListener(event -> this.showStructure(gui.getActiveEditor())); |
| 66 | this.optionsPanel.add(this.sortingOrder, cb.pos(1, 2).build()); | 73 | this.optionsPanel.add(this.sortingOrder, cb.pos(1, 2).build()); |
| 67 | 74 | ||
| 68 | this.structureTree = new JTree(); | 75 | this.structureTree = new JTree(); |
| 69 | this.structureTree.setModel(null); | 76 | this.structureTree.setModel(null); |
| 70 | this.structureTree.setCellRenderer(new StructureTreeCellRenderer(gui)); | 77 | this.structureTree.setCellRenderer(new StructureTreeCellRenderer(gui)); |
| 71 | this.structureTree.setSelectionModel(new SingleTreeSelectionModel()); | 78 | this.structureTree.setSelectionModel(new SingleTreeSelectionModel()); |
| 72 | this.structureTree.setShowsRootHandles(true); | 79 | this.structureTree.setShowsRootHandles(true); |
| 73 | this.structureTree.addMouseListener(GuiUtil.onMouseClick(this::onClick)); | 80 | this.structureTree.addMouseListener(GuiUtil.onMouseClick(this::onClick)); |
| 74 | 81 | ||
| 75 | this.retranslateUi(); | 82 | this.retranslateUi(); |
| 76 | 83 | ||
| 77 | this.panel.add(this.optionsPanel, BorderLayout.NORTH); | 84 | this.panel.add(this.optionsPanel, BorderLayout.NORTH); |
| 78 | this.panel.add(new JScrollPane(this.structureTree)); | 85 | this.panel.add(new JScrollPane(this.structureTree)); |
| 79 | } | 86 | } |
| 80 | 87 | ||
| 81 | public void showStructure(EditorPanel editor) { | 88 | public void showStructure(EditorPanel editor) { |
| 82 | structureTree.setModel(null); | 89 | structureTree.setModel(null); |
| 83 | 90 | ||
| 84 | if (editor == null) { | 91 | if (editor == null) { |
| 85 | this.optionsPanel.setVisible(false); | 92 | this.optionsPanel.setVisible(false); |
| 86 | return; | 93 | return; |
| 87 | } | 94 | } |
| 88 | 95 | ||
| 89 | ClassEntry classEntry = editor.getClassHandle().getRef(); | 96 | ClassEntry classEntry = editor.getClassHandle().getRef(); |
| 90 | if (classEntry == null) return; | 97 | |
| 91 | 98 | if (classEntry == null) { | |
| 92 | this.optionsPanel.setVisible(true); | 99 | return; |
| 93 | 100 | } | |
| 94 | // get the class structure | 101 | |
| 95 | StructureTreeNode node = this.gui.getController().getClassStructure(classEntry, this.getOptions()); | 102 | this.optionsPanel.setVisible(true); |
| 96 | 103 | ||
| 97 | // show the tree at the root | 104 | // get the class structure |
| 98 | TreePath path = GuiUtil.getPathToRoot(node); | 105 | StructureTreeNode node = this.gui.getController().getClassStructure(classEntry, this.getOptions()); |
| 99 | structureTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0))); | 106 | |
| 100 | structureTree.expandPath(path); | 107 | // show the tree at the root |
| 101 | structureTree.setSelectionRow(structureTree.getRowForPath(path)); | 108 | TreePath path = GuiUtil.getPathToRoot(node); |
| 102 | } | 109 | structureTree.setModel(new DefaultTreeModel((TreeNode) path.getPathComponent(0))); |
| 103 | 110 | structureTree.expandPath(path); | |
| 104 | private void onClick(MouseEvent event) { | 111 | structureTree.setSelectionRow(structureTree.getRowForPath(path)); |
| 105 | if (event.getClickCount() >= 2 && event.getButton() == MouseEvent.BUTTON1) { | 112 | } |
| 106 | // get the selected node | 113 | |
| 107 | TreePath path = structureTree.getSelectionPath(); | 114 | private void onClick(MouseEvent event) { |
| 108 | if (path == null) { | 115 | if (event.getClickCount() >= 2 && event.getButton() == MouseEvent.BUTTON1) { |
| 109 | return; | 116 | // get the selected node |
| 110 | } | 117 | TreePath path = structureTree.getSelectionPath(); |
| 111 | 118 | ||
| 112 | Object node = path.getLastPathComponent(); | 119 | if (path == null) { |
| 113 | 120 | return; | |
| 114 | if (node instanceof StructureTreeNode) { | 121 | } |
| 115 | this.gui.getController().navigateTo(((StructureTreeNode) node).getEntry()); | 122 | |
| 116 | } | 123 | Object node = path.getLastPathComponent(); |
| 117 | } | 124 | |
| 118 | } | 125 | if (node instanceof StructureTreeNode) { |
| 119 | 126 | this.gui.getController().navigateTo(((StructureTreeNode) node).getEntry()); | |
| 120 | /** | 127 | } |
| 121 | * Creates and returns the options of this structure panel. | 128 | } |
| 122 | */ | 129 | } |
| 123 | private StructureTreeOptions getOptions() { | 130 | |
| 124 | return new StructureTreeOptions( | 131 | /** |
| 125 | (StructureTreeOptions.ObfuscationVisibility) this.obfuscationVisibility.getSelectedItem(), | 132 | * Creates and returns the options of this structure panel. |
| 126 | (StructureTreeOptions.DocumentationVisibility) this.documentationVisibility.getSelectedItem(), | 133 | */ |
| 127 | (StructureTreeOptions.SortingOrder) this.sortingOrder.getSelectedItem() | 134 | private StructureTreeOptions getOptions() { |
| 128 | ); | 135 | return new StructureTreeOptions((StructureTreeOptions.ObfuscationVisibility) this.obfuscationVisibility.getSelectedItem(), (StructureTreeOptions.DocumentationVisibility) this.documentationVisibility.getSelectedItem(), (StructureTreeOptions.SortingOrder) this.sortingOrder.getSelectedItem()); |
| 129 | } | 136 | } |
| 130 | 137 | ||
| 131 | public void retranslateUi() { | 138 | public void retranslateUi() { |
| 132 | this.obfuscationVisibilityLabel.setText(I18n.translate("structure.options.obfuscation")); | 139 | this.obfuscationVisibilityLabel.setText(I18n.translate("structure.options.obfuscation")); |
| 133 | this.documentationVisibilityLabel.setText(I18n.translate("structure.options.documentation")); | 140 | this.documentationVisibilityLabel.setText(I18n.translate("structure.options.documentation")); |
| 134 | this.sortingOrderLabel.setText(I18n.translate("structure.options.sorting")); | 141 | this.sortingOrderLabel.setText(I18n.translate("structure.options.sorting")); |
| 135 | } | 142 | } |
| 136 | 143 | ||
| 137 | public JPanel getPanel() { | 144 | public JPanel getPanel() { |
| 138 | return this.panel; | 145 | return this.panel; |
| 139 | } | 146 | } |
| 140 | 147 | ||
| 141 | private static class StructureTreeCellRenderer extends DefaultTreeCellRenderer { | 148 | private static class StructureTreeCellRenderer extends DefaultTreeCellRenderer { |
| 142 | private final Gui gui; | 149 | private final Gui gui; |
| 143 | 150 | ||
| 144 | StructureTreeCellRenderer(Gui gui) { | 151 | StructureTreeCellRenderer(Gui gui) { |
| 145 | this.gui = gui; | 152 | this.gui = gui; |
| 146 | } | 153 | } |
| 147 | 154 | ||
| 148 | @Override | 155 | @Override |
| 149 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { | 156 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { |
| 150 | Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); | 157 | Component c = super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); |
| 151 | ParentedEntry<?> entry = ((StructureTreeNode) value).getEntry(); | 158 | ParentedEntry<?> entry = ((StructureTreeNode) value).getEntry(); |
| 152 | 159 | ||
| 153 | if (entry instanceof ClassEntry classEntry) { | 160 | if (entry instanceof ClassEntry classEntry) { |
| 154 | this.setIcon(GuiUtil.getClassIcon(gui, classEntry)); | 161 | this.setIcon(GuiUtil.getClassIcon(gui, classEntry)); |
| 155 | } else if (entry instanceof MethodEntry methodEntry) { | 162 | } else if (entry instanceof MethodEntry methodEntry) { |
| 156 | this.setIcon(GuiUtil.getMethodIcon(methodEntry)); | 163 | this.setIcon(GuiUtil.getMethodIcon(methodEntry)); |
| 157 | } else if (entry instanceof FieldEntry) { | 164 | } else if (entry instanceof FieldEntry) { |
| 158 | this.setIcon(GuiUtil.FIELD_ICON); | 165 | this.setIcon(GuiUtil.FIELD_ICON); |
| 159 | } | 166 | } |
| 160 | 167 | ||
| 161 | this.setText("<html>" + ((StructureTreeNode) value).toHtml()); | 168 | this.setText("<html>" + ((StructureTreeNode) value).toHtml()); |
| 162 | 169 | ||
| 163 | return c; | 170 | return c; |
| 164 | } | 171 | } |
| 165 | } | 172 | } |
| 166 | } | 173 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/CallsTreeCellRenderer.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/CallsTreeCellRenderer.java index 0aa6510..3791a1e 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/CallsTreeCellRenderer.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/CallsTreeCellRenderer.java | |||
| @@ -1,45 +1,51 @@ | |||
| 1 | package cuchaz.enigma.gui.renderer; | 1 | package cuchaz.enigma.gui.renderer; |
| 2 | 2 | ||
| 3 | import cuchaz.enigma.analysis.*; | 3 | import java.awt.Component; |
| 4 | |||
| 5 | import javax.swing.JTree; | ||
| 6 | import javax.swing.tree.DefaultTreeCellRenderer; | ||
| 7 | |||
| 8 | import cuchaz.enigma.analysis.ClassReferenceTreeNode; | ||
| 9 | import cuchaz.enigma.analysis.EntryReference; | ||
| 10 | import cuchaz.enigma.analysis.FieldReferenceTreeNode; | ||
| 11 | import cuchaz.enigma.analysis.MethodReferenceTreeNode; | ||
| 12 | import cuchaz.enigma.analysis.ReferenceTreeNode; | ||
| 4 | import cuchaz.enigma.gui.Gui; | 13 | import cuchaz.enigma.gui.Gui; |
| 5 | import cuchaz.enigma.gui.config.UiConfig; | 14 | import cuchaz.enigma.gui.config.UiConfig; |
| 6 | import cuchaz.enigma.gui.util.GuiUtil; | 15 | import cuchaz.enigma.gui.util.GuiUtil; |
| 7 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | 16 | import cuchaz.enigma.translation.representation.entry.MethodEntry; |
| 8 | 17 | ||
| 9 | import javax.swing.*; | ||
| 10 | import javax.swing.tree.DefaultTreeCellRenderer; | ||
| 11 | import java.awt.*; | ||
| 12 | |||
| 13 | public class CallsTreeCellRenderer extends DefaultTreeCellRenderer { | 18 | public class CallsTreeCellRenderer extends DefaultTreeCellRenderer { |
| 14 | private final Gui gui; | 19 | private final Gui gui; |
| 15 | 20 | ||
| 16 | public CallsTreeCellRenderer(Gui gui) { | 21 | public CallsTreeCellRenderer(Gui gui) { |
| 17 | this.gui = gui; | 22 | this.gui = gui; |
| 18 | } | 23 | } |
| 19 | 24 | ||
| 20 | @Override | 25 | @Override |
| 21 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { | 26 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { |
| 22 | Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); | 27 | Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); |
| 23 | EntryReference<?, ?> reference = ((ReferenceTreeNode<?, ?>) value).getReference(); | 28 | EntryReference<?, ?> reference = ((ReferenceTreeNode<?, ?>) value).getReference(); |
| 24 | 29 | ||
| 25 | this.setForeground(UiConfig.getTextColor()); | 30 | this.setForeground(UiConfig.getTextColor()); |
| 26 | 31 | ||
| 27 | // if the node represents the method calling the entry | 32 | // if the node represents the method calling the entry |
| 28 | if (reference != null) { | 33 | if (reference != null) { |
| 29 | if (reference.context instanceof MethodEntry) { | 34 | if (reference.context instanceof MethodEntry) { |
| 30 | this.setIcon(GuiUtil.getMethodIcon((MethodEntry) reference.context)); | 35 | this.setIcon(GuiUtil.getMethodIcon((MethodEntry) reference.context)); |
| 31 | } | 36 | } |
| 32 | // if the node represents the called entry | 37 | |
| 33 | } else { | 38 | // if the node represents the called entry |
| 34 | if (value instanceof ClassReferenceTreeNode node) { | 39 | } else { |
| 35 | this.setIcon(GuiUtil.getClassIcon(this.gui, node.getEntry())); | 40 | if (value instanceof ClassReferenceTreeNode node) { |
| 36 | } else if (value instanceof MethodReferenceTreeNode node) { | 41 | this.setIcon(GuiUtil.getClassIcon(this.gui, node.getEntry())); |
| 37 | this.setIcon(GuiUtil.getMethodIcon(node.getEntry())); | 42 | } else if (value instanceof MethodReferenceTreeNode node) { |
| 38 | } else if (value instanceof FieldReferenceTreeNode) { | 43 | this.setIcon(GuiUtil.getMethodIcon(node.getEntry())); |
| 39 | this.setIcon(GuiUtil.FIELD_ICON); | 44 | } else if (value instanceof FieldReferenceTreeNode) { |
| 40 | } | 45 | this.setIcon(GuiUtil.FIELD_ICON); |
| 41 | } | 46 | } |
| 42 | 47 | } | |
| 43 | return c; | 48 | |
| 44 | } | 49 | return c; |
| 50 | } | ||
| 45 | } | 51 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/ImplementationsTreeCellRenderer.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/ImplementationsTreeCellRenderer.java index 7bf3900..b4126c0 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/ImplementationsTreeCellRenderer.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/ImplementationsTreeCellRenderer.java | |||
| @@ -1,34 +1,35 @@ | |||
| 1 | package cuchaz.enigma.gui.renderer; | 1 | package cuchaz.enigma.gui.renderer; |
| 2 | 2 | ||
| 3 | import java.awt.Component; | ||
| 4 | |||
| 5 | import javax.swing.JTree; | ||
| 6 | import javax.swing.tree.DefaultTreeCellRenderer; | ||
| 7 | |||
| 3 | import cuchaz.enigma.analysis.ClassImplementationsTreeNode; | 8 | import cuchaz.enigma.analysis.ClassImplementationsTreeNode; |
| 4 | import cuchaz.enigma.analysis.MethodImplementationsTreeNode; | 9 | import cuchaz.enigma.analysis.MethodImplementationsTreeNode; |
| 5 | import cuchaz.enigma.gui.Gui; | 10 | import cuchaz.enigma.gui.Gui; |
| 6 | import cuchaz.enigma.gui.config.UiConfig; | 11 | import cuchaz.enigma.gui.config.UiConfig; |
| 7 | import cuchaz.enigma.gui.util.GuiUtil; | 12 | import cuchaz.enigma.gui.util.GuiUtil; |
| 8 | 13 | ||
| 9 | import javax.swing.*; | ||
| 10 | import javax.swing.tree.DefaultTreeCellRenderer; | ||
| 11 | import java.awt.*; | ||
| 12 | |||
| 13 | public class ImplementationsTreeCellRenderer extends DefaultTreeCellRenderer { | 14 | public class ImplementationsTreeCellRenderer extends DefaultTreeCellRenderer { |
| 14 | private final Gui gui; | 15 | private final Gui gui; |
| 15 | 16 | ||
| 16 | public ImplementationsTreeCellRenderer(Gui gui) { | 17 | public ImplementationsTreeCellRenderer(Gui gui) { |
| 17 | this.gui = gui; | 18 | this.gui = gui; |
| 18 | } | 19 | } |
| 19 | 20 | ||
| 20 | @Override | 21 | @Override |
| 21 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { | 22 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { |
| 22 | Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); | 23 | Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); |
| 23 | 24 | ||
| 24 | this.setForeground(UiConfig.getTextColor()); | 25 | this.setForeground(UiConfig.getTextColor()); |
| 25 | 26 | ||
| 26 | if (value instanceof ClassImplementationsTreeNode node) { | 27 | if (value instanceof ClassImplementationsTreeNode node) { |
| 27 | this.setIcon(GuiUtil.getClassIcon(this.gui, node.getClassEntry())); | 28 | this.setIcon(GuiUtil.getClassIcon(this.gui, node.getClassEntry())); |
| 28 | } else if (value instanceof MethodImplementationsTreeNode node) { | 29 | } else if (value instanceof MethodImplementationsTreeNode node) { |
| 29 | this.setIcon(GuiUtil.getMethodIcon(node.getMethodEntry())); | 30 | this.setIcon(GuiUtil.getMethodIcon(node.getMethodEntry())); |
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | return c; | 33 | return c; |
| 33 | } | 34 | } |
| 34 | } | 35 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/InheritanceTreeCellRenderer.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/InheritanceTreeCellRenderer.java index a102553..04bf0f9 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/InheritanceTreeCellRenderer.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/InheritanceTreeCellRenderer.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | /******************************************************************************* | 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2015 Jeff Martin. | 2 | * Copyright (c) 2015 Jeff Martin. |
| 3 | * All rights reserved. This program and the accompanying materials | 3 | * All rights reserved. This program and the accompanying materials |
| 4 | * are made available under the terms of the GNU Lesser General Public | 4 | * are made available under the terms of the GNU Lesser General Public |
| 5 | * License v3.0 which accompanies this distribution, and is available at | 5 | * License v3.0 which accompanies this distribution, and is available at |
| 6 | * http://www.gnu.org/licenses/lgpl.html | 6 | * http://www.gnu.org/licenses/lgpl.html |
| 7 | * <p> | 7 | * |
| 8 | * Contributors: | 8 | * <p>Contributors: |
| 9 | * Jeff Martin - initial API and implementation | 9 | * Jeff Martin - initial API and implementation |
| 10 | ******************************************************************************/ | 10 | ******************************************************************************/ |
| 11 | 11 | ||
| 12 | package cuchaz.enigma.gui.renderer; | 12 | package cuchaz.enigma.gui.renderer; |
| 13 | 13 | ||
| @@ -37,6 +37,7 @@ public class InheritanceTreeCellRenderer extends DefaultTreeCellRenderer { | |||
| 37 | if (!(value instanceof MethodInheritanceTreeNode node) || node.isImplemented()) { | 37 | if (!(value instanceof MethodInheritanceTreeNode node) || node.isImplemented()) { |
| 38 | ret.setForeground(UiConfig.getTextColor()); | 38 | ret.setForeground(UiConfig.getTextColor()); |
| 39 | ret.setFont(ret.getFont().deriveFont(Font.PLAIN)); | 39 | ret.setFont(ret.getFont().deriveFont(Font.PLAIN)); |
| 40 | |||
| 40 | if (value instanceof ClassInheritanceTreeNode) { | 41 | if (value instanceof ClassInheritanceTreeNode) { |
| 41 | this.setIcon(GuiUtil.getClassIcon(this.gui, ((ClassInheritanceTreeNode) value).getClassEntry())); | 42 | this.setIcon(GuiUtil.getClassIcon(this.gui, ((ClassInheritanceTreeNode) value).getClassEntry())); |
| 42 | } else if (value instanceof MethodInheritanceTreeNode) { | 43 | } else if (value instanceof MethodInheritanceTreeNode) { |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/MessageListCellRenderer.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/MessageListCellRenderer.java index b6ae0c5..123990e 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/MessageListCellRenderer.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/MessageListCellRenderer.java | |||
| @@ -10,15 +10,15 @@ import cuchaz.enigma.network.Message; | |||
| 10 | // For now, just render the translated text. | 10 | // For now, just render the translated text. |
| 11 | // TODO: Icons or something later? | 11 | // TODO: Icons or something later? |
| 12 | public class MessageListCellRenderer extends DefaultListCellRenderer { | 12 | public class MessageListCellRenderer extends DefaultListCellRenderer { |
| 13 | |||
| 14 | @Override | 13 | @Override |
| 15 | public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { | 14 | public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
| 16 | super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); | 15 | super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
| 17 | Message message = (Message) value; | 16 | Message message = (Message) value; |
| 17 | |||
| 18 | if (message != null) { | 18 | if (message != null) { |
| 19 | setText(message.translate()); | 19 | setText(message.translate()); |
| 20 | } | 20 | } |
| 21 | |||
| 21 | return this; | 22 | return this; |
| 22 | } | 23 | } |
| 23 | |||
| 24 | } | 24 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/StructureOptionListCellRenderer.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/StructureOptionListCellRenderer.java index f9a1cae..09cdc9b 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/StructureOptionListCellRenderer.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/renderer/StructureOptionListCellRenderer.java | |||
| @@ -1,21 +1,22 @@ | |||
| 1 | package cuchaz.enigma.gui.renderer; | 1 | package cuchaz.enigma.gui.renderer; |
| 2 | 2 | ||
| 3 | import java.awt.Component; | ||
| 4 | |||
| 5 | import javax.swing.DefaultListCellRenderer; | ||
| 6 | import javax.swing.JList; | ||
| 7 | |||
| 3 | import cuchaz.enigma.analysis.StructureTreeOptions; | 8 | import cuchaz.enigma.analysis.StructureTreeOptions; |
| 4 | import cuchaz.enigma.utils.I18n; | 9 | import cuchaz.enigma.utils.I18n; |
| 5 | 10 | ||
| 6 | import javax.swing.*; | ||
| 7 | import java.awt.*; | ||
| 8 | |||
| 9 | public class StructureOptionListCellRenderer extends DefaultListCellRenderer { | 11 | public class StructureOptionListCellRenderer extends DefaultListCellRenderer { |
| 12 | @Override | ||
| 13 | public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { | ||
| 14 | Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); | ||
| 10 | 15 | ||
| 11 | @Override | 16 | if (value instanceof StructureTreeOptions.Option option) { |
| 12 | public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) { | 17 | this.setText(I18n.translate(option.getTranslationKey())); |
| 13 | Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); | 18 | } |
| 14 | |||
| 15 | if (value instanceof StructureTreeOptions.Option option) { | ||
| 16 | this.setText(I18n.translate(option.getTranslationKey())); | ||
| 17 | } | ||
| 18 | 19 | ||
| 19 | return c; | 20 | return c; |
| 20 | } | 21 | } |
| 21 | } | 22 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchEntry.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchEntry.java index 91727c3..93507bc 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchEntry.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchEntry.java | |||
| @@ -3,7 +3,6 @@ package cuchaz.enigma.gui.search; | |||
| 3 | import java.util.List; | 3 | import java.util.List; |
| 4 | 4 | ||
| 5 | public interface SearchEntry { | 5 | public interface SearchEntry { |
| 6 | |||
| 7 | List<String> getSearchableNames(); | 6 | List<String> getSearchableNames(); |
| 8 | 7 | ||
| 9 | /** | 8 | /** |
| @@ -13,5 +12,4 @@ public interface SearchEntry { | |||
| 13 | * @return a unique identifier for this search entry | 12 | * @return a unique identifier for this search entry |
| 14 | */ | 13 | */ |
| 15 | String getIdentifier(); | 14 | String getIdentifier(); |
| 16 | |||
| 17 | } | 15 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java index a3b35fa..c8212ce 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/search/SearchUtil.java | |||
| @@ -1,6 +1,14 @@ | |||
| 1 | package cuchaz.enigma.gui.search; | 1 | package cuchaz.enigma.gui.search; |
| 2 | 2 | ||
| 3 | import java.util.*; | 3 | import java.util.ArrayList; |
| 4 | import java.util.Arrays; | ||
| 5 | import java.util.Collection; | ||
| 6 | import java.util.Collections; | ||
| 7 | import java.util.Comparator; | ||
| 8 | import java.util.HashMap; | ||
| 9 | import java.util.List; | ||
| 10 | import java.util.Locale; | ||
| 11 | import java.util.Map; | ||
| 4 | import java.util.concurrent.Executor; | 12 | import java.util.concurrent.Executor; |
| 5 | import java.util.concurrent.Executors; | 13 | import java.util.concurrent.Executors; |
| 6 | import java.util.concurrent.atomic.AtomicBoolean; | 14 | import java.util.concurrent.atomic.AtomicBoolean; |
| @@ -14,7 +22,6 @@ import java.util.stream.Stream; | |||
| 14 | import cuchaz.enigma.utils.Pair; | 22 | import cuchaz.enigma.utils.Pair; |
| 15 | 23 | ||
| 16 | public class SearchUtil<T extends SearchEntry> { | 24 | public class SearchUtil<T extends SearchEntry> { |
| 17 | |||
| 18 | private final Map<T, Entry<T>> entries = new HashMap<>(); | 25 | private final Map<T, Entry<T>> entries = new HashMap<>(); |
| 19 | private final Map<String, Integer> hitCount = new HashMap<>(); | 26 | private final Map<String, Integer> hitCount = new HashMap<>(); |
| 20 | private final Executor searchExecutor = Executors.newWorkStealingPool(); | 27 | private final Executor searchExecutor = Executors.newWorkStealingPool(); |
| @@ -45,12 +52,7 @@ public class SearchUtil<T extends SearchEntry> { | |||
| 45 | } | 52 | } |
| 46 | 53 | ||
| 47 | public Stream<T> search(String term) { | 54 | public Stream<T> search(String term) { |
| 48 | return entries.values().parallelStream() | 55 | return entries.values().parallelStream().map(e -> new Pair<>(e, e.getScore(term, hitCount.getOrDefault(e.searchEntry.getIdentifier(), 0)))).filter(e -> e.b > 0).sorted(Comparator.comparingDouble(o -> -o.b)).map(e -> e.a.searchEntry).sequential(); |
| 49 | .map(e -> new Pair<>(e, e.getScore(term, hitCount.getOrDefault(e.searchEntry.getIdentifier(), 0)))) | ||
| 50 | .filter(e -> e.b > 0) | ||
| 51 | .sorted(Comparator.comparingDouble(o -> -o.b)) | ||
| 52 | .map(e -> e.a.searchEntry) | ||
| 53 | .sequential(); | ||
| 54 | } | 56 | } |
| 55 | 57 | ||
| 56 | public SearchControl asyncSearch(String term, SearchResultConsumer<T> consumer) { | 58 | public SearchControl asyncSearch(String term, SearchResultConsumer<T> consumer) { |
| @@ -61,21 +63,36 @@ public class SearchUtil<T extends SearchEntry> { | |||
| 61 | AtomicInteger size = new AtomicInteger(); | 63 | AtomicInteger size = new AtomicInteger(); |
| 62 | AtomicBoolean control = new AtomicBoolean(false); | 64 | AtomicBoolean control = new AtomicBoolean(false); |
| 63 | AtomicInteger elapsed = new AtomicInteger(); | 65 | AtomicInteger elapsed = new AtomicInteger(); |
| 66 | |||
| 64 | for (Entry<T> value : entries.values()) { | 67 | for (Entry<T> value : entries.values()) { |
| 65 | searchExecutor.execute(() -> { | 68 | searchExecutor.execute(() -> { |
| 66 | try { | 69 | try { |
| 67 | if (control.get()) return; | 70 | if (control.get()) { |
| 71 | return; | ||
| 72 | } | ||
| 73 | |||
| 68 | float score = value.getScore(term, hitCount.getOrDefault(value.searchEntry.getIdentifier(), 0)); | 74 | float score = value.getScore(term, hitCount.getOrDefault(value.searchEntry.getIdentifier(), 0)); |
| 69 | if (score <= 0) return; | 75 | |
| 76 | if (score <= 0) { | ||
| 77 | return; | ||
| 78 | } | ||
| 79 | |||
| 70 | score = -score; // sort descending | 80 | score = -score; // sort descending |
| 81 | |||
| 71 | try { | 82 | try { |
| 72 | scoresLock.lock(); | 83 | scoresLock.lock(); |
| 73 | if (control.get()) return; | 84 | |
| 85 | if (control.get()) { | ||
| 86 | return; | ||
| 87 | } | ||
| 88 | |||
| 74 | int dataSize = size.getAndIncrement(); | 89 | int dataSize = size.getAndIncrement(); |
| 75 | int index = Arrays.binarySearch(scores, 0, dataSize, score); | 90 | int index = Arrays.binarySearch(scores, 0, dataSize, score); |
| 91 | |||
| 76 | if (index < 0) { | 92 | if (index < 0) { |
| 77 | index = ~index; | 93 | index = ~index; |
| 78 | } | 94 | } |
| 95 | |||
| 79 | System.arraycopy(scores, index, scores, index + 1, dataSize - index); | 96 | System.arraycopy(scores, index, scores, index + 1, dataSize - index); |
| 80 | scores[index] = score; | 97 | scores[index] = score; |
| 81 | consumer.add(index, value.searchEntry); | 98 | consumer.add(index, value.searchEntry); |
| @@ -113,7 +130,6 @@ public class SearchUtil<T extends SearchEntry> { | |||
| 113 | } | 130 | } |
| 114 | 131 | ||
| 115 | public static final class Entry<T extends SearchEntry> { | 132 | public static final class Entry<T extends SearchEntry> { |
| 116 | |||
| 117 | public final T searchEntry; | 133 | public final T searchEntry; |
| 118 | private final String[][] components; | 134 | private final String[][] components; |
| 119 | 135 | ||
| @@ -124,9 +140,7 @@ public class SearchUtil<T extends SearchEntry> { | |||
| 124 | 140 | ||
| 125 | public float getScore(String term, int hits) { | 141 | public float getScore(String term, int hits) { |
| 126 | String ucTerm = term.toUpperCase(Locale.ROOT); | 142 | String ucTerm = term.toUpperCase(Locale.ROOT); |
| 127 | float maxScore = (float) Arrays.stream(components) | 143 | float maxScore = (float) Arrays.stream(components).mapToDouble(name -> getScoreFor(ucTerm, name)).max().orElse(0.0); |
| 128 | .mapToDouble(name -> getScoreFor(ucTerm, name)) | ||
| 129 | .max().orElse(0.0); | ||
| 130 | return maxScore * (hits + 1); | 144 | return maxScore * (hits + 1); |
| 131 | } | 145 | } |
| 132 | 146 | ||
| @@ -156,17 +170,20 @@ public class SearchUtil<T extends SearchEntry> { | |||
| 156 | String component = name[componentIndex]; | 170 | String component = name[componentIndex]; |
| 157 | float posMultiplier = (name.length - componentIndex) * 0.3f; | 171 | float posMultiplier = (name.length - componentIndex) * 0.3f; |
| 158 | Map<String, Float> newSnapshots = new HashMap<>(); | 172 | Map<String, Float> newSnapshots = new HashMap<>(); |
| 173 | |||
| 159 | for (Map.Entry<String, Float> snapshot : snapshots.entrySet()) { | 174 | for (Map.Entry<String, Float> snapshot : snapshots.entrySet()) { |
| 160 | String remaining = snapshot.getKey(); | 175 | String remaining = snapshot.getKey(); |
| 161 | float score = snapshot.getValue(); | 176 | float score = snapshot.getValue(); |
| 162 | component = component.toUpperCase(Locale.ROOT); | 177 | component = component.toUpperCase(Locale.ROOT); |
| 163 | int l = compareEqualLength(remaining, component); | 178 | int l = compareEqualLength(remaining, component); |
| 179 | |||
| 164 | for (int i = 1; i <= l; i++) { | 180 | for (int i = 1; i <= l; i++) { |
| 165 | float baseScore = scorePerChar * i; | 181 | float baseScore = scorePerChar * i; |
| 166 | float chainBonus = (i - 1) * 0.5f; | 182 | float chainBonus = (i - 1) * 0.5f; |
| 167 | merge(newSnapshots, Collections.singletonMap(remaining.substring(i), score + baseScore * posMultiplier + chainBonus), Math::max); | 183 | merge(newSnapshots, Collections.singletonMap(remaining.substring(i), score + baseScore * posMultiplier + chainBonus), Math::max); |
| 168 | } | 184 | } |
| 169 | } | 185 | } |
| 186 | |||
| 170 | merge(snapshots, newSnapshots, Math::max); | 187 | merge(snapshots, newSnapshots, Math::max); |
| 171 | } | 188 | } |
| 172 | 189 | ||
| @@ -180,24 +197,24 @@ public class SearchUtil<T extends SearchEntry> { | |||
| 180 | } | 197 | } |
| 181 | 198 | ||
| 182 | public static <T extends SearchEntry> Entry<T> from(T e) { | 199 | public static <T extends SearchEntry> Entry<T> from(T e) { |
| 183 | String[][] components = e.getSearchableNames().parallelStream() | 200 | String[][] components = e.getSearchableNames().parallelStream().map(Entry::wordwiseSplit).toArray(String[][]::new); |
| 184 | .map(Entry::wordwiseSplit) | ||
| 185 | .toArray(String[][]::new); | ||
| 186 | return new Entry<>(e, components); | 201 | return new Entry<>(e, components); |
| 187 | } | 202 | } |
| 188 | 203 | ||
| 189 | private static int compareEqualLength(String s1, String s2) { | 204 | private static int compareEqualLength(String s1, String s2) { |
| 190 | int len = 0; | 205 | int len = 0; |
| 206 | |||
| 191 | while (len < s1.length() && len < s2.length() && s1.charAt(len) == s2.charAt(len)) { | 207 | while (len < s1.length() && len < s2.length() && s1.charAt(len) == s2.charAt(len)) { |
| 192 | len += 1; | 208 | len += 1; |
| 193 | } | 209 | } |
| 210 | |||
| 194 | return len; | 211 | return len; |
| 195 | } | 212 | } |
| 196 | 213 | ||
| 197 | /** | 214 | /** |
| 198 | * Splits the given input into components, trying to detect word parts. | 215 | * Splits the given input into components, trying to detect word parts. |
| 199 | * <p> | 216 | * |
| 200 | * Example of how words get split (using <code>|</code> as seperator): | 217 | * <p>Example of how words get split (using <code>|</code> as seperator): |
| 201 | * <p><code>MinecraftClientGame -> Minecraft|Client|Game</code></p> | 218 | * <p><code>MinecraftClientGame -> Minecraft|Client|Game</code></p> |
| 202 | * <p><code>HTTPInputStream -> HTTP|Input|Stream</code></p> | 219 | * <p><code>HTTPInputStream -> HTTP|Input|Stream</code></p> |
| 203 | * <p><code>class_932 -> class|_|932</code></p> | 220 | * <p><code>class_932 -> class|_|932</code></p> |
| @@ -210,46 +227,57 @@ public class SearchUtil<T extends SearchEntry> { | |||
| 210 | */ | 227 | */ |
| 211 | private static String[] wordwiseSplit(String input) { | 228 | private static String[] wordwiseSplit(String input) { |
| 212 | List<String> list = new ArrayList<>(); | 229 | List<String> list = new ArrayList<>(); |
| 230 | |||
| 213 | while (!input.isEmpty()) { | 231 | while (!input.isEmpty()) { |
| 214 | int take; | 232 | int take; |
| 233 | |||
| 215 | if (Character.isLetter(input.charAt(0))) { | 234 | if (Character.isLetter(input.charAt(0))) { |
| 216 | if (input.length() == 1) { | 235 | if (input.length() == 1) { |
| 217 | take = 1; | 236 | take = 1; |
| 218 | } else { | 237 | } else { |
| 219 | boolean nextSegmentIsUppercase = Character.isUpperCase(input.charAt(0)) && Character.isUpperCase(input.charAt(1)); | 238 | boolean nextSegmentIsUppercase = Character.isUpperCase(input.charAt(0)) && Character.isUpperCase(input.charAt(1)); |
| 239 | |||
| 220 | if (nextSegmentIsUppercase) { | 240 | if (nextSegmentIsUppercase) { |
| 221 | int nextLowercase = 1; | 241 | int nextLowercase = 1; |
| 242 | |||
| 222 | while (Character.isUpperCase(input.charAt(nextLowercase))) { | 243 | while (Character.isUpperCase(input.charAt(nextLowercase))) { |
| 223 | nextLowercase += 1; | 244 | nextLowercase += 1; |
| 245 | |||
| 224 | if (nextLowercase == input.length()) { | 246 | if (nextLowercase == input.length()) { |
| 225 | nextLowercase += 1; | 247 | nextLowercase += 1; |
| 226 | break; | 248 | break; |
| 227 | } | 249 | } |
| 228 | } | 250 | } |
| 251 | |||
| 229 | take = nextLowercase - 1; | 252 | take = nextLowercase - 1; |
| 230 | } else { | 253 | } else { |
| 231 | int nextUppercase = 1; | 254 | int nextUppercase = 1; |
| 255 | |||
| 232 | while (nextUppercase < input.length() && Character.isLowerCase(input.charAt(nextUppercase))) { | 256 | while (nextUppercase < input.length() && Character.isLowerCase(input.charAt(nextUppercase))) { |
| 233 | nextUppercase += 1; | 257 | nextUppercase += 1; |
| 234 | } | 258 | } |
| 259 | |||
| 235 | take = nextUppercase; | 260 | take = nextUppercase; |
| 236 | } | 261 | } |
| 237 | } | 262 | } |
| 238 | } else if (Character.isDigit(input.charAt(0))) { | 263 | } else if (Character.isDigit(input.charAt(0))) { |
| 239 | int nextNonNum = 1; | 264 | int nextNonNum = 1; |
| 265 | |||
| 240 | while (nextNonNum < input.length() && Character.isLetter(input.charAt(nextNonNum)) && !Character.isLowerCase(input.charAt(nextNonNum))) { | 266 | while (nextNonNum < input.length() && Character.isLetter(input.charAt(nextNonNum)) && !Character.isLowerCase(input.charAt(nextNonNum))) { |
| 241 | nextNonNum += 1; | 267 | nextNonNum += 1; |
| 242 | } | 268 | } |
| 269 | |||
| 243 | take = nextNonNum; | 270 | take = nextNonNum; |
| 244 | } else { | 271 | } else { |
| 245 | take = 1; | 272 | take = 1; |
| 246 | } | 273 | } |
| 274 | |||
| 247 | list.add(input.substring(0, take)); | 275 | list.add(input.substring(0, take)); |
| 248 | input = input.substring(take); | 276 | input = input.substring(take); |
| 249 | } | 277 | } |
| 278 | |||
| 250 | return list.toArray(new String[0]); | 279 | return list.toArray(new String[0]); |
| 251 | } | 280 | } |
| 252 | |||
| 253 | } | 281 | } |
| 254 | 282 | ||
| 255 | @FunctionalInterface | 283 | @FunctionalInterface |
| @@ -264,5 +292,4 @@ public class SearchUtil<T extends SearchEntry> { | |||
| 264 | 292 | ||
| 265 | float getProgress(); | 293 | float getProgress(); |
| 266 | } | 294 | } |
| 267 | |||
| 268 | } | 295 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java index 20d6a0e..99b5572 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsGenerator.java | |||
| @@ -1,5 +1,10 @@ | |||
| 1 | package cuchaz.enigma.gui.stats; | 1 | package cuchaz.enigma.gui.stats; |
| 2 | 2 | ||
| 3 | import java.util.EnumSet; | ||
| 4 | import java.util.HashMap; | ||
| 5 | import java.util.Map; | ||
| 6 | import java.util.Set; | ||
| 7 | |||
| 3 | import cuchaz.enigma.EnigmaProject; | 8 | import cuchaz.enigma.EnigmaProject; |
| 4 | import cuchaz.enigma.ProgressListener; | 9 | import cuchaz.enigma.ProgressListener; |
| 5 | import cuchaz.enigma.analysis.index.EntryIndex; | 10 | import cuchaz.enigma.analysis.index.EntryIndex; |
| @@ -7,109 +12,112 @@ import cuchaz.enigma.translation.mapping.EntryRemapper; | |||
| 7 | import cuchaz.enigma.translation.mapping.EntryResolver; | 12 | import cuchaz.enigma.translation.mapping.EntryResolver; |
| 8 | import cuchaz.enigma.translation.mapping.ResolutionStrategy; | 13 | import cuchaz.enigma.translation.mapping.ResolutionStrategy; |
| 9 | import cuchaz.enigma.translation.representation.TypeDescriptor; | 14 | import cuchaz.enigma.translation.representation.TypeDescriptor; |
| 10 | import cuchaz.enigma.translation.representation.entry.*; | 15 | import cuchaz.enigma.translation.representation.entry.ClassEntry; |
| 16 | import cuchaz.enigma.translation.representation.entry.Entry; | ||
| 17 | import cuchaz.enigma.translation.representation.entry.FieldDefEntry; | ||
| 18 | import cuchaz.enigma.translation.representation.entry.FieldEntry; | ||
| 19 | import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; | ||
| 20 | import cuchaz.enigma.translation.representation.entry.MethodDefEntry; | ||
| 21 | import cuchaz.enigma.translation.representation.entry.MethodEntry; | ||
| 11 | import cuchaz.enigma.utils.I18n; | 22 | import cuchaz.enigma.utils.I18n; |
| 12 | 23 | ||
| 13 | import java.util.*; | ||
| 14 | |||
| 15 | public class StatsGenerator { | 24 | public class StatsGenerator { |
| 16 | private final EnigmaProject project; | 25 | private final EnigmaProject project; |
| 17 | private final EntryIndex entryIndex; | 26 | private final EntryIndex entryIndex; |
| 18 | private final EntryRemapper mapper; | 27 | private final EntryRemapper mapper; |
| 19 | private final EntryResolver entryResolver; | 28 | private final EntryResolver entryResolver; |
| 20 | 29 | ||
| 21 | public StatsGenerator(EnigmaProject project) { | 30 | public StatsGenerator(EnigmaProject project) { |
| 22 | this.project = project; | 31 | this.project = project; |
| 23 | this.entryIndex = project.getJarIndex().getEntryIndex(); | 32 | this.entryIndex = project.getJarIndex().getEntryIndex(); |
| 24 | this.mapper = project.getMapper(); | 33 | this.mapper = project.getMapper(); |
| 25 | this.entryResolver = project.getJarIndex().getEntryResolver(); | 34 | this.entryResolver = project.getJarIndex().getEntryResolver(); |
| 26 | } | 35 | } |
| 27 | 36 | ||
| 28 | public StatsResult generate(ProgressListener progress, Set<StatsMember> includedMembers, String topLevelPackage, boolean includeSynthetic) { | 37 | public StatsResult generate(ProgressListener progress, Set<StatsMember> includedMembers, String topLevelPackage, boolean includeSynthetic) { |
| 29 | includedMembers = EnumSet.copyOf(includedMembers); | 38 | includedMembers = EnumSet.copyOf(includedMembers); |
| 30 | int totalWork = 0; | 39 | int totalWork = 0; |
| 31 | int totalMappable = 0; | 40 | int totalMappable = 0; |
| 32 | 41 | ||
| 33 | if (includedMembers.contains(StatsMember.METHODS) || includedMembers.contains(StatsMember.PARAMETERS)) { | 42 | if (includedMembers.contains(StatsMember.METHODS) || includedMembers.contains(StatsMember.PARAMETERS)) { |
| 34 | totalWork += entryIndex.getMethods().size(); | 43 | totalWork += entryIndex.getMethods().size(); |
| 35 | } | 44 | } |
| 36 | 45 | ||
| 37 | if (includedMembers.contains(StatsMember.FIELDS)) { | 46 | if (includedMembers.contains(StatsMember.FIELDS)) { |
| 38 | totalWork += entryIndex.getFields().size(); | 47 | totalWork += entryIndex.getFields().size(); |
| 39 | } | 48 | } |
| 40 | 49 | ||
| 41 | if (includedMembers.contains(StatsMember.CLASSES)) { | 50 | if (includedMembers.contains(StatsMember.CLASSES)) { |
| 42 | totalWork += entryIndex.getClasses().size(); | 51 | totalWork += entryIndex.getClasses().size(); |
| 43 | } | 52 | } |
| 44 | 53 | ||
| 45 | progress.init(totalWork, I18n.translate("progress.stats")); | 54 | progress.init(totalWork, I18n.translate("progress.stats")); |
| 46 | 55 | ||
| 47 | Map<String, Integer> counts = new HashMap<>(); | 56 | Map<String, Integer> counts = new HashMap<>(); |
| 48 | 57 | ||
| 49 | int numDone = 0; | 58 | int numDone = 0; |
| 50 | if (includedMembers.contains(StatsMember.METHODS) || includedMembers.contains(StatsMember.PARAMETERS)) { | 59 | |
| 51 | for (MethodEntry method : entryIndex.getMethods()) { | 60 | if (includedMembers.contains(StatsMember.METHODS) || includedMembers.contains(StatsMember.PARAMETERS)) { |
| 52 | progress.step(numDone++, I18n.translate("type.methods")); | 61 | for (MethodEntry method : entryIndex.getMethods()) { |
| 53 | MethodEntry root = entryResolver | 62 | progress.step(numDone++, I18n.translate("type.methods")); |
| 54 | .resolveEntry(method, ResolutionStrategy.RESOLVE_ROOT) | 63 | MethodEntry root = entryResolver.resolveEntry(method, ResolutionStrategy.RESOLVE_ROOT).stream().findFirst().orElseThrow(AssertionError::new); |
| 55 | .stream() | 64 | |
| 56 | .findFirst() | 65 | if (root == method) { |
| 57 | .orElseThrow(AssertionError::new); | 66 | if (includedMembers.contains(StatsMember.METHODS) && !((MethodDefEntry) method).getAccess().isSynthetic()) { |
| 58 | 67 | update(counts, method); | |
| 59 | if (root == method) { | 68 | totalMappable++; |
| 60 | if (includedMembers.contains(StatsMember.METHODS) && !((MethodDefEntry) method).getAccess().isSynthetic()) { | 69 | } |
| 61 | update(counts, method); | 70 | |
| 62 | totalMappable ++; | 71 | if (includedMembers.contains(StatsMember.PARAMETERS) && (!((MethodDefEntry) method).getAccess().isSynthetic() || includeSynthetic)) { |
| 63 | } | 72 | int index = ((MethodDefEntry) method).getAccess().isStatic() ? 0 : 1; |
| 64 | 73 | ||
| 65 | if (includedMembers.contains(StatsMember.PARAMETERS) && (!((MethodDefEntry) method).getAccess().isSynthetic() || includeSynthetic)) { | 74 | for (TypeDescriptor argument : method.getDesc().getArgumentDescs()) { |
| 66 | int index = ((MethodDefEntry) method).getAccess().isStatic() ? 0 : 1; | 75 | update(counts, new LocalVariableEntry(method, index, "", true, null)); |
| 67 | for (TypeDescriptor argument : method.getDesc().getArgumentDescs()) { | 76 | index += argument.getSize(); |
| 68 | update(counts, new LocalVariableEntry(method, index, "", true,null)); | 77 | totalMappable++; |
| 69 | index += argument.getSize(); | 78 | } |
| 70 | totalMappable ++; | 79 | } |
| 71 | } | 80 | } |
| 72 | } | 81 | } |
| 73 | } | 82 | } |
| 74 | } | 83 | |
| 75 | } | 84 | if (includedMembers.contains(StatsMember.FIELDS)) { |
| 76 | 85 | for (FieldEntry field : entryIndex.getFields()) { | |
| 77 | if (includedMembers.contains(StatsMember.FIELDS)) { | 86 | progress.step(numDone++, I18n.translate("type.fields")); |
| 78 | for (FieldEntry field : entryIndex.getFields()) { | 87 | |
| 79 | progress.step(numDone++, I18n.translate("type.fields")); | 88 | if (!((FieldDefEntry) field).getAccess().isSynthetic()) { |
| 80 | if (!((FieldDefEntry)field).getAccess().isSynthetic()) { | 89 | update(counts, field); |
| 81 | update(counts, field); | 90 | totalMappable++; |
| 82 | totalMappable ++; | 91 | } |
| 83 | } | 92 | } |
| 84 | } | 93 | } |
| 85 | } | 94 | |
| 86 | 95 | if (includedMembers.contains(StatsMember.CLASSES)) { | |
| 87 | if (includedMembers.contains(StatsMember.CLASSES)) { | 96 | for (ClassEntry clazz : entryIndex.getClasses()) { |
| 88 | for (ClassEntry clazz : entryIndex.getClasses()) { | 97 | progress.step(numDone++, I18n.translate("type.classes")); |
| 89 | progress.step(numDone++, I18n.translate("type.classes")); | 98 | update(counts, clazz); |
| 90 | update(counts, clazz); | 99 | totalMappable++; |
| 91 | totalMappable ++; | 100 | } |
| 92 | } | 101 | } |
| 93 | } | 102 | |
| 94 | 103 | progress.step(-1, I18n.translate("progress.stats.data")); | |
| 95 | progress.step(-1, I18n.translate("progress.stats.data")); | 104 | |
| 96 | 105 | StatsResult.Tree<Integer> tree = new StatsResult.Tree<>(); | |
| 97 | StatsResult.Tree<Integer> tree = new StatsResult.Tree<>(); | 106 | |
| 98 | 107 | for (Map.Entry<String, Integer> entry : counts.entrySet()) { | |
| 99 | for (Map.Entry<String, Integer> entry : counts.entrySet()) { | 108 | if (entry.getKey().startsWith(topLevelPackage)) { |
| 100 | if (entry.getKey().startsWith(topLevelPackage)) { | 109 | tree.getNode(entry.getKey()).value = entry.getValue(); |
| 101 | tree.getNode(entry.getKey()).value = entry.getValue(); | 110 | } |
| 102 | } | 111 | } |
| 103 | } | 112 | |
| 104 | 113 | tree.collapse(tree.root); | |
| 105 | tree.collapse(tree.root); | 114 | return new StatsResult(totalMappable, counts.values().stream().mapToInt(i -> i).sum(), tree); |
| 106 | return new StatsResult(totalMappable, counts.values().stream().mapToInt(i -> i).sum(), tree); | 115 | } |
| 107 | } | 116 | |
| 108 | 117 | private void update(Map<String, Integer> counts, Entry<?> entry) { | |
| 109 | private void update(Map<String, Integer> counts, Entry<?> entry) { | 118 | if (project.isObfuscated(entry)) { |
| 110 | if (project.isObfuscated(entry)) { | 119 | String parent = mapper.deobfuscate(entry.getAncestry().get(0)).getName().replace('/', '.'); |
| 111 | String parent = mapper.deobfuscate(entry.getAncestry().get(0)).getName().replace('/', '.'); | 120 | counts.put(parent, counts.getOrDefault(parent, 0) + 1); |
| 112 | counts.put(parent, counts.getOrDefault(parent, 0) + 1); | 121 | } |
| 113 | } | 122 | } |
| 114 | } | ||
| 115 | } | 123 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsMember.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsMember.java index 0e2452f..0037ab5 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsMember.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsMember.java | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | package cuchaz.enigma.gui.stats; | 1 | package cuchaz.enigma.gui.stats; |
| 2 | 2 | ||
| 3 | public enum StatsMember { | 3 | public enum StatsMember { |
| 4 | CLASSES, | 4 | CLASSES, |
| 5 | METHODS, | 5 | METHODS, |
| 6 | FIELDS, | 6 | FIELDS, |
| 7 | PARAMETERS | 7 | PARAMETERS |
| 8 | } | 8 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsResult.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsResult.java index 0a71a64..12726c0 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsResult.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/stats/StatsResult.java | |||
| @@ -1,14 +1,13 @@ | |||
| 1 | package cuchaz.enigma.gui.stats; | 1 | package cuchaz.enigma.gui.stats; |
| 2 | 2 | ||
| 3 | import com.google.gson.GsonBuilder; | ||
| 4 | |||
| 5 | import java.util.ArrayList; | 3 | import java.util.ArrayList; |
| 6 | import java.util.HashMap; | 4 | import java.util.HashMap; |
| 7 | import java.util.List; | 5 | import java.util.List; |
| 8 | import java.util.Map; | 6 | import java.util.Map; |
| 9 | 7 | ||
| 10 | public final class StatsResult { | 8 | import com.google.gson.GsonBuilder; |
| 11 | 9 | ||
| 10 | public final class StatsResult { | ||
| 12 | private final int total; | 11 | private final int total; |
| 13 | private final int unmapped; | 12 | private final int unmapped; |
| 14 | private final Tree<Integer> tree; | 13 | private final Tree<Integer> tree; |
| @@ -101,5 +100,4 @@ public final class StatsResult { | |||
| 101 | } | 100 | } |
| 102 | } | 101 | } |
| 103 | } | 102 | } |
| 104 | |||
| 105 | } | 103 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/AbstractListCellRenderer.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/AbstractListCellRenderer.java index 612e3e9..f8ce36d 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/AbstractListCellRenderer.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/AbstractListCellRenderer.java | |||
| @@ -3,11 +3,16 @@ package cuchaz.enigma.gui.util; | |||
| 3 | import java.awt.Component; | 3 | import java.awt.Component; |
| 4 | import java.awt.event.MouseEvent; | 4 | import java.awt.event.MouseEvent; |
| 5 | 5 | ||
| 6 | import javax.swing.*; | 6 | import javax.swing.BorderFactory; |
| 7 | import javax.swing.JComponent; | ||
| 8 | import javax.swing.JList; | ||
| 9 | import javax.swing.JPanel; | ||
| 10 | import javax.swing.ListCellRenderer; | ||
| 11 | import javax.swing.UIDefaults; | ||
| 12 | import javax.swing.UIManager; | ||
| 7 | import javax.swing.border.Border; | 13 | import javax.swing.border.Border; |
| 8 | 14 | ||
| 9 | public abstract class AbstractListCellRenderer<E> extends JPanel implements ListCellRenderer<E> { | 15 | public abstract class AbstractListCellRenderer<E> extends JPanel implements ListCellRenderer<E> { |
| 10 | |||
| 11 | private static final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1); | 16 | private static final Border NO_FOCUS_BORDER = BorderFactory.createEmptyBorder(1, 1, 1, 1); |
| 12 | 17 | ||
| 13 | private Border noFocusBorder; | 18 | private Border noFocusBorder; |
| @@ -21,22 +26,27 @@ public abstract class AbstractListCellRenderer<E> extends JPanel implements List | |||
| 21 | Border border = UIManager.getLookAndFeel().getDefaults().getBorder("List.List.cellNoFocusBorder"); | 26 | Border border = UIManager.getLookAndFeel().getDefaults().getBorder("List.List.cellNoFocusBorder"); |
| 22 | noFocusBorder = border != null ? border : NO_FOCUS_BORDER; | 27 | noFocusBorder = border != null ? border : NO_FOCUS_BORDER; |
| 23 | } | 28 | } |
| 29 | |||
| 24 | return noFocusBorder; | 30 | return noFocusBorder; |
| 25 | } | 31 | } |
| 26 | 32 | ||
| 27 | protected Border getBorder(boolean isSelected, boolean cellHasFocus) { | 33 | protected Border getBorder(boolean isSelected, boolean cellHasFocus) { |
| 28 | Border b = null; | 34 | Border b = null; |
| 35 | |||
| 29 | if (cellHasFocus) { | 36 | if (cellHasFocus) { |
| 30 | UIDefaults defaults = UIManager.getLookAndFeel().getDefaults(); | 37 | UIDefaults defaults = UIManager.getLookAndFeel().getDefaults(); |
| 38 | |||
| 31 | if (isSelected) { | 39 | if (isSelected) { |
| 32 | b = defaults.getBorder("List.focusSelectedCellHighlightBorder"); | 40 | b = defaults.getBorder("List.focusSelectedCellHighlightBorder"); |
| 33 | } | 41 | } |
| 42 | |||
| 34 | if (b == null) { | 43 | if (b == null) { |
| 35 | b = defaults.getBorder("List.focusCellHighlightBorder"); | 44 | b = defaults.getBorder("List.focusCellHighlightBorder"); |
| 36 | } | 45 | } |
| 37 | } else { | 46 | } else { |
| 38 | b = getNoFocusBorder(); | 47 | b = getNoFocusBorder(); |
| 39 | } | 48 | } |
| 49 | |||
| 40 | return b; | 50 | return b; |
| 41 | } | 51 | } |
| 42 | 52 | ||
| @@ -68,10 +78,11 @@ public abstract class AbstractListCellRenderer<E> extends JPanel implements List | |||
| 68 | @Override | 78 | @Override |
| 69 | public String getToolTipText(MouseEvent event) { | 79 | public String getToolTipText(MouseEvent event) { |
| 70 | Component c = getComponentAt(event.getPoint()); | 80 | Component c = getComponentAt(event.getPoint()); |
| 81 | |||
| 71 | if (c instanceof JComponent) { | 82 | if (c instanceof JComponent) { |
| 72 | return ((JComponent) c).getToolTipText(); | 83 | return ((JComponent) c).getToolTipText(); |
| 73 | } | 84 | } |
| 85 | |||
| 74 | return getToolTipText(); | 86 | return getToolTipText(); |
| 75 | } | 87 | } |
| 76 | |||
| 77 | } | 88 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GridBagConstraintsBuilder.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GridBagConstraintsBuilder.java index 6a75686..2d8aa73 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GridBagConstraintsBuilder.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GridBagConstraintsBuilder.java | |||
| @@ -3,7 +3,6 @@ package cuchaz.enigma.gui.util; | |||
| 3 | import java.awt.GridBagConstraints; | 3 | import java.awt.GridBagConstraints; |
| 4 | 4 | ||
| 5 | public final class GridBagConstraintsBuilder { | 5 | public final class GridBagConstraintsBuilder { |
| 6 | |||
| 7 | private final GridBagConstraints inner; | 6 | private final GridBagConstraints inner; |
| 8 | 7 | ||
| 9 | private GridBagConstraintsBuilder(GridBagConstraints inner) { | 8 | private GridBagConstraintsBuilder(GridBagConstraints inner) { |
| @@ -136,5 +135,4 @@ public final class GridBagConstraintsBuilder { | |||
| 136 | public GridBagConstraints build() { | 135 | public GridBagConstraints build() { |
| 137 | return (GridBagConstraints) this.inner.clone(); | 136 | return (GridBagConstraints) this.inner.clone(); |
| 138 | } | 137 | } |
| 139 | |||
| 140 | } | 138 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java index 3b8ecbc..d078424 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/GuiUtil.java | |||
| @@ -1,8 +1,17 @@ | |||
| 1 | package cuchaz.enigma.gui.util; | 1 | package cuchaz.enigma.gui.util; |
| 2 | 2 | ||
| 3 | import java.awt.*; | 3 | import java.awt.Color; |
| 4 | import java.awt.Cursor; | ||
| 5 | import java.awt.Desktop; | ||
| 6 | import java.awt.Font; | ||
| 7 | import java.awt.Toolkit; | ||
| 4 | import java.awt.datatransfer.StringSelection; | 8 | import java.awt.datatransfer.StringSelection; |
| 5 | import java.awt.event.*; | 9 | import java.awt.event.MouseAdapter; |
| 10 | import java.awt.event.MouseEvent; | ||
| 11 | import java.awt.event.MouseListener; | ||
| 12 | import java.awt.event.WindowAdapter; | ||
| 13 | import java.awt.event.WindowEvent; | ||
| 14 | import java.awt.event.WindowListener; | ||
| 6 | import java.awt.font.TextAttribute; | 15 | import java.awt.font.TextAttribute; |
| 7 | import java.io.IOException; | 16 | import java.io.IOException; |
| 8 | import java.net.URI; | 17 | import java.net.URI; |
| @@ -13,7 +22,14 @@ import java.util.Map; | |||
| 13 | import java.util.NoSuchElementException; | 22 | import java.util.NoSuchElementException; |
| 14 | import java.util.function.Consumer; | 23 | import java.util.function.Consumer; |
| 15 | 24 | ||
| 16 | import javax.swing.*; | 25 | import javax.swing.Icon; |
| 26 | import javax.swing.JComponent; | ||
| 27 | import javax.swing.JLabel; | ||
| 28 | import javax.swing.JToolTip; | ||
| 29 | import javax.swing.Popup; | ||
| 30 | import javax.swing.PopupFactory; | ||
| 31 | import javax.swing.Timer; | ||
| 32 | import javax.swing.ToolTipManager; | ||
| 17 | import javax.swing.tree.TreeNode; | 33 | import javax.swing.tree.TreeNode; |
| 18 | import javax.swing.tree.TreePath; | 34 | import javax.swing.tree.TreePath; |
| 19 | 35 | ||
| @@ -28,160 +44,160 @@ import cuchaz.enigma.translation.representation.entry.MethodEntry; | |||
| 28 | import cuchaz.enigma.utils.Os; | 44 | import cuchaz.enigma.utils.Os; |
| 29 | 45 | ||
| 30 | public class GuiUtil { | 46 | public class GuiUtil { |
| 31 | public static final Icon CLASS_ICON = loadIcon("class"); | 47 | public static final Icon CLASS_ICON = loadIcon("class"); |
| 32 | public static final Icon INTERFACE_ICON = loadIcon("interface"); | 48 | public static final Icon INTERFACE_ICON = loadIcon("interface"); |
| 33 | public static final Icon ENUM_ICON = loadIcon("enum"); | 49 | public static final Icon ENUM_ICON = loadIcon("enum"); |
| 34 | public static final Icon ANNOTATION_ICON = loadIcon("annotation"); | 50 | public static final Icon ANNOTATION_ICON = loadIcon("annotation"); |
| 35 | public static final Icon RECORD_ICON = loadIcon("record"); | 51 | public static final Icon RECORD_ICON = loadIcon("record"); |
| 36 | public static final Icon METHOD_ICON = loadIcon("method"); | 52 | public static final Icon METHOD_ICON = loadIcon("method"); |
| 37 | public static final Icon FIELD_ICON = loadIcon("field"); | 53 | public static final Icon FIELD_ICON = loadIcon("field"); |
| 38 | public static final Icon CONSTRUCTOR_ICON = loadIcon("constructor"); | 54 | public static final Icon CONSTRUCTOR_ICON = loadIcon("constructor"); |
| 39 | 55 | ||
| 40 | public static void openUrl(String url) { | 56 | public static void openUrl(String url) { |
| 41 | try { | 57 | try { |
| 42 | switch (Os.getOs()) { | 58 | switch (Os.getOs()) { |
| 43 | case LINUX: | 59 | case LINUX: |
| 44 | new ProcessBuilder("/usr/bin/env", "xdg-open", url).start(); | 60 | new ProcessBuilder("/usr/bin/env", "xdg-open", url).start(); |
| 45 | break; | 61 | break; |
| 46 | default: | 62 | default: |
| 47 | if (Desktop.isDesktopSupported()) { | 63 | if (Desktop.isDesktopSupported()) { |
| 48 | Desktop desktop = Desktop.getDesktop(); | 64 | Desktop desktop = Desktop.getDesktop(); |
| 49 | desktop.browse(new URI(url)); | 65 | desktop.browse(new URI(url)); |
| 50 | } | 66 | } |
| 51 | } | 67 | } |
| 52 | } catch (IOException ex) { | 68 | } catch (IOException ex) { |
| 53 | throw new RuntimeException(ex); | 69 | throw new RuntimeException(ex); |
| 54 | } catch (URISyntaxException ex) { | 70 | } catch (URISyntaxException ex) { |
| 55 | throw new IllegalArgumentException(ex); | 71 | throw new IllegalArgumentException(ex); |
| 56 | } | 72 | } |
| 57 | } | 73 | } |
| 58 | 74 | ||
| 59 | public static JLabel unboldLabel(JLabel label) { | 75 | public static JLabel unboldLabel(JLabel label) { |
| 60 | Font font = label.getFont(); | 76 | Font font = label.getFont(); |
| 61 | label.setFont(font.deriveFont(font.getStyle() & ~Font.BOLD)); | 77 | label.setFont(font.deriveFont(font.getStyle() & ~Font.BOLD)); |
| 62 | return label; | 78 | return label; |
| 63 | } | 79 | } |
| 64 | 80 | ||
| 65 | /** | 81 | /** |
| 66 | * Puts the provided {@code text} in the system clipboard. | 82 | * Puts the provided {@code text} in the system clipboard. |
| 67 | */ | 83 | */ |
| 68 | public static void copyToClipboard(String text) { | 84 | public static void copyToClipboard(String text) { |
| 69 | Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null); | 85 | Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(text), null); |
| 70 | } | 86 | } |
| 71 | 87 | ||
| 72 | public static void showPopup(JComponent component, String text, int x, int y) { | 88 | public static void showPopup(JComponent component, String text, int x, int y) { |
| 73 | // from https://stackoverflow.com/questions/39955015/java-swing-show-tooltip-as-a-message-dialog | 89 | // from https://stackoverflow.com/questions/39955015/java-swing-show-tooltip-as-a-message-dialog |
| 74 | JToolTip tooltip = new JToolTip(); | 90 | JToolTip tooltip = new JToolTip(); |
| 75 | tooltip.setTipText(text); | 91 | tooltip.setTipText(text); |
| 76 | Popup p = PopupFactory.getSharedInstance().getPopup(component, tooltip, x + 10, y); | 92 | Popup p = PopupFactory.getSharedInstance().getPopup(component, tooltip, x + 10, y); |
| 77 | p.show(); | 93 | p.show(); |
| 78 | Timer t = new Timer(1000, e -> p.hide()); | 94 | Timer t = new Timer(1000, e -> p.hide()); |
| 79 | t.setRepeats(false); | 95 | t.setRepeats(false); |
| 80 | t.start(); | 96 | t.start(); |
| 81 | } | 97 | } |
| 82 | 98 | ||
| 83 | public static void showToolTipNow(JComponent component) { | 99 | public static void showToolTipNow(JComponent component) { |
| 84 | // HACKHACK: trick the tooltip manager into showing the tooltip right now | 100 | // HACKHACK: trick the tooltip manager into showing the tooltip right now |
| 85 | ToolTipManager manager = ToolTipManager.sharedInstance(); | 101 | ToolTipManager manager = ToolTipManager.sharedInstance(); |
| 86 | int oldDelay = manager.getInitialDelay(); | 102 | int oldDelay = manager.getInitialDelay(); |
| 87 | manager.setInitialDelay(0); | 103 | manager.setInitialDelay(0); |
| 88 | manager.mouseMoved(new MouseEvent(component, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 0, 0, 0, 0, false)); | 104 | manager.mouseMoved(new MouseEvent(component, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), 0, 0, 0, 0, false)); |
| 89 | manager.setInitialDelay(oldDelay); | 105 | manager.setInitialDelay(oldDelay); |
| 90 | } | 106 | } |
| 91 | 107 | ||
| 92 | public static JLabel createLink(String text, Runnable action) { | 108 | public static JLabel createLink(String text, Runnable action) { |
| 93 | JLabel link = new JLabel(text); | 109 | JLabel link = new JLabel(text); |
| 94 | link.setForeground(Color.BLUE.darker()); | 110 | link.setForeground(Color.BLUE.darker()); |
| 95 | link.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); | 111 | link.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); |
| 96 | @SuppressWarnings("unchecked") | 112 | @SuppressWarnings("unchecked") Map<TextAttribute, Object> attributes = (Map<TextAttribute, Object>) link.getFont().getAttributes(); |
| 97 | Map<TextAttribute, Object> attributes = (Map<TextAttribute, Object>) link.getFont().getAttributes(); | 113 | attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); |
| 98 | attributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); | 114 | link.setFont(link.getFont().deriveFont(attributes)); |
| 99 | link.setFont(link.getFont().deriveFont(attributes)); | 115 | link.addMouseListener(new MouseAdapter() { |
| 100 | link.addMouseListener(new MouseAdapter() { | 116 | @Override |
| 101 | @Override | 117 | public void mousePressed(MouseEvent e) { |
| 102 | public void mousePressed(MouseEvent e) { | 118 | action.run(); |
| 103 | action.run(); | 119 | } |
| 104 | } | 120 | }); |
| 105 | }); | 121 | return link; |
| 106 | return link; | 122 | } |
| 107 | } | 123 | |
| 108 | 124 | public static Icon loadIcon(String name) { | |
| 109 | public static Icon loadIcon(String name) { | 125 | String path = "icons/" + name + ".svg"; |
| 110 | String path = "icons/" + name + ".svg"; | 126 | |
| 111 | 127 | // Do an eager check for a missing icon since FlatSVGIcon does it later at render time | |
| 112 | // Do an eager check for a missing icon since FlatSVGIcon does it later at render time | 128 | if (GuiUtil.class.getResource('/' + path) == null) { |
| 113 | if (GuiUtil.class.getResource('/' + path) == null) { | 129 | throw new NoSuchElementException("Missing icon: '" + name + "' at " + path); |
| 114 | throw new NoSuchElementException("Missing icon: '" + name + "' at " + path); | 130 | } |
| 115 | } | 131 | |
| 116 | 132 | // Note: the width and height are scaled automatically because the FlatLaf UI scale | |
| 117 | // Note: the width and height are scaled automatically because the FlatLaf UI scale | 133 | // is set in LookAndFeel.setGlobalLAF() |
| 118 | // is set in LookAndFeel.setGlobalLAF() | 134 | return new FlatSVGIcon(path, 16, 16, GuiUtil.class.getClassLoader()); |
| 119 | return new FlatSVGIcon(path, 16, 16, GuiUtil.class.getClassLoader()); | 135 | } |
| 120 | } | 136 | |
| 121 | 137 | public static Icon getClassIcon(Gui gui, ClassEntry entry) { | |
| 122 | public static Icon getClassIcon(Gui gui, ClassEntry entry) { | 138 | EntryIndex entryIndex = gui.getController().project.getJarIndex().getEntryIndex(); |
| 123 | EntryIndex entryIndex = gui.getController().project.getJarIndex().getEntryIndex(); | 139 | AccessFlags access = entryIndex.getClassAccess(entry); |
| 124 | AccessFlags access = entryIndex.getClassAccess(entry); | 140 | |
| 125 | 141 | if (access != null) { | |
| 126 | if (access != null) { | 142 | if (access.isAnnotation()) { |
| 127 | if (access.isAnnotation()) { | 143 | return ANNOTATION_ICON; |
| 128 | return ANNOTATION_ICON; | 144 | } else if (access.isInterface()) { |
| 129 | } else if (access.isInterface()) { | 145 | return INTERFACE_ICON; |
| 130 | return INTERFACE_ICON; | 146 | } else if (access.isEnum()) { |
| 131 | } else if (access.isEnum()) { | 147 | return ENUM_ICON; |
| 132 | return ENUM_ICON; | 148 | } else if (entryIndex.getDefinition(entry).isRecord()) { |
| 133 | } else if (entryIndex.getDefinition(entry).isRecord()) { | 149 | return RECORD_ICON; |
| 134 | return RECORD_ICON; | 150 | } |
| 135 | } | 151 | } |
| 136 | } | 152 | |
| 137 | 153 | return CLASS_ICON; | |
| 138 | return CLASS_ICON; | 154 | } |
| 139 | } | 155 | |
| 140 | 156 | public static Icon getMethodIcon(MethodEntry entry) { | |
| 141 | public static Icon getMethodIcon(MethodEntry entry) { | 157 | if (entry.isConstructor()) { |
| 142 | if (entry.isConstructor()) { | 158 | return CONSTRUCTOR_ICON; |
| 143 | return CONSTRUCTOR_ICON; | 159 | } |
| 144 | } | 160 | |
| 145 | return METHOD_ICON; | 161 | return METHOD_ICON; |
| 146 | } | 162 | } |
| 147 | 163 | ||
| 148 | public static TreePath getPathToRoot(TreeNode node) { | 164 | public static TreePath getPathToRoot(TreeNode node) { |
| 149 | List<TreeNode> nodes = Lists.newArrayList(); | 165 | List<TreeNode> nodes = Lists.newArrayList(); |
| 150 | TreeNode n = node; | 166 | TreeNode n = node; |
| 151 | 167 | ||
| 152 | do { | 168 | do { |
| 153 | nodes.add(n); | 169 | nodes.add(n); |
| 154 | n = n.getParent(); | 170 | n = n.getParent(); |
| 155 | } while (n != null); | 171 | } while (n != null); |
| 156 | 172 | ||
| 157 | Collections.reverse(nodes); | 173 | Collections.reverse(nodes); |
| 158 | return new TreePath(nodes.toArray()); | 174 | return new TreePath(nodes.toArray()); |
| 159 | } | 175 | } |
| 160 | 176 | ||
| 161 | public static MouseListener onMouseClick(Consumer<MouseEvent> op) { | 177 | public static MouseListener onMouseClick(Consumer<MouseEvent> op) { |
| 162 | return new MouseAdapter() { | 178 | return new MouseAdapter() { |
| 163 | @Override | 179 | @Override |
| 164 | public void mouseClicked(MouseEvent e) { | 180 | public void mouseClicked(MouseEvent e) { |
| 165 | op.accept(e); | 181 | op.accept(e); |
| 166 | } | 182 | } |
| 167 | }; | 183 | }; |
| 168 | } | 184 | } |
| 169 | 185 | ||
| 170 | public static MouseListener onMousePress(Consumer<MouseEvent> op) { | 186 | public static MouseListener onMousePress(Consumer<MouseEvent> op) { |
| 171 | return new MouseAdapter() { | 187 | return new MouseAdapter() { |
| 172 | @Override | 188 | @Override |
| 173 | public void mousePressed(MouseEvent e) { | 189 | public void mousePressed(MouseEvent e) { |
| 174 | op.accept(e); | 190 | op.accept(e); |
| 175 | } | 191 | } |
| 176 | }; | 192 | }; |
| 177 | } | 193 | } |
| 178 | 194 | ||
| 179 | public static WindowListener onWindowClose(Consumer<WindowEvent> op) { | 195 | public static WindowListener onWindowClose(Consumer<WindowEvent> op) { |
| 180 | return new WindowAdapter() { | 196 | return new WindowAdapter() { |
| 181 | @Override | 197 | @Override |
| 182 | public void windowClosing(WindowEvent e) { | 198 | public void windowClosing(WindowEvent e) { |
| 183 | op.accept(e); | 199 | op.accept(e); |
| 184 | } | 200 | } |
| 185 | }; | 201 | }; |
| 186 | } | 202 | } |
| 187 | } | 203 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/History.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/History.java index b128699..f1a8a7a 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/History.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/History.java | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | package cuchaz.enigma.gui.util; | 1 | package cuchaz.enigma.gui.util; |
| 2 | 2 | ||
| 3 | import com.google.common.collect.Queues; | ||
| 4 | |||
| 5 | import java.util.Deque; | 3 | import java.util.Deque; |
| 6 | 4 | ||
| 5 | import com.google.common.collect.Queues; | ||
| 6 | |||
| 7 | public class History<T> { | 7 | public class History<T> { |
| 8 | private final Deque<T> previous = Queues.newArrayDeque(); | 8 | private final Deque<T> previous = Queues.newArrayDeque(); |
| 9 | private final Deque<T> next = Queues.newArrayDeque(); | 9 | private final Deque<T> next = Queues.newArrayDeque(); |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/LanguageChangeListener.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/LanguageChangeListener.java index 9f53a44..818e112 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/LanguageChangeListener.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/LanguageChangeListener.java | |||
| @@ -1,11 +1,9 @@ | |||
| 1 | package cuchaz.enigma.gui.util; | 1 | package cuchaz.enigma.gui.util; |
| 2 | 2 | ||
| 3 | public interface LanguageChangeListener { | 3 | public interface LanguageChangeListener { |
| 4 | |||
| 5 | void retranslateUi(); | 4 | void retranslateUi(); |
| 6 | 5 | ||
| 7 | default boolean isValid() { | 6 | default boolean isValid() { |
| 8 | return true; | 7 | return true; |
| 9 | } | 8 | } |
| 10 | |||
| 11 | } | 9 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/LanguageUtil.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/LanguageUtil.java index d3e6376..30a9180 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/LanguageUtil.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/LanguageUtil.java | |||
| @@ -4,7 +4,6 @@ import java.util.ArrayList; | |||
| 4 | import java.util.List; | 4 | import java.util.List; |
| 5 | 5 | ||
| 6 | public final class LanguageUtil { | 6 | public final class LanguageUtil { |
| 7 | |||
| 8 | private static final List<LanguageChangeListener> listeners = new ArrayList<>(); | 7 | private static final List<LanguageChangeListener> listeners = new ArrayList<>(); |
| 9 | 8 | ||
| 10 | public LanguageUtil() { | 9 | public LanguageUtil() { |
| @@ -21,5 +20,4 @@ public final class LanguageUtil { | |||
| 21 | public static void dispatchLanguageChange() { | 20 | public static void dispatchLanguageChange() { |
| 22 | listeners.forEach(LanguageChangeListener::retranslateUi); | 21 | listeners.forEach(LanguageChangeListener::retranslateUi); |
| 23 | } | 22 | } |
| 24 | |||
| 25 | } | 23 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/ScaleChangeListener.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/ScaleChangeListener.java index d045c6d..243f26f 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/ScaleChangeListener.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/ScaleChangeListener.java | |||
| @@ -2,7 +2,5 @@ package cuchaz.enigma.gui.util; | |||
| 2 | 2 | ||
| 3 | @FunctionalInterface | 3 | @FunctionalInterface |
| 4 | public interface ScaleChangeListener { | 4 | public interface ScaleChangeListener { |
| 5 | |||
| 6 | void onScaleChanged(float scale, float oldScale); | 5 | void onScaleChanged(float scale, float oldScale); |
| 7 | |||
| 8 | } | 6 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/ScaleUtil.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/ScaleUtil.java index 28e3769..bc587fa 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/ScaleUtil.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/ScaleUtil.java | |||
| @@ -21,7 +21,6 @@ import de.sciss.syntaxpane.DefaultSyntaxKit; | |||
| 21 | import cuchaz.enigma.gui.config.UiConfig; | 21 | import cuchaz.enigma.gui.config.UiConfig; |
| 22 | 22 | ||
| 23 | public class ScaleUtil { | 23 | public class ScaleUtil { |
| 24 | |||
| 25 | private static List<ScaleChangeListener> listeners = new ArrayList<>(); | 24 | private static List<ScaleChangeListener> listeners = new ArrayList<>(); |
| 26 | 25 | ||
| 27 | public static void setScaleFactor(float scaleFactor) { | 26 | public static void setScaleFactor(float scaleFactor) { |
| @@ -110,15 +109,19 @@ public class ScaleUtil { | |||
| 110 | 109 | ||
| 111 | private static BasicTweaker createTweakerForCurrentLook(float dpiScaling) { | 110 | private static BasicTweaker createTweakerForCurrentLook(float dpiScaling) { |
| 112 | String testString = UIManager.getLookAndFeel().getName().toLowerCase(); | 111 | String testString = UIManager.getLookAndFeel().getName().toLowerCase(); |
| 112 | |||
| 113 | if (testString.contains("windows")) { | 113 | if (testString.contains("windows")) { |
| 114 | return new WindowsTweaker(dpiScaling, testString.contains("classic")); | 114 | return new WindowsTweaker(dpiScaling, testString.contains("classic")); |
| 115 | } | 115 | } |
| 116 | |||
| 116 | if (testString.contains("metal")) { | 117 | if (testString.contains("metal")) { |
| 117 | return new MetalTweaker(dpiScaling); | 118 | return new MetalTweaker(dpiScaling); |
| 118 | } | 119 | } |
| 120 | |||
| 119 | if (testString.contains("nimbus")) { | 121 | if (testString.contains("nimbus")) { |
| 120 | return new NimbusTweaker(dpiScaling); | 122 | return new NimbusTweaker(dpiScaling); |
| 121 | } | 123 | } |
| 124 | |||
| 122 | return new BasicTweaker(dpiScaling); | 125 | return new BasicTweaker(dpiScaling); |
| 123 | } | 126 | } |
| 124 | } | 127 | } |
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/SingleTreeSelectionModel.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/SingleTreeSelectionModel.java index 8915264..9d967b8 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/util/SingleTreeSelectionModel.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/util/SingleTreeSelectionModel.java | |||
| @@ -4,8 +4,7 @@ import javax.swing.tree.DefaultTreeSelectionModel; | |||
| 4 | import javax.swing.tree.TreeSelectionModel; | 4 | import javax.swing.tree.TreeSelectionModel; |
| 5 | 5 | ||
| 6 | public class SingleTreeSelectionModel extends DefaultTreeSelectionModel { | 6 | public class SingleTreeSelectionModel extends DefaultTreeSelectionModel { |
| 7 | 7 | public SingleTreeSelectionModel() { | |
| 8 | public SingleTreeSelectionModel() { | 8 | this.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); |
| 9 | this.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); | 9 | } |
| 10 | } | ||
| 11 | } | 10 | } |