0

So I've been having a problem regarding Look and Feel. I have a submenu that changes look and feel but it doesn't do anything, it only resizes the window bar.

1)The problem I have with my code is Look and feel does not work, despite even updating the UI

2)When I change look and feel the text area changes sizes for some reason.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class NoteTaker extends JFrame
{
   // Constants for set up of the note taking area
   public static final int WIDTH = 600;
   public static final int HEIGHT = 300;
   public static final int LINES = 13;
   public static final int CHAR_PER_LINE = 45;

   // Objects in GUI
   private JTextArea theText; // Text area to take notes
   private JMenuBar mBar;     // Horizontal menu bar
   private JPanel textPanel;  // Scrolling text area panel
   private JMenu notesMenu;   // Vertical menu for notes

   // THESE ITEMS ARE NOT YET USED
   // YOU WILL BE CREATING THEM IN THIS LAB
   private JMenu viewMenu; // Vertical menu for views
   private JMenu lafMenu;  // Vertical menu look and feel
   private JMenu sbMenu;   // Vertical menu for scroll bar
   private JScrollPane scrolledText;   // Scroll bars

   // Default notes
   private String note1 = "No Note 1.";
   private String note2 = "No Note 2.";

   /**
      Constructor
   */

   public NoteTaker()
   {
      // Create a closeable JFrame with a specific size
      super("Note Taker");
      setSize(WIDTH, HEIGHT);
      setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

      // Get contentPane and set layout of the window
      Container contentPane = getContentPane();
      contentPane.setLayout(new BorderLayout());

      // Creates the vertical menus
      createNotes();
      createViews();

      // Creates horizontal menu bar and
      // adds vertical menus to it
      mBar = new JMenuBar();
      mBar.add(notesMenu);
      mBar.add(viewMenu);
      // ADD THE viewMenu TO THE MENU BAR HERE
      setJMenuBar(mBar);

      // Creates a panel to take notes on
      textPanel = new JPanel();
      textPanel.setBackground(Color.blue);
      theText = new JTextArea(LINES, CHAR_PER_LINE);
      theText.setBackground(Color.white);

      // CREATE A JScrollPane OBJECT HERE CALLED
      // scrolledText AND PASS IN theText, THEN
      scrolledText = new JScrollPane(theText);
      // CHANGE THE LINE BELOW BY PASSING IN scrolledText
      textPanel.add(scrolledText);
      contentPane.add(textPanel, BorderLayout.CENTER);
   }

    /**
      Creates vertical menu associated with Notes
      menu item on menu bar.
   */

   public void createNotes()
   {
      notesMenu = new JMenu("Notes");
      JMenuItem item;

      item = new JMenuItem("Save Note 1");
      item.addActionListener(new MenuListener());
      notesMenu.add(item);

      item = new JMenuItem("Save Note 2");
      item.addActionListener(new MenuListener());
      notesMenu.add(item);

      item = new JMenuItem("Open Note 1");
      item.addActionListener(new MenuListener());
      notesMenu.add(item);

      item = new JMenuItem("Open Note 2");
      item.addActionListener(new MenuListener());
      notesMenu.add(item);

      item = new JMenuItem("Clear");
      item.addActionListener(new MenuListener());
      notesMenu.add(item);

      item = new JMenuItem("Exit");
      item.addActionListener(new MenuListener());
      notesMenu.add(item);
   }

   /**
      Creates vertical menu associated with Views
      menu item on the menu bar.
   */

   public void createViews()
   {
       viewMenu = new JMenu("Views"); // Creates Menu Item called Views on horizontal Menu Bar

       createLookAndFeel(); //Creates submenu Look And Feel
       lafMenu.addActionListener(new MenuListener());

       createScrollBars(); //Creates submenu Scroll Bars
       sbMenu.addActionListener(new MenuListener());
   }

   /**
      Creates the look and feel Sub menu.
   */

   public void createLookAndFeel()
   {
       lafMenu = new JMenu("Look and Feel"); //Creates Menu Item called Look and Feel
       viewMenu.add(lafMenu);

       //Adds Menu item metal
       JMenuItem itemMetal;
       itemMetal = new JMenuItem("Metal");
       itemMetal.addActionListener(new MenuListener());
       lafMenu.add(itemMetal);

       //Adds Menu item Motif
       JMenuItem itemMotif;
       itemMotif = new JMenuItem("Motif");
       itemMotif.addActionListener(new MenuListener());
       lafMenu.add(itemMotif);

       //Adds Menu item Windows
       JMenuItem itemWindows;
       itemWindows = new JMenuItem("Windows");
       itemWindows.addActionListener(new MenuListener());
       lafMenu.add(itemWindows);
   }

   /**
      Creates the scroll bars submenu.
   */

   public void createScrollBars()
   {
       sbMenu = new JMenu("Scroll Bars");
       viewMenu.add(sbMenu);

       //Adds MenuItem called Never
       JMenuItem itemNever;
       itemNever = new JMenuItem("Never");
       itemNever.addActionListener(new MenuListener());
       sbMenu.add(itemNever);

       //Adds Menu item Always
       JMenuItem itemAlways;
       itemAlways = new JMenuItem("Always");
       itemAlways.addActionListener(new MenuListener());
       sbMenu.add(itemAlways);

       //Adds Menu item As Needed
       JMenuItem itemAsNeeded;
       itemAsNeeded = new JMenuItem("As Needed");
       itemAsNeeded.addActionListener(new MenuListener());
       sbMenu.add(itemAsNeeded);
   }

   /**
      Private inner class that handles the Menu object's
      action events.
   */

   private class MenuListener implements ActionListener
   {

      public void actionPerformed(ActionEvent e)
      {
         String actionCommand = e.getActionCommand();
         if (actionCommand.equals("Save Note 1"))
            note1 = theText.getText();
         else if (actionCommand.equals("Save Note 2"))
            note2 = theText.getText();
         else if (actionCommand.equals("Clear"))
            theText.setText("");
         else if (actionCommand.equals("Open Note 1"))
            theText.setText(note1);
         else if (actionCommand.equals("Open Note 2"))
            theText.setText(note2);
         else if (actionCommand.equals("Exit"))
            System.exit(0);
        // ADD 6 BRANCHES TO THE ELSE-IF STRUCTURE
        // TO ALLOW ACTION TO BE PERFORMED FOR EACH
        // MENU ITEM YOU HAVE CREATED
         else if (actionCommand.equals("Metal")) {
             try {
                 UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
                 SwingUtilities.updateComponentTreeUI(getContentPane());
             } catch (Exception e1) {
                 JOptionPane.showMessageDialog(null, "Error for Look and Feel");
                 System.exit(0);
             }
         } else if (actionCommand.equals("Motif")) {
             try {
                 UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
                 SwingUtilities.updateComponentTreeUI(getContentPane());
             } catch (Exception e1) {
                 JOptionPane.showMessageDialog(null, "Error setting the look and feel.");
                 System.exit(0);
             }
         } else if (actionCommand.equals("Windows")) {
             try {
                 UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                 SwingUtilities.updateComponentTreeUI(getContentPane());
             } catch (Exception e1) {
                 JOptionPane.showMessageDialog(null, "Error setting the look and feel.");
                 System.exit(0);
             }
         } else if (actionCommand.equals("Never")) {
             scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
             SwingUtilities.updateComponentTreeUI(getContentPane());
             scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
             SwingUtilities.updateComponentTreeUI(getContentPane());
         } else if (actionCommand.equals("Always")) {
             scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
             SwingUtilities.updateComponentTreeUI(getContentPane());
             scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
             SwingUtilities.updateComponentTreeUI(getContentPane());
         } else if (actionCommand.equals("As Needed")) {
             scrolledText.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
             SwingUtilities.updateComponentTreeUI(getContentPane());
             scrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
             SwingUtilities.updateComponentTreeUI(getContentPane());
         }
         else {
             theText.setText("Error in memo interface");
         }
  }
}

   /**
      The main method creates an instance of the
      NoteTaker class which causes it to display
      its window.
   */

   public static void main(String[] args)
   {
      NoteTaker gui = new NoteTaker();
      gui.setVisible(true);
   }
}
Anmol
  • 43
  • 6
  • 1
    That's a lot of code, try changing it to a [mcve] that we can copy-paste and see your issue. This isn't a code snippet or your whole code, but a small runnable example that demonstrates your problem and compiles w/o modifications on our part – Frakcool Mar 27 '17 at 17:25

1 Answers1

2

The issue is that while you update the component tree UI, you are not updating the part where the menu is. That is, the menu bar and its subcomponents do not reside in the content pane. That can be fixed by simply using the frame as the root of the tree to be updated. So changing

SwingUtilities.updateComponentTreeUI(getContentPane());

to

SwingUtilities.updateComponentTreeUI(NoteTaker.this);

should fix the issue.

kiheru
  • 6,588
  • 25
  • 31
  • Thank you very much! I also had a question when I change Look and Feel it changes the text Area size as well. Any idea how to keep it constant? – Anmol Mar 28 '17 at 04:45
  • @Peerless I think it is related to the fonts used by the different look & feels. Motif seems to use a fixed size font so it can make a better estimate of the needed width, whereas metal needs to account for wider characters (so that W fits, using narrower characters can fit more than 45 to the text area). – kiheru Mar 28 '17 at 08:31