2

I want to know if it is possible to undecorate a JFrame and then show only close button at the top or something similar to that.. Any help will be greatly appreciated. Detail: Actually i am making a project, which is a GUI based software, i have used JdesktopPane in it and i am using JInternalFrames so showing the titlebar on the top is not just suiting me. Is there any way to solve my problem.

nsthethunderbolt
  • 2,059
  • 1
  • 17
  • 24

1 Answers1

3

Basically, once you remove the frame border, you become responsible for it's functionality, including moving.

This example basically uses a JPanel to act as a place holder for the "title" pane and uses a BorderLayout to layout out the title and content.

The actual close button is a simple JButton which is using some images to represent the close action. Obviously, this is only going to look right on Windows, these buttons are normal generated by the OS itself...and we don't have access to that layer...

enter image description here enter image description here

public class TestUndecoratedFrame {

    public static void main(String[] args) {
        new TestUndecoratedFrame();
    }

    public TestUndecoratedFrame() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                TitlePane titlePane = new TitlePane();

                JFrame frame = new JFrame("Testing");
                frame.setUndecorated(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                ((JComponent)frame.getContentPane()).setBorder(new LineBorder(Color.BLACK));
                frame.add(titlePane, BorderLayout.NORTH);
                frame.add(new JLabel("This is your content", JLabel.CENTER));
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TitlePane extends JPanel {

        public TitlePane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.weightx = 1;
            gbc.anchor = GridBagConstraints.EAST;
            add(new CloseControl(), gbc);
        }
    }

    public class CloseControl extends JButton {

        public CloseControl() {
            setBorderPainted(false);
            setContentAreaFilled(false);
            setFocusPainted(false);
            setOpaque(false);
            setBorder(new EmptyBorder(0, 0, 8, 12));
            try {
                setRolloverIcon(new ImageIcon(ImageIO.read(getClass().getResource("/Highlighted.png"))));
                setRolloverEnabled(true);
                setIcon(new ImageIcon(ImageIO.read(getClass().getResource("/Normal.png"))));
            } catch (IOException ex) {
                Logger.getLogger(TestUndecoratedFrame.class.getName()).log(Level.SEVERE, null, ex);
            }

            addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    SwingUtilities.getWindowAncestor(CloseControl.this).dispose();
                }
            });
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 2
    @nsthethunderbolt: You might be able to leverage the internal frame icons, seen [here](http://stackoverflow.com/a/10360374/230513), in this context. – trashgod Mar 02 '13 at 06:40