1
1
package com .jvms .i18neditor .editor ;
2
2
3
3
import java .awt .BorderLayout ;
4
+ import java .awt .Component ;
4
5
import java .awt .Container ;
5
6
import java .awt .Desktop ;
6
7
import java .awt .Dimension ;
7
8
import java .awt .Image ;
9
+ import java .awt .KeyboardFocusManager ;
8
10
import java .awt .event .KeyAdapter ;
9
11
import java .awt .event .KeyEvent ;
10
12
import java .awt .event .MouseAdapter ;
@@ -102,6 +104,7 @@ public Editor() {
102
104
super ();
103
105
setupUI ();
104
106
setupFileDrop ();
107
+ setupGlobalKeyEventDispatcher ();
105
108
}
106
109
107
110
public void createProject (Path dir , ResourceType type ) {
@@ -372,7 +375,7 @@ public void showRenameTranslationDialog(String key) {
372
375
boolean isReplace = newNode .isLeaf () || oldNode .isLeaf ();
373
376
boolean confirm = Dialogs .showConfirmDialog (this ,
374
377
MessageBundle .get ("dialogs.translation.conflict.title" ),
375
- MessageBundle .get ("dialogs.translation.conflict.text." + (isReplace ? "replace" : "merge" )),
378
+ MessageBundle .get ("dialogs.translation.conflict.text." + (isReplace ? "replace" : "merge" )),
376
379
JOptionPane .WARNING_MESSAGE );
377
380
if (confirm ) {
378
381
renameTranslationKey (key , newKey );
@@ -403,7 +406,7 @@ public void showDuplicateTranslationDialog(String key) {
403
406
boolean isReplace = newNode .isLeaf () || oldNode .isLeaf ();
404
407
boolean confirm = Dialogs .showConfirmDialog (this ,
405
408
MessageBundle .get ("dialogs.translation.conflict.title" ),
406
- MessageBundle .get ("dialogs.translation.conflict.text." + (isReplace ? "replace" : "merge" )),
409
+ MessageBundle .get ("dialogs.translation.conflict.text." + (isReplace ? "replace" : "merge" )),
407
410
JOptionPane .WARNING_MESSAGE );
408
411
if (confirm ) {
409
412
duplicateTranslationKey (key , newKey );
@@ -560,6 +563,47 @@ public void launch() {
560
563
}
561
564
}
562
565
566
+ public void updateUI () {
567
+ TranslationTreeNode selectedNode = translationTree .getSelectedNode ();
568
+
569
+ resourcesPanel .removeAll ();
570
+ resourceFields = resourceFields .stream ().sorted ().collect (Collectors .toList ());
571
+ resourceFields .forEach (field -> {
572
+ Locale locale = field .getResource ().getLocale ();
573
+ String label = locale != null ? locale .getDisplayName () : MessageBundle .get ("resources.locale.default" );
574
+ field .setEnabled (selectedNode != null && selectedNode .isEditable ());
575
+ field .setRows (settings .getInputHeight ());
576
+ resourcesPanel .add (Box .createVerticalStrut (5 ));
577
+ resourcesPanel .add (new JLabel (label ));
578
+ resourcesPanel .add (Box .createVerticalStrut (5 ));
579
+ resourcesPanel .add (field );
580
+ resourcesPanel .add (Box .createVerticalStrut (10 ));
581
+ });
582
+
583
+ Container container = getContentPane ();
584
+ if (project != null ) {
585
+ container .add (contentPane );
586
+ container .remove (introText );
587
+ List <Resource > resources = project .getResources ();
588
+ editorMenu .setEnabled (true );
589
+ editorMenu .setEditable (!resources .isEmpty ());
590
+ translationTree .setEditable (!resources .isEmpty ());
591
+ translationField .setEditable (!resources .isEmpty ());
592
+ } else {
593
+ container .add (introText );
594
+ container .remove (contentPane );
595
+ editorMenu .setEnabled (false );
596
+ editorMenu .setEditable (false );
597
+ translationTree .setEditable (false );
598
+ translationField .setEditable (false );
599
+ }
600
+ translationField .setVisible (settings .isShowKeyField ());
601
+
602
+ updateTitle ();
603
+ validate ();
604
+ repaint ();
605
+ }
606
+
563
607
private void clearUI () {
564
608
translationField .clear ();
565
609
translationTree .clear ();
@@ -584,14 +628,14 @@ private void setupUI() {
584
628
translationField = new TranslationField ();
585
629
translationField .addKeyListener (new TranslationFieldKeyListener ());
586
630
translationField .setBorder (BorderFactory .createCompoundBorder (
587
- BorderFactory .createMatteBorder (1 ,0 ,0 ,1 ,LookAndFeel .TEXTFIELD_BORDER_COLOR ),
631
+ BorderFactory .createMatteBorder (1 ,0 ,0 ,1 ,LookAndFeel .BORDER_COLOR ),
588
632
((CompoundBorder )translationField .getBorder ()).getInsideBorder ()));
589
633
590
634
JScrollPane translationsScrollPane = new JScrollPane (translationTree );
591
635
translationsScrollPane .getViewport ().setOpaque (false );
592
636
translationsScrollPane .setOpaque (false );
593
637
translationsScrollPane .setBorder (
594
- BorderFactory .createMatteBorder (0 ,0 ,0 ,1 ,LookAndFeel .TEXTFIELD_BORDER_COLOR ));
638
+ BorderFactory .createMatteBorder (0 ,0 ,0 ,1 ,LookAndFeel .BORDER_COLOR ));
595
639
596
640
translationsPanel = new JPanel (new BorderLayout ());
597
641
translationsPanel .add (translationsScrollPane );
@@ -654,51 +698,68 @@ public void filesDropped(java.io.File[] files) {
654
698
});
655
699
}
656
700
701
+ private void setupGlobalKeyEventDispatcher () {
702
+ KeyboardFocusManager .getCurrentKeyboardFocusManager ().addKeyEventDispatcher (e -> {
703
+ if (!e .isAltDown () || e .getID () != KeyEvent .KEY_PRESSED ) {
704
+ return false ;
705
+ }
706
+ TreePath selected = translationTree .getSelectionPath ();
707
+ if (selected == null ) {
708
+ return false ;
709
+ }
710
+ boolean result = false ;
711
+ int row = translationTree .getRowForPath (selected );
712
+ switch (e .getKeyCode ()) {
713
+ case KeyEvent .VK_RIGHT :
714
+ if (translationTree .isExpanded (row )) {
715
+ translationTree .setSelectionRow (row +1 );
716
+ } else {
717
+ translationTree .expandRow (row );
718
+ }
719
+ result = true ;
720
+ break ;
721
+ case KeyEvent .VK_LEFT :
722
+ if (translationTree .isCollapsed (row )) {
723
+ translationTree .setSelectionPath (selected .getParentPath ());
724
+ } else {
725
+ translationTree .collapseRow (row );
726
+ }
727
+ result = true ;
728
+ break ;
729
+ case KeyEvent .VK_UP :
730
+ translationTree .setSelectionRow (Math .max (0 , row -1 ));
731
+ result = true ;
732
+ break ;
733
+ case KeyEvent .VK_DOWN :
734
+ TreePath next = translationTree .getPathForRow (row +1 );
735
+ if (next != null ) {
736
+ translationTree .setSelectionPath (next );
737
+ }
738
+ result = true ;
739
+ break ;
740
+ }
741
+ if (result && !resourceFields .isEmpty ()) {
742
+ Component comp = getFocusOwner ();
743
+ if (comp != null && (comp instanceof ResourceField || comp .equals (this ))) {
744
+ TranslationTreeNode current = translationTree .getSelectedNode ();
745
+ if (!current .isLeaf () || current .isRoot ()) {
746
+ requestFocusInWindow ();
747
+ } else if (comp .equals (this )) {
748
+ resourceFields .get (0 ).requestFocusInWindow ();
749
+ }
750
+ }
751
+ }
752
+ return result ;
753
+ });
754
+ }
755
+
657
756
private void setupResource (Resource resource ) {
658
757
resource .addListener (e -> setDirty (true ));
659
758
ResourceField field = new ResourceField (resource );
660
759
field .addKeyListener (new ResourceFieldKeyListener ());
661
760
resourceFields .add (field );
662
761
}
663
762
664
- private void updateUI () {
665
- TranslationTreeNode selectedNode = translationTree .getSelectedNode ();
666
-
667
- resourcesPanel .removeAll ();
668
- resourceFields .stream ().sorted ().forEach (field -> {
669
- Locale locale = field .getResource ().getLocale ();
670
- String label = locale != null ? locale .getDisplayName () : MessageBundle .get ("resources.locale.default" );
671
- field .setEditable (selectedNode != null && selectedNode .isEditable ());
672
- resourcesPanel .add (Box .createVerticalStrut (5 ));
673
- resourcesPanel .add (new JLabel (label ));
674
- resourcesPanel .add (Box .createVerticalStrut (5 ));
675
- resourcesPanel .add (field );
676
- resourcesPanel .add (Box .createVerticalStrut (10 ));
677
- });
678
-
679
- Container container = getContentPane ();
680
- if (project != null ) {
681
- container .add (contentPane );
682
- container .remove (introText );
683
- List <Resource > resources = project .getResources ();
684
- editorMenu .setEnabled (true );
685
- editorMenu .setEditable (!resources .isEmpty ());
686
- translationTree .setEditable (!resources .isEmpty ());
687
- translationField .setEditable (!resources .isEmpty ());
688
- } else {
689
- container .add (introText );
690
- container .remove (contentPane );
691
- editorMenu .setEnabled (false );
692
- editorMenu .setEditable (false );
693
- translationTree .setEditable (false );
694
- translationField .setEditable (false );
695
- }
696
-
697
- updateTitle ();
698
- validate ();
699
- repaint ();
700
- }
701
-
702
763
private void updateHistory () {
703
764
List <String > recentDirs = settings .getHistory ();
704
765
if (project != null ) {
@@ -762,6 +823,8 @@ private void storeEditorState() {
762
823
props .setProperty ("minify_resources" , settings .isMinifyResources ());
763
824
props .setProperty ("resource_name" , settings .getResourceName ());
764
825
props .setProperty ("check_version" , settings .isCheckVersionOnStartup ());
826
+ props .setProperty ("input_height" , settings .getInputHeight ());
827
+ props .setProperty ("key_field" , settings .isShowKeyField ());
765
828
if (!settings .getHistory ().isEmpty ()) {
766
829
props .setProperty ("history" , settings .getHistory ());
767
830
}
@@ -792,6 +855,8 @@ private void restoreEditorState() {
792
855
settings .setMinifyResources (props .getBooleanProperty ("minify_resources" , false ));
793
856
settings .setResourceName (props .getProperty ("resource_name" , DEFAULT_RESOURCE_NAME ));
794
857
settings .setCheckVersionOnStartup (props .getBooleanProperty ("check_version" , true ));
858
+ settings .setInputHeight (props .getIntegerProperty ("input_height" , 5 ));
859
+ settings .setShowKeyField (props .getBooleanProperty ("key_field" , true ));
795
860
}
796
861
797
862
private class TranslationTreeMouseListener extends MouseAdapter {
@@ -836,7 +901,7 @@ public void valueChanged(TreeSelectionEvent e) {
836
901
translationField .setValue (key );
837
902
resourceFields .forEach (f -> {
838
903
f .setValue (key );
839
- f .setEditable (node .isEditable ());
904
+ f .setEnabled (node .isEditable ());
840
905
});
841
906
842
907
// Restore scroll position
0 commit comments