Skip to content

Cannot evaluate because of compilation error(s): Evaluations must contain either an expression or a block of well-formed statements #844

Closed

Description

@noel-yap

While debugging Java, watches emit Cannot evaluate because of compilation error(s): Evaluations must contain either an expression or a block of well-formed statements

Environment
  • Operating System:
    Ubuntu 18.04.4 LTS
    Linux 5.3.0-62-generic add activate event in telemetry #56~18.04.1-Ubuntu SMP Wed Jun 24 16:17:03 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

  • JDK version:
    openjdk version "11.0.7" 2020-04-14 LTS
    OpenJDK Runtime Environment Zulu11.39+15-CA (build 11.0.7+10-LTS)
    OpenJDK 64-Bit Server VM Zulu11.39+15-CA (build 11.0.7+10-LTS, mixed mode)

  • Visual Studio Code version:
    Version: 1.47.0
    Commit: d5e9aa0227e057a60c82568bf31c04730dc15dcd
    Date: 2020-07-09T08:30:34.302Z
    Electron: 7.3.2
    Chrome: 78.0.3904.130
    Node.js: 12.8.1
    V8: 7.8.279.23-electron.0
    OS: Linux x64 5.3.0-62-generic

  • Java extension version:
    v0.9.1

  • Java Debugger extension version:
    v0.26.0

  • Vavr version:
    1.0.0-alpha-3

Steps To Reproduce
  1. Set a breakpoint in a lambda expression being used, say, to map a Vavr Array (I have not been able to reproduce this with plain Java Stream).
  2. Debug a test to hit that breakpoint.

[attach a sample project reproducing the error]

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;

import io.vavr.collection.Array;

public class AoeuTest {
  @Test
  public void shouldHavePerfectGrade() {
    final Array<Integer> integers = Array.of(1);
    
    final int actual = function(integers);

    assertThat(actual).isEqualTo(1);
  }

  static int function(final Array<Integer> integers) {
    return integers
        .map(i -> {
              final Integer result = i;

              return result; // set breakpoint here and create watch on `result`. also create a condition for the breakpoint
            })
        .get();
  }
}
Current Result

Cannot evaluate because of compilation error(s): Evaluations must contain either an expression or a block of well-formed statements emitted for watches and breakpoint conditions even for literal primitives like 15.

Expected Result

Watches and breakpoint conditions work.

Additional Informations

Activity

  1. testforstephen commented on Jul 15, 2020

    @testforstephen
    Contributor

    Also can reproduce it in the upstream eclipse, looks like a new corner case that needs fix in the upstream.

    Regarding the case you provide above, i try to use maven to add io.vavr.vavr dependency, then try the sample snippet Array<Integer>.map(lambda) and also get the same evaluation error.

    But if i use the JDK built-in Stream API or define a lambda callback in my source code itself, the evaluation in the lambda body works well. See a sample below.

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.Function;
    import java.util.stream.Stream;
    
    public class Lambda {
        public static void main(String[] args) {
            GenericBar<Bar> bar = new GenericBar<>();
            bar.context = new Bar("test");
            bar.map(item -> {
                item.name = item.name + "new";
                return item; // Add a breakpoint here, the evaluation on the variable 'item' works.
            });
        }
    
        static class Bar {
            public String name;
    
            Bar(String name) {
                this.name = name;
            }
        }
    
        static class GenericBar<T extends Bar> {
            public T context;
        
            public <R> Stream<R> map(Function<T, R> mapper) {
                List<R> result = new ArrayList<>();
                Arrays.asList(context).forEach(item -> {
                    result.add(mapper.apply(item));
                });
                return result.stream();
            }
        }
    }

    So it seems this error only happens at the third party build tool dependencies such as maven/gradle. However, need open an issue in the upstream and fix there.

  2. noel-yap commented on Jul 15, 2020

    @noel-yap
    Author

    I wasn't able to reproduce the issue using Java's Stream, either, so I'm not understanding how the build tool is a factor here.

  3. prumseycsi commented on Apr 19, 2021

    @prumseycsi

    I get this error annoyingly after several iterations of running a relatively simple program derived from the Tables tutorial, running v 0.32.1 of the debugger in Windows. It is cured by restarting VSCode. More details available if any interest.

    Update: Now there is no cure, and the issue is quite reproducible, at least in my project. The debug console becomes useless after a few statements of the class constructor.

    package SlideCatalog;
    /*
    * Copyright (c)
    */
    
    /*
    * SlideCatalog.java requires no other files.
    */
    
    import javax.swing.*;
    import javax.swing.plaf.FontUIResource;
    import javax.swing.table.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import java.nio.file.Files;
    import java.util.*;
    import java.util.stream.*;
    import java.util.prefs.*;
    
    public class SlideCatalog
    {
       private final boolean debug;
       void debugPrint(Object dat) {
           if (debug) System.out.println(dat);
       }
       void debugPrint(String format, Object ... dat) {
           debugPrint(String.format(format, dat)); 
       }
       boolean isWindows() {
           return System.getProperty("os.name").toLowerCase().contains("windows");
       }
       private JFrame frame;
       private JTable table;
       private MyTableModel model;
    
       private Preferences preferences = Preferences.userNodeForPackage(SlideCatalog.class);
       private String slideShowCmd = preferences.get("SlideShow",
           "cmd /c start slideshow /ro slides/%"); // "sh -c cd slides; eog %" for linux
       private RecentFiles recent;
       private int scale;
    
    /**
    * SlideCatalog frame initializer
    * No arguments (except from preferences!)
    */
       public SlideCatalog() {
           debug = !getClass().getResource("SlideCatalog.class").toString().contains(".jar");
    // build the table with its model and sorter/filter
           model = new MyTableModel();
           table = new JTable(model);
           table.getSelectionModel().addListSelectionListener(event-> {
               if (event.getValueIsAdjusting()) return;
               debugPrint(event);
               int row = table.getSelectedRow();
               if (MNU.EDIT.getState() && row>0) ;//ask if updated, revert if cancel
               //MNU.EDIT.menuItem.setEnabled(table.getSelectedRowCount() == 1);
               MNU.SLIDESHOW.menuItem.setEnabled(table.getSelectedRowCount() > 0);
           });
    
           table.setFillsViewportHeight(true);
           TableRowSorter<MyTableModel> sorter = new TableRowSorter<>(model); 
           sorter.setRowFilter(new RowFilter<MyTableModel,Integer>() {
               @Override
               public boolean include(RowFilter.Entry<? extends MyTableModel, ? extends Integer> entry) {
                   return model.isRowShown(entry.getIdentifier());
               }
           });
           table.setRowSorter(sorter);
           table.moveColumn(3, 1); //switch file's code,count,good,subject to view's cd,sb,ct,gd
           InputMap im = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).getParent();
           im.remove(KeyStroke.getKeyStroke("control C")); //table has row-editing accelerators
           im.remove(KeyStroke.getKeyStroke("control X")); //remove them!
           im.remove(KeyStroke.getKeyStroke("control A"));
    
    // build the framework
           frame = new JFrame("Slide Catalog - (untitled) *");
           frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
           frame.addWindowListener(new WindowAdapter() {
               @Override
               public void windowClosing(WindowEvent e) {
                   preferences.putInt("Width", frame.getWidth());
                   preferences.putInt("Height", frame.getHeight());
                   System.exit(0);
               }
           });
           // make Alt-mnemonic work for empty JMenus (table has focus)
           table.addKeyListener(new KeyAdapter() {
               @Override public void keyPressed(KeyEvent e) {
                   JMenu jm = MNU.doMnemonic(e);
                   if (jm != null) menuClicked(jm.getText()); 
               }
           });
           /*frame.setUndecorated(true); // nice appearance, but not too practical*/
     
    // Build the menus
           frame.setJMenuBar(createMenus());
           recent = new RecentFiles((JMenu)MNU.RECENT.menuItem, preferences, 0) {
               @Override public void clicked(File file) {model.readFile(file);}
           };
    
    //Create the scroll pane, add table to it, add it to frame.
           frame.setContentPane(new JScrollPane(table));
    
    //Set up column sizes.
           initColumnSizes();
    
    //Display the window.
           frame.setPreferredSize(new Dimension(
               preferences.getInt("Width", 600),
               preferences.getInt("Height", 200)));
           frame.pack();
           frame.setLocationRelativeTo(null); //center screen - works better after set size
           model.scaleFont(preferences.getInt("Scale", 0));
           frame.setVisible(true);
    
    //Load data if indicated
           if (MNU.AUTOLOAD.getState()) model.readFile(recent.last());
       }
    
       public String toRGB(String in) {
           String out = "<html>";
           for (Character c:(in+".....").substring(0,5).toLowerCase().toCharArray()) {
               out += String.format("<span x%s style=background-color:%s>&emsp;",
               c=='r'?"1":c=='g'?"2":c=='b'?'3':'0',
               c=='r'?"red": //weirdly spelled to sort by r,g,b
               c=='g'?"lime":
               c=='b'?"blue":"#f0f0f0");                
           }
           //System.out.println(in+"->"+fromRGB(out));
           return out;
       }
       public String fromRGB(String in) {
           String[] out = in.split("x");
           out[0] = "";
           IntStream.range(1,out.length)
           .forEach(i->out[i] = String.valueOf("_rgb".charAt(out[i].charAt(0)%4)));
           return String.join("", out);
       }
    
    /**
    * This method picks good column sizes.
    * If all column heads are wider than the column's cells'
    * contents, then you can just use column.sizeWidthToFit().
    */
       private void initColumnSizes() {
           for (int i = 0; i < 4; i++) {
               TableColumn column = table.getColumnModel().getColumn(i);
               int h = table.getFontMetrics(table.getFont()).getHeight();
               table.setRowHeight(h);
               table.getTableHeader().setPreferredSize(new Dimension(table.getWidth(), h+h));
               if (i == 1) continue;
               int Width = Math.round(table.getFont().getSize2D()*5.3f +.6f);
               column.setMaxWidth(Width);
               column.setPreferredWidth(Width);
           }
       }
    
       public void setUpUpDownColumn(int col) {
           //Set up the editor for the sport cells.
           TableColumn tcol = table.getColumn(col);
           JSpinner spinner = new JSpinner();
           //tcol.setCellEditor(new DefaultCellEditor(spinner));
       }
    
       class MyTableModel extends AbstractTableModel {
           private static final long serialVersionUID = 1L;
           private String[] columnNames = {"","","",""};
           private ArrayList<Object[]> data = new ArrayList<>();
    
           public MyTableModel() {
               addRow("r.g.b 5 0 Snowboarding");
               addRow("b.b.r 4 3 Rowing");
               addRow("g...b 0 0 Knitting");
               addRow("...rg 10 5 Playing in the Pool");
           }
           public int getColumnCount() {
               return columnNames.length;
           }
    
           public int getRowCount() {
               return data.size(); // - permutes;
           }
    
           public String getColumnName(int col) {
               if (columnNames[1].isEmpty()) doFilter();
               return columnNames[col];
           }
    
           public Object getValueAt(int row, int col) {
               //debugPrint("GetValue %d,%d",row,col);
               return data.get(row)[col];
           }
    
           /*
            * JTable uses this method to determine the default renderer/
            * editor for each cell.  If we didn't implement this method,
            * then the last column would contain text ("true"/"false"),
            * rather than a check box.
            */
           public Class<?> getColumnClass(int c) {
               if (data.size() == 0) return "".getClass();
               return getValueAt(0, c).getClass();
           }
    
           /*
            * Don't need to implement this method unless your table's
            * editable.
            */
           public boolean isCellEditable(int row, int col) {
               //Note that the data/cell address is constant,
               //no matter where the cell appears onscreen
               debugPrint("IsEditable %d,%d",row,col);
               return (MNU.EDIT.getState() && col > 0);
           }
    
           /*
            * Don't need to implement this method unless your table's
            * data can change.
            */
           public void setValueAt(Object value, int row, int col) {
               debugPrint("SetValue %d,%d", row, col);
               data.get(row)[col] = value;
               fireTableCellUpdated(row, col);
           }
    
           public boolean isRowShown(int row) {
               if (MNU.SKIPEMPTY.getState() && !MNU.EDIT.getState())
                   if (data.get(row)[1] == Integer.valueOf(0)) return false;
               if (!MNU.PERMUTE.getState() || MNU.EDIT.getState())
                   if ("<p>".equals(data.get(row)[4])) return false;
                   return true;
           }
    
           public String getSlideShowCmd() {
               if (table.getSelectedRowCount() == 0) return "";
               ArrayList<String> out = new ArrayList<>();
               String s;
               for (int row: table.getSelectedRows()) {
                   row = table.convertRowIndexToModel(row);
                   s = fromRGB(""+getValueAt(row, 0)) + "*";
                   if (!out.contains(s)) out.add(s);
               }
               String f = slideShowCmd.split("%")[0];
               s = (slideShowCmd + "% ").split("%")[1];
               if (s.isEmpty()) s = " ";
               return f + String.join(s, out);
           }
    
           public void clear() {
               data.clear();
               frame.setTitle("Slide Catalog - (untitled)  ");
               table.getTableHeader().setVisible(false);
               fireTableDataChanged();
           }
           
           private Object[] validateRow(String rowtext) { //format: Code\tCount\tGood\tSubject
               Object[] orow = new Object[]{"",0,0,"",rowtext};
               String[] row = rowtext.split("\\s+",4);
               String c;
               if (row.length > 0) {
                   c = row[0];
                   if (c.length() < 10) orow[0] = toRGB(c);
                   else orow[0] = toRGB(fromRGB(c));
               }
               if (row.length > 1) {
                   c = row[1]; if (c.matches("\\d+")) orow[1] = Integer.valueOf(c);
               }
               if (row.length > 2) {
                   c = row[2]; if (c.matches("\\d+")) orow[2] = Integer.valueOf(c);
               }
               if (row.length > 2) orow[3] = String.join(" ",row[3].split("\\s+"));
               orow[4] = String.format("%s %d %d %s", fromRGB((String)orow[0]),
                   orow[1], orow[2], orow[3]);
               return orow;
               }
    
           public void addRow(String row) {
               Object[] orow = validateRow(row);
               data.add(orow);
               fireTableRowsInserted(data.size()-1, data.size()-1);
               String subject = (String)orow[3];
               subject = String.join(" ",subject.split("\\s+"));
               for (int i=0;;) {
                   i = subject.indexOf(' ', i) + 1;
                   if (i == 0) break;
                   orow = orow.clone();
                   orow[4] = "<p>";
                   orow[3] = subject.substring(i) + ", " + subject.substring(0,i-1) + " <p>";
                   data.add(orow);
                   fireTableRowsInserted(data.size()-1, data.size()-1);
               }
           }
    
           public void openFile() {
               JFileChooser fc = new JFileChooser();
               fc.setFileFilter(new javax.swing.filechooser.FileNameExtensionFilter(
                   "SlideCatalog File", "slc"));
               if (fc.showOpenDialog(frame) != JFileChooser.APPROVE_OPTION) return;
               readFile(fc.getSelectedFile());
           }
    
           public void readFile(File f) {
               try {
                   java.nio.charset.Charset cs = java.nio.charset.Charset.forName("cp437");
                   java.util.List<String> s = Files.readAllLines(f.toPath(),cs);
                   clear();
                   s.forEach(line->addRow(line));
                   recent.promote(f);
                   frame.setTitle("Slide Catalog - " + f.getName() + "  ");
                   table.getTableHeader().setVisible(true);
                   doFilter();
               } catch (Exception e0) {
                   if (f.getName().isEmpty()) return;
                   JOptionPane.showMessageDialog(frame,
                       f.getAbsolutePath()+"\n"+e0.getClass().getSimpleName(),
                       "Read File", JOptionPane.ERROR_MESSAGE);
                   recent.remove(f);
                   return;
               }
           }
    
           public void scaleFont(int x1) {
               if (table.getFont().getSize() + x1 < 4 || x1 == 0) return;
               scale += x1;
               preferences.putInt("Scale", scale);
               UIDefaults ud = UIManager.getDefaults();
               HashMap<String, Font> fmap = new HashMap<>();
               HashMap<Object, Font> map = new HashMap<>();
               ud.keys().asIterator().forEachRemaining(s->{
                   if (ud.get(s) instanceof Font) { // make all fonts bigger or smaller
                       FontUIResource f = (FontUIResource)ud.get(s);
                       fmap.putIfAbsent(f.toString(), new FontUIResource(
                           f.getFontName(), f.getStyle(), f.getSize()+x1));
                       map.put(s, fmap.get(f.toString()));
                   } 
               });
               map.forEach((s,f)->ud.put(s,f));
               SwingUtilities.updateComponentTreeUI(frame);
               int h = frame.getFontMetrics(MNU.MENU.menuItem.getFont()).getHeight();
               frame.getJMenuBar().setPreferredSize(new Dimension(20, h));
               initColumnSizes();
           }
    
           public void doFilter() {
               int shown = 0;
               int count = 0;
               int good = 0;
               for (int i = 0; i < data.size();++i) {
                   if (isRowShown(i)) {
                       shown += 1;
                       if ("<p>".equals(data.get(i)[4])) continue;
                       count += (int)data.get(i)[1];
                       good += (int)data.get(i)[2];
                   }
               }
               columnNames[0] = headerFormat[0];
               columnNames[1] = String.format(headerFormat[1], count);
               columnNames[2] = String.format(headerFormat[2], good);
               columnNames[3] = String.format(headerFormat[3], shown, data.size());
               if (table == null) return;
               TableColumnModel cm = table.getColumnModel();
               for (int i=0; i<getColumnCount(); ++i) {
                   cm.getColumn(table.convertColumnIndexToView(i)).setHeaderValue(columnNames[i]);}
               table.getRowSorter().allRowsChanged(); //re-sort and filter
               table.getTableHeader().repaint(); //update header text
           }
    
           private final String[] headerFormat = {
               "Code",
               "<html><div align=right>Count<br>%d",
               "<html><div align=right>Good<br>%d",
               "<html><div align=center>Subject<br>%d of %d shown"
           };
       }
    
       /**
        * Recent Files list - maintains a dropdown list of recent file paths
        * Construct with its menu or menuitem parent.
        */
       public class RecentFiles {
           private final ArrayList<File> lst;
           private final JMenu menu;
           private final Preferences prefs;
           private final int limit;
    
           public RecentFiles(JMenu menu, Preferences prefs, int limit) {
               this.menu = menu;
               this.prefs = prefs;
               this.limit = limit;
               lst = new ArrayList<File>();
               for (int i = 1;;i++) {
                   File f = new File(prefs.get("RecentFiles/"+i, ""));
                   if (f.toString().isEmpty()) break;
                   lst.add(f);
               }
               setMenu();
           }
           public File last() {return lst.isEmpty()? new File("") : lst.get(0);}
           public void promote(File f) {
               if (f.toString().isEmpty()) return;
               if (lst.contains(f)) if (lst.indexOf(f) == 0) return;
               lst.remove(f);
               lst.add(0, f);
               if (limit > 3 && lst.size() > limit) lst.remove(limit);
               menu.removeAll();
               setMenu();       
           }
           public void remove(File f) {
               int i = lst.indexOf(f);
               if (i < 0) return;  
               menu.remove(i);
               setMenu();
           }
           private void setMenu(){
               prefs.remove("RecentFiles/" + (lst.size()+1));
               if (lst.isEmpty()) {
                   menu.setVisible(false);
                   return;
               }
               menu.setVisible(true);
               menu.removeAll();
               for (int i = 0; i < lst.size(); i++) {
                   String s = lst.get(i).getName();
                   if (i>0) if (!lst.get(i).getParent().equals(lst.get(0).getParent()))
                       s = "... " + s;
                   if (i < 10) s = "" + (i+1) + " " + s;
                   JMenuItem f = new JMenuItem(s);
                   f.setToolTipText(lst.get(i).getAbsolutePath());
                   if (i < 10) {
                       int c = s.charAt(0);
                       f.setMnemonic(c);
                       c = KeyEvent.getExtendedKeyCodeForChar(c);
                       f.setAccelerator(KeyStroke.getKeyStroke(c, InputEvent.CTRL_DOWN_MASK));
                   }
                   menu.add(f);
                   f.addActionListener(e->clicked(new File(f.getToolTipText())));
                   prefs.put("RecentFiles/"+(i+1), lst.get(i).toString());
               }
           }
           public void clicked(File file) {
               debugPrint(file);
           }
       }
    
       /**
        * Menu building script.  MNU names are canonical labels for menu items.
        * So that spellings can be changed, etc.  Two parameters, first is 
        * menu text.  Second starts with mnemonic unless '\0'; then flags:
        * '-' for addSep after, '^' for new JMenuBar menu, 'm' for submenu,
        * 'x' for last submenu item, '~' for checkbox item, 'd' for disabled,
        * 'l' for a label,
        * 'c', 'a', 's' for ctrl,alt,shift modifiers, 0 for no accelerator;
        * then tooltip after '|'.
        */
       private enum MNU {MENU("Menu","M^a"),
           NEW("New","Nc|Empty the list"),
           OPEN("Open","Oc|Open a file"),
           SAVE("Save","Sc|Save the current data"),
           SAVEAS("Save As","Acs|Save with a new name"),
           RECENT("Recent Files","Rmx-|Shows recently opened files"),
           EDIT("Edit","E~c|Change the data in the selected row"),
           KEYWORD("KeyWord","W|Search in Subject text"),
           BIG("Bigger","B|Make everything bigger"),
           SMALL("Smaller","m-|Make everything smaller"),
           EDITSHOW("Edit ShowCmd","wc|Change the Slideshow command line"),
           SKIPEMPTY("Skip Empty","k~|Show only line with Count>0"),
           PERMUTE("Show Permuted", "P~|Show lines with permuted Subject words"),
           AUTOLOAD("AutoLoad","Lc~|Load last opened file at startup"),
           ABOUT("About","tc-|Show slide Catlog info"),
           EXIT("Exit","xax|Exit the program"),
           SLIDESHOW("SlideShow","S^dx|Invoke another program to show selected images"),
           MSG("F1 for Help","\0l|This area shows notes");
    
           public final String text;
           public final boolean isCheck;
           public final boolean addSep;
           public final boolean isMenu;
           public final boolean isLabel;
           public final boolean isSubMenu;
           public final boolean isLast;
           public final JMenuItem menuItem;
           public final JLabel label;
           private final String tooltip; 
           MNU(String txt, String flg) {
               // System.out.println(txt); - clever! only happens once per label! 
               text = txt;
               int c = KeyEvent.getExtendedKeyCodeForChar(flg.charAt(0));
               int tt = flg.indexOf('|');
               if (tt >= 0) {tooltip = flg.substring(tt+1); flg = flg.substring(1,tt);}
               else {tooltip = ""; flg = flg.substring(1);}
               isCheck = flg.contains("~");
               addSep = flg.contains("-");
               isMenu = flg.contains("^");
               isSubMenu = flg.contains("m");
               isLast = flg.contains("x");
               isLabel = flg.contains("l");
               label = (isLabel) ? new JLabel(text) : null;
               menuItem = (isMenu || isSubMenu) ? new JMenu(text)
               : (isCheck) ? new JCheckBoxMenuItem(text)
               : (isLabel) ? null
               : new JMenuItem(text);
               if (isLabel) {
                   label.setToolTipText(tooltip);
                   return;
               }
               menuItem.setEnabled(!flg.contains("d"));
               menuItem.setToolTipText(tooltip);
               if (c == KeyEvent.VK_UNDEFINED) return;   
               menuItem.setMnemonic(c);
               if (isMenu || isSubMenu) return;
               if (flg.contains("0")) return;
               int msk = 0;
               if (flg.contains("c")) msk |= InputEvent.CTRL_DOWN_MASK;
               if (flg.contains("a")) msk |= InputEvent.ALT_DOWN_MASK;
               if (flg.contains("s")) msk |= InputEvent.SHIFT_DOWN_MASK;
               menuItem.setAccelerator(KeyStroke.getKeyStroke(c, msk));
           }
           public JMenu getMenu() {
               return (menuItem instanceof JMenu) ? (JMenu)menuItem : null;
           }
    
           public boolean getState() {
               if (!isCheck) return false;
               return ((JCheckBoxMenuItem)menuItem).getState();
           }
           public void setState(boolean state) {
               if (isCheck) ((JCheckBoxMenuItem)menuItem).setState(state);
           }
           /** look up ActionCommand (menu.text) to find MNU instance */
           public static MNU byText(String txt) {
               for (MNU mnu:MNU.values())
                   if(mnu.text.equals(txt)) return mnu;
               return null;
           }
           /** Alt-mnemonic finds empty JMenu item and consumes the event */
           public static JMenu doMnemonic(KeyEvent e) {
               if (!e.isAltDown() || e.getKeyChar() > 127) return null; 
               for (MNU mnu:MNU.values())
                   if (mnu.isMenu && mnu.getMenu().getPopupMenu().getComponentCount() == 0
                       && e.getKeyCode() == mnu.menuItem.getMnemonic()) {
                       if (mnu.menuItem.isEnabled()) {
                           e.consume(); //don't leave the menu pressed
                           return (JMenu)mnu.menuItem;
                       }
                   }
               return null;
           }
       }
       private JMenuBar createMenus() {
           //Create and setup a menu bar.
           JMenuBar jMenu = new JMenuBar();
           jMenu.setBackground(Color.yellow);
           JMenu m = null;
           for (MNU mnu: MNU.values()) {
               JMenuItem mi = mnu.menuItem;
               if (mnu.isLabel) {
                   if (m == null) jMenu.add(mnu.label); else m.add(mnu.label);
               } else if (mnu.isMenu || mnu.isSubMenu) {
                   mi.addMouseListener(new MouseAdapter() {
                       public void mouseClicked(MouseEvent e)
                           {menuClicked(((JMenu)e.getSource()).getText());}
                   });
                   if (mnu.isSubMenu) m.add(mi); else jMenu.add(mi);
                   if (!mnu.isLast) m = (JMenu)mi;
               } else {
                   mi.addActionListener(e->menuClicked(e.getActionCommand()));
                   if (m == null) jMenu.add(mi); else m.add(mi);
                   if (mnu.isLast) m = (m.getParent() == jMenu) ? null : (JMenu)m.getParent();
               }
               if (mnu.addSep) m.addSeparator();
           }
           MNU.SKIPEMPTY.setState(preferences.getBoolean("SkipEmpty", false));
           MNU.PERMUTE.setState(preferences.getBoolean("ShowPermute", false));
           MNU.AUTOLOAD.setState(preferences.getBoolean("AutoLoad", false));
           return jMenu;
       }
    
       public void menuClicked(String t) {
           MNU mnu = MNU.byText(t);
           if (!mnu.menuItem.isEnabled()) return;
           debugPrint("Action %s",t);
           switch (mnu) {
           case EXIT:
               frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
           case NEW:
               model.clear(); break;
           case OPEN:
               model.openFile(); break;
           case BIG:
               model.scaleFont(1); break;
           case SMALL:
               model.scaleFont(-1); break;
           case AUTOLOAD:
               preferences.putBoolean("AutoLoad", MNU.AUTOLOAD.getState());
           case PERMUTE:
               preferences.putBoolean("ShowPermute", MNU.PERMUTE.getState());
               model.doFilter(); break;
           case SKIPEMPTY:  // toggles happen automatically
               preferences.putBoolean("SkipEmpty", MNU.AUTOLOAD.getState());
               model.doFilter(); break;
           case EDITSHOW:
               String s = JOptionPane.showInputDialog(frame,
                   "Edit SlideShow command", slideShowCmd);
               if (s == null) break;
               preferences.put("SlideShow", slideShowCmd); break;
           case SLIDESHOW:
               try {new ProcessBuilder((model.getSlideShowCmd()).split("\\s+")).start();}
               catch (IOException ex) {} break;
           case EDIT:
               if (MNU.EDIT.getState()) {
                   table.clearSelection();
                   MNU.MSG.label.setText("Editing data ...");
               } else MNU.MSG.label.setText("");
               model.doFilter(); break;
           case MENU: // not needed
           case RECENT: // not needed
           case MSG: // not possible
               break;
           }
       }
    
       /**
        * Create the GUI and show it.  For thread safety,
        * this method should be invoked from the
        * event-dispatching thread.
        */
    
       public static void main(String[] args) {
           //Schedule a job for the event-dispatching thread:
           //creating and showing this application's GUI.
           javax.swing.SwingUtilities.invokeLater(new Runnable() {
               public void run() {
                   new SlideCatalog();
               }
           });
       }
    }
  4. testforstephen commented on Dec 14, 2021

    @testforstephen
    Contributor

    Duplicate with #754, let's use that issue to track the progress.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions