• category: swing folder: CustomDecoratedFrame title: JFrameのタイトルバーなどの装飾を独自のものにカスタマイズする tags: [JFrame, MouseListener, MouseMotionListener, JPanel, JLabel, ContentPane, Transparent] author: aterai pubdate: 2010-01-18T11:27:29+09:00 description: JFrameのタイトルバーなどを非表示にして独自に描画し、これに移動リサイズなどの機能も追加します。 image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTKV1P7mYI/AAAAAAAAAV0/u4qjd-ItBYU/s800/CustomDecoratedFrame.png hreflang:
       href: https://java-swing-tips.blogspot.com/2010/05/custom-decorated-titlebar-jframe.html
       lang: en

概要

概要

JFrameのタイトルバーなどを非表示にして独自に描画し、これに移動リサイズなどの機能も追加します。

サンプルコード

サンプルコード

class ResizeWindowListener extends MouseAdapter {
  private Rectangle startSide = null;
  private final JFrame frame;
  public ResizeWindowListener(JFrame frame) {
    this.frame = frame;
  }
#spanadd

#spanend
  @Override public void mousePressed(MouseEvent e) {
    startSide = frame.getBounds();
  }
#spanadd

#spanend
  @Override public void mouseDragged(MouseEvent e) {
    if(startSide==null) return;
    if (startSide == null) return;
    Component c = e.getComponent();
    if(c==topleft) {
    if (c == topleft) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==top) {
    } else if (c == top) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
    }else if(c==topright) {
    } else if (c == topright) {
      startSide.y += e.getY();
      startSide.height -= e.getY();
      startSide.width += e.getX();
    }else if(c==left) {
    } else if (c == left) {
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==right) {
    } else if (c == right) {
      startSide.width += e.getX();
    }else if(c==bottomleft) {
    } else if (c == bottomleft) {
      startSide.height += e.getY();
      startSide.x += e.getX();
      startSide.width -= e.getX();
    }else if(c==bottom) {
    } else if (c == bottom) {
      startSide.height += e.getY();
    }else if(c==bottomright) {
    } else if (c == bottomright) {
      startSide.height += e.getY();
      startSide.width += e.getX();
    }
    frame.setBounds(startSide);
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルではタイトルバーを、setUndecorated(true)で非表示にし、移動可能にしたJPanelを追加してタイトルバーにしています。 リサイズは、Swing - Undecorated and resizable dialogBasicInternalFrameUI.javaMetalRootPaneUI#MouseInputHandlerなどを参考にして、周辺にそれぞれ対応するリサイズカーソルを設定したJLabelを配置しています。

解説

上記のサンプルではJFrameの元のタイトルバーをsetUndecorated(true)で非表示にし、マウスドラッグで移動可能にしたJPanelを追加してタイトルバーの代わりにしています。
  • - JDK 1.7.0の場合、JFrameの背景色を透明(frame.setBackground(new Color(0,0,0,0));)にし、ContentPaneの左右上の角をクリアして透明にしています。
  • マウスドラッグでのフレームのリサイズはSwing - Undecorated and resizable dialogBasicInternalFrameUI.javaMetalRootPaneUI#MouseInputHandlerなどを参考にして、周辺にそれぞれ対応するリサイズカーソルを設定したJLabelを配置して実行
  • JDK 1.7.0の場合JFrame#setBackground(new Color(0x0, true))JFrameの背景色を透明化、かつContentPaneの左右上の角をクリアして透明化
  • JRootPaneにリサイズのための装飾を設定するのようにJRootPane#setWindowDecorationStyle(JRootPane.PLAIN_DIALOG)を使用してリサイズする方法もある
  • -
  • JRootPaneにリサイズのための装飾を設定するのように、JRootPane#setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);を使用してリサイズする方法もあります。
    #spanend
    #spanadd
    // package example;
    #spanend
    
    #spandel
    #code{{
    #spanend
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    #spandel
    public class WindowDecorationStyleTest {
    #spanend
    #spanadd
    public class MainPanel {
    #spanend
      private static final Color BG_COLOR = Color.ORANGE;
      public JComponent makeTitleBar() {
        JLabel label = new JLabel("Title");
        JLabel label = new JLabel("Title", SwingConstants.CENTER);
        label.setOpaque(true);
        label.setForeground(Color.WHITE);
        label.setBackground(Color.BLACK);
        label.setBackground(BG_COLOR);
        DragWindowListener dwl = new DragWindowListener();
        label.addMouseListener(dwl);
        label.addMouseMotionListener(dwl);
    
        JPanel title = new JPanel(new BorderLayout());
        title.setBorder(BorderFactory.createMatteBorder(0, 4, 4, 4, Color.BLACK));
        title.setBorder(BorderFactory.createMatteBorder(0, 2, 2, 2, BG_COLOR));
        title.add(label);
        title.add(new JButton(new AbstractAction("x") {
          @Override public void actionPerformed(ActionEvent e) {
            Window w = SwingUtilities.windowForComponent((Component) e.getSource());
            w.dispatchEvent(new WindowEvent(w, WindowEvent.WINDOW_CLOSING));
          }
        }), BorderLayout.EAST);
        title.add(makeCloseButton(), BorderLayout.EAST);
        return title;
      }
    #spanadd
    
    #spanend
      public JComponent makeUI() {
        return new JScrollPane(new JTree());
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          @Override public void run() {
            createAndShowGUI();
    #spanadd
    
    #spanend
      private static JButton makeCloseButton() {
        JButton button = new JButton(new CloseIcon());
        button.setContentAreaFilled(false);
        button.setFocusPainted(false);
        button.setBorder(BorderFactory.createEmptyBorder());
        button.setOpaque(true);
        button.setBackground(BG_COLOR);
        button.addActionListener(e -> {
          JComponent b = (JComponent) e.getSource();
          Container c = b.getTopLevelAncestor();
          if (c instanceof Window) {
            Window w = (Window) c;
            w.dispatchEvent(new WindowEvent(w, WindowEvent.WINDOW_CLOSING));
          }
        });
        return button;
      }
    #spanadd
    
    #spanend
      public static void main(String[] args) {
        EventQueue.invokeLater(MainPanel::createAndShowGUI);
      }
    #spanadd
    
    #spanend
      public static void createAndShowGUI() {
        JFrame frame = new JFrame();
        frame.setUndecorated(true);
    
        WindowDecorationStyleTest demo = new WindowDecorationStyleTest();
        MainPanel demo = new MainPanel();
        JRootPane root = frame.getRootPane();
        root.setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
        root.setBorder(BorderFactory.createMatteBorder(4, 8, 8, 8, Color.BLACK));
        root.setBorder(BorderFactory.createMatteBorder(2, 4, 4, 4, BG_COLOR));
        JLayeredPane layeredPane = root.getLayeredPane();
        Component c = layeredPane.getComponent(1);
        if (c instanceof JComponent) {
          JComponent orgTitlePane = (JComponent) c;
          orgTitlePane.removeAll();
          orgTitlePane.setLayout(new BorderLayout());
          orgTitlePane.add(demo.makeTitleBar());
        }
        frame.setMinimumSize(new Dimension(300, 120));
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    #spanadd
    
    #spanend
        try {
          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
          ex.printStackTrace();
          Toolkit.getDefaultToolkit().beep();
        }
    #spanadd
    
    #spanend
        frame.getContentPane().add(demo.makeUI());
        frame.setSize(320, 240);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
      }
    }
    
    class DragWindowListener extends MouseAdapter {
      private final transient Point startPt = new Point();
      private final Point startPt = new Point();
      private Window window;
      @Override public void mousePressed(MouseEvent me) {
        if (window == null) {
          Object o = me.getSource();
          if (o instanceof Window) {
            window = (Window) o;
          } else if (o instanceof JComponent) {
            window = SwingUtilities.windowForComponent(me.getComponent());
          }
        }
        startPt.setLocation(me.getPoint());
      }
    #spanadd
    
    #spanend
      @Override public void mouseDragged(MouseEvent me) {
        if (window != null) {
          Point pt = new Point();
          pt = window.getLocation(pt);
          int x = pt.x - startPt.x + me.getX();
          int y = pt.y - startPt.y + me.getY();
          window.setLocation(x, y);
        }
      }
    }
    #spanadd
    
    #spanend
    #spanadd
    class CloseIcon implements Icon {
    #spanend
      @Override public void paintIcon(Component c, Graphics g, int x, int y) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.translate(x, y);
        g2.setPaint(Color.WHITE);
        g2.drawLine(4, 4, 11, 11);
        g2.drawLine(4, 5, 10, 11);
        g2.drawLine(5, 4, 11, 10);
        g2.drawLine(11, 4, 4, 11);
        g2.drawLine(11, 5, 5, 11);
        g2.drawLine(10, 4, 4, 10);
        g2.dispose();
      }
    #spanadd
    
    #spanend
      @Override public int getIconWidth() {
        return 16;
      }
    #spanadd
    
    #spanend
      @Override public int getIconHeight() {
        return 16;
      }
    #spanadd
    }
    #spanend
    

参考リンク

参考リンク

コメント

コメント