Search code examples
javaswing

How do I disable a JFrame's specific window control button in Java?


The BA wants a window that

  • has a close button
  • has a maximize button
  • has no enabled minimize button

He wants us, Java devs, to achieve what the C guys did which is this

enter image description here

Considering the requirements for window control buttons, it seems there's no way around JFrame. But how do I disable the minimize button? I will consider going for native methods, if it's the only way (the apps are installed on Windows PCs)

I can do something like this, but the minimize button stays enabled -- just the frame pops back up

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

public class NonMinimizableFrameDemo {

    public NonMinimizableFrameDemo() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 300);
        frame.setLocationRelativeTo(null);
        frame.addWindowListener(getWindowAdapter());
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(NonMinimizableFrameDemo::new);
    }
    private final JFrame frame = new JFrame();

    private WindowAdapter getWindowAdapter() {
        return new WindowAdapter() {

            @Override
            public void windowIconified(WindowEvent we) {
                frame.setState(JFrame.NORMAL);
                JOptionPane.showMessageDialog(frame, "Cant Minimize");
            }
        };
    }
}

Solution

  • A complicated option is to undecorate the JFrame and put an JInternalFrame inside. With a listener you have to maximize the parent JFrame when the JInternalFrame is maximized.

    enter image description here

    package fenster;
    
    import java.awt.Toolkit;
    import java.awt.event.MouseEvent;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.util.EventObject;
    
    import javax.swing.JFrame;
    import javax.swing.JInternalFrame;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.event.InternalFrameAdapter;
    import javax.swing.event.InternalFrameEvent;
    import javax.swing.event.MouseInputAdapter;
    
    public class Test
    {
       public Test()
       {
          initComponents();
       }
    
       public static void main(String[] args)
       {
          javax.swing.SwingUtilities.invokeLater(new Runnable()
          {
             @Override
             public void run()
             {
                new Test();
             }
          });
       }
    
       private JFrame frame;
    
       private void initComponents()
       {
          try
          {
             
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
          }
          catch (ClassNotFoundException | InstantiationException
            | IllegalAccessException | UnsupportedLookAndFeelException e)
          {
             // nothing
          }
      
          frame = new JFrame();
          frame.setUndecorated(true);
          frame.setResizable(true);
          frame.setSize(600, 400);
          frame.setLocationByPlatform(true);
          JInternalFrame iframe = new JInternalFrame();
          iframe.setResizable(true);
          iframe.setClosable(true);
          iframe.setMaximizable(true);
          iframe.setIconifiable(false);   
          iframe.setSize(600, 400);
          iframe.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
          iframe.addInternalFrameListener(getAdapter());
          iframe.addPropertyChangeListener(new MyPropertyChangeListener());
          iframe.addMouseMotionListener( new DragHandler() );
          frame.addMouseMotionListener( new DragHandler() );
          frame.add(iframe);
          iframe.setVisible(true);
          frame.setVisible(true);
       }
    
       private InternalFrameAdapter getAdapter()
       {
           return new InternalFrameAdapter()
           {
              @Override
              public void internalFrameClosing(InternalFrameEvent e)
              {
                 System.exit(0);
              }
           };
        }
    
       private class MyPropertyChangeListener implements PropertyChangeListener
       {
          @Override
          public void propertyChange(PropertyChangeEvent evt)
          {
             dealWithEvent(evt);   
          }
       }
    
       private class DragHandler extends MouseInputAdapter
       {
           public void mouseDragged( MouseEvent evt )
           {
              dealWithEvent(evt);
           }
       }
    
       private void dealWithEvent (EventObject event)
       {      
          if(event instanceof PropertyChangeEvent)
          {
             PropertyChangeEvent e = (PropertyChangeEvent) event;
             if(e.getPropertyName().equalsIgnoreCase("maximum"))
             {
                if(Toolkit.getDefaultToolkit().getScreenSize().width == frame.getWidth())
                {
                   frame.setExtendedState(JFrame.NORMAL);
                }
                else
                {
                   frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
                }
             }
          }
          else if(event instanceof MouseEvent && ((MouseEvent) event).getY() < 200)
          {
             MouseEvent e = (MouseEvent) event;
             int x = e.getX();
             int y = e.getY();
             int screenX = frame.getX();
             int screenY = frame.getY();
             screenX += x;
             screenY += y;
             frame.setLocation( screenX, screenY );
          }
          else if(event instanceof MouseEvent && ((MouseEvent) event).getY() > 200)
          {
             MouseEvent e = (MouseEvent) event;
             frame.setSize(e.getX(), e.getY());
          }  
       }
    }