Undecorated JFrame i animacje zmiany jego stanu

0

Witam!
Od niedawna uczę się programować w Javie. Aktualnie próbuję stworzyć własny wygląd JFrame dla moich aplikacji. O ile stworzenie paska tytuły i przycisków funkcyjnych nie sprawiło mi kłopotów, problemy pojawiły się później, mianowicie:

Podstawowy JFrame
user image
Podczas zmiany stanu programu (otwierania, zamykania, minimalizacji lub maksymalizacji) okno programu zdaje się być animowane.
Zamknięcie sprawia że okno staję się lekko przezroczyste i zmniejsza się do środka, natomiast minimalizacja daje efekt kurczenia się okna i stopniowego przesunięcia go na pasek start.

JFrame napisany przeze mnie
user image
Nie posiada żadnej z tych animacja (okno po prostu znika, zarówno podczas zamykania jak i minimalizacji). Zakładam że spowodowane jest to użyciem setUndecorated(true).
Zacząłem więc szukać programów które posiadają własny styl paska tytuły. Jak się okazało wiele z nich posiada animacje wspominane pod pierwszym obrazkiem (np. Steam).

Stąd też moje pytanie: czy mogę jakoś zaimplementować te animacje w moim JFrame czy może muszę napisać je od początku?

Kod mojego programu:

package test2;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Test2 extends JFrame{
    
    Point point = new Point();

    public Test2(){
        setSize(new Dimension(400, 400));
        setLocation(200, 200);
        setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
        setUndecorated(true);
        
        panel_title();
        panel_minimalize();
        panel_close();
        panel_content();
        
        setVisible(true);
    }
    
    void panel_title(){
        JLabel title = new JLabel();
        title.setPreferredSize(new Dimension(300, 25));
        title.setText(" Jframe Test2");
        title.setBackground(new Color(14, 29, 43));
        title.setForeground(new Color(255, 255, 255));
        title.setOpaque(true);
        
        title.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                point.x = e.getX();
                point.y = e.getY();
            }
        });
        
        title.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e){
                Point p = getLocation();
                setLocation(p.x + e.getX() - point.x, p.y + e.getY() - point.y);
            }
        });
        
        add(title);
    }
    
    void panel_close(){
        JButton close = new JButton();
        close.setPreferredSize(new Dimension(60, 25));
        close.setText("x");
        close.setBackground(new Color(217, 30, 24));
        close.setForeground(new Color(255, 255, 255));
        close.setBorder(BorderFactory.createEmptyBorder());
        close.setContentAreaFilled(true);
        close.setFocusPainted(false);
        
        close.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        
        add(close);
    }
    
    void panel_minimalize(){
        JButton minimalize = new JButton();
        minimalize.setPreferredSize(new Dimension(40, 25));
        minimalize.setText("_");
        minimalize.setBackground(new Color(14, 29, 43));
        minimalize.setForeground(new Color(255, 255, 255));
        minimalize.setBorder(BorderFactory.createEmptyBorder());
        minimalize.setContentAreaFilled(true);
        minimalize.setFocusPainted(false);
        
        minimalize.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setState(ICONIFIED);
            }
        });
        
        add(minimalize);
    }
    
    void panel_content(){
        JPanel content = new JPanel();
        content.setPreferredSize(new Dimension(400, 375));
        content.setBackground(new Color(34, 49, 63));
        
        add(content);
    }
    
    public static void main(String[] args) {
        new Test2();
    }
    
}

Przy okazji chciałbym się też dowiedzieć, czy opłaca się pisać własne JFrame, czy może powinienem korzystać z tego podstawowego (setUndecorated(false))?

0

Ustawiając setUndecorated(true) pozbawiasz się wszelkich animacji. Musiałbyś je napisać na własną rękę. Z tego względu IMHO nie opłaca się tego używać.

0

@Haskell, dzięki za odpowiedź.

Wydaje mi się, że dla zwykłych testów i eksperymentów z programowaniem mógłbym spróbować napisać własne animacje zmiany stanu okna dla mojego JFrame.

Chyba najprostszym sposobem będzie:

  • wykonanie zrzutu okna aplikacji i zapisanie go do ImageIcon
  • ustawienie widoczności wszystkich elementów w JFrame na false
  • ustawienie zrzutu jako tła dla JFrame
  • animowanie okna (ustawienie przezroczystości, zmiana rozmiaru i pozycji na ekranie)

Chciałbym dowiedzieć się jeszcze dwóch rzeczy:
Po pierwsze, czy animacje napisane przeze mnie (np. sposobem przedstawionym powyżej) mogą wywołać większe obciążenie komputera niż te zawarte w podstawowym oknie?
Po drugie, czy napisanie własnego JFrame w oparciu o setUndecorated(true) niesie ze sobą jeszcze jakieś minusy (poza brakiem animacji)?

1 użytkowników online, w tym zalogowanych: 0, gości: 1