package de.brainiac.sudoku.controller;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.BorderLayout;
/**
* GraphicExtendContainer erzeugt ein JPanel welches mit einem Graphischen Rahmen umrahmt ist. Der Rahmen kann zusammengeschoben werden.
* Auf dem Panel können andere Componenten angebracht werden addComponent(). Beim zusammengeklappent Rahmen werden die enthaltenen
* Componenten nicht angezeigt. Diese sind nur sichtbar wenn der Rahmen ausgefahren ist.
*
* @author Brainiac
*/
public class GraphicExtendContainer extends JPanel implements ActionListener {
private ImageIcon panelTop, panelBottom, frameTop, frameBottom, frameLeft, frameCenter, frameRight;
private boolean isOpend, isOpening, isClosing, isOpeningUppwards;
private int panelTopHeight, panelTopWidth, panelBottomHeight, panelBottomWidth, panelOpenHeight, panelClosedHeight, panelOpendHeight, panelWidth;
private int frameTopHeight, frameTopWidth, frameBottomHeight, frameBottomWidth, frameLeftWidth, frameCenterWidth, frameRightWidth;
private int currentPanelOpendHeight;
private int currentFrameTopPosition, currentFrameBottomPosition, currentCenterHeight, topGap, bottomGap, containerHeight;
private int actualPosPanelTop, actualPosPanelBottom, actualPosFrameTop, actualPosFrameBottom, actualPosFrameCenter;
private int animationDelay = 100;
private Timer animationTimer;
private JPanel container;
/**
* GraphicExtendContainer constructor erzeugt das aufklappbare JPanel.
* @param panelTop der obere Rand des Bildes/Rahmen der auch im geschlossenen Zustand angezeigt wird.
* @param frameTop der obere Rand des Bildes/Rahmen der nur im geoeffneten Zustand angezeigt wird.
* @param frameLeft der linke Rand des Bildes/Rahmen der nur im geoeffneten Zustand angezeigt wird.
* Er wird beliebig verlängert umd die benötigte Größe zu erreichen.
* @param frameCenter der zentrale Hintergrund des Bildes/Rahmen der nur im geoeffneten Zustand angezeigt wird.
* Er wird beliebig verlängert umd die benötigte Größe zu erreichen.
* @param frameRight der rechte Rand des Bildes/Rahmen der nur im geoeffneten Zustand angezeigt wird.
* Er wird beliebig verlängert umd die benötigte Größe zu erreichen.
* @param frameBottom der untere Rand des Bildes/Rahmen der nur im geoeffneten Zustand angezeigt wird.
* @param panelBottom der untere Rand des Bildes/Rahmen der auch im geschlossenen Zustand angezeigt wird.
*/
public GraphicExtendContainer(ImageIcon panelTop, ImageIcon panelBottom, ImageIcon frameTop, ImageIcon frameBottom, ImageIcon frameLeft, ImageIcon frameCenter, ImageIcon frameRight) {
this.panelTop = panelTop;
this.panelBottom = panelBottom;
this.frameTop = frameTop;
this.frameBottom = frameBottom;
this.frameLeft = frameLeft;
this.frameLeft = frameLeft;
this.frameCenter = frameCenter;
this.frameRight = frameRight;
calculateDimensions();
setLayout(null);
container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
container.setOpaque(false);
container.setBounds(frameLeftWidth, panelTopHeight+topGap, frameCenterWidth, panelOpenHeight);
add(container);
isOpend = false;
currentPanelOpendHeight = 0;
currentFrameTopPosition = panelTopHeight-frameTopHeight;
currentFrameBottomPosition = 0;
currentCenterHeight = 1;
animationTimer = new Timer(animationDelay, this);
//setOpaque(false);
isOpeningUppwards = true;
addMouseListener(
new MouseAdapter() {
public void mouseClicked(MouseEvent event) {
int mousex = event.getX();
int mousey = event.getY();
if (isOpend) {
if ( (mousex > -1 && mousex < panelTopWidth && mousey > -1 && mousey < panelTopHeight) ||
(mousex > -1 && mousex < panelBottomWidth && mousey > panelTopHeight+frameTopHeight+panelOpenHeight+frameBottomHeight-1 && mousey < panelOpendHeight+1) ) {
isOpend = false;
isClosing = true;
currentPanelOpendHeight = panelOpenHeight;
//currentFrameTopPosition = panelTopHeight;
//currentFrameBottomPosition = panelTopHeight+panelOpenHeight-frameBottomHeight;
//currentFrameRightLeftHeight = panelOpenHeight - frameTopHeight - frameBottomHeight;
animationTimer.start();
}
} else {
if (isOpeningUppwards) {
if (mousex > -1 && mousex < panelWidth && mousey > panelOpendHeight-panelClosedHeight-1 && mousey < panelOpendHeight) {
isOpening = true;
currentPanelOpendHeight = 0;
actualPosPanelTop = panelOpendHeight-panelBottomHeight-panelTopHeight;
actualPosFrameTop = panelOpendHeight-panelBottomHeight-frameTopHeight;
actualPosFrameCenter = panelOpendHeight-panelBottomHeight;
actualPosFrameBottom = panelOpendHeight-panelBottomHeight;
actualPosPanelBottom = panelOpendHeight-panelBottomHeight;
animationTimer.start();
}
} else {
if (mousex > -1 && mousex < panelWidth && mousey > -1 && mousey < panelClosedHeight) {
isOpening = true;
currentPanelOpendHeight = 0;
actualPosPanelTop = 0;
actualPosFrameTop = panelTopHeight-frameTopHeight;
actualPosFrameCenter = panelTopHeight-1;
actualPosFrameBottom = panelTopHeight;
actualPosPanelBottom = panelTopHeight;
animationTimer.start();
}
}
}
repaint();
}
}
);
}
public void actionPerformed(ActionEvent event) {
if (isOpening)
doCenterOpenAnimation();
else if (isClosing)
doCloseAnimation();
}
public void addComponent(Component component) {
container.add(component);
setComponentsVisible(false);
calculateDimensions();
}
public void addGap(int i) {
container.add(Box.createVerticalStrut(i));
calculateDimensions();
}
public Dimension getMaximumSize() {
return new Dimension(panelWidth, panelOpendHeight);
}
public Dimension getMinimumSize() {
return new Dimension(panelWidth, panelOpendHeight);
}
public Dimension getPreferredSize() {
return new Dimension(panelWidth, panelOpendHeight);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (isOpend) {
paintOpend(g);
} else if (!isOpening && !isClosing) {
paintClosed(g);
} else if (isOpening) {
paintOpening(g);
} else if (isClosing) {
//paintClosing(g);
}
}
public void paintOpend(Graphics g) {
panelTop.paintIcon(this, g, 0, 0);
frameTop.paintIcon(this, g, 0, panelTopHeight);
for (int x = 0; x < panelOpenHeight; x++) {
frameLeft.paintIcon(this, g, 0, panelTopHeight+frameTopHeight+x);
frameCenter.paintIcon(this, g, frameLeftWidth, panelTopHeight+frameTopHeight+x);
frameRight.paintIcon(this, g, frameLeftWidth+frameCenterWidth, panelTopHeight+frameTopHeight+x);
}
frameBottom.paintIcon(this, g, 0, panelTopHeight+frameTopHeight+panelOpenHeight);
panelBottom.paintIcon(this, g, 0, panelTopHeight+frameTopHeight+panelOpenHeight+frameBottomHeight);
}
public void paintClosed(Graphics g) {
if (isOpeningUppwards) {
panelTop.paintIcon(this, g, 0, panelOpendHeight-panelBottomHeight-panelTopHeight);
panelBottom.paintIcon(this, g, 0, panelOpendHeight-panelBottomHeight);
} else {
panelTop.paintIcon(this, g, 0, 0);
panelBottom.paintIcon(this, g, 0, panelTopHeight);
}
}
public void paintOpening(Graphics g) {
if (isOpeningUppwards) {
panelTop.paintIcon(this, g, 0, actualPosPanelTop);
frameTop.paintIcon(this, g, 0, actualPosFrameTop);
for (int x = 0; x < currentCenterHeight; x++) {
frameLeft.paintIcon(this, g, 0, actualPosFrameCenter-x);
frameCenter.paintIcon(this, g, frameLeftWidth, actualPosFrameCenter-x);
frameRight.paintIcon(this, g, frameLeftWidth+frameCenterWidth, actualPosFrameCenter-x);
}
frameBottom.paintIcon(this, g, 0, actualPosFrameBottom);
panelBottom.paintIcon(this, g, 0, actualPosPanelBottom);
} else {
for (int x = 0; x < currentCenterHeight; x++) {
frameLeft.paintIcon(this, g, 0, actualPosFrameCenter+x);
frameCenter.paintIcon(this, g, frameLeftWidth, actualPosFrameCenter+x);
frameRight.paintIcon(this, g, frameLeftWidth+frameCenterWidth, actualPosFrameCenter+x);
}
frameTop.paintIcon(this, g, 0, actualPosFrameTop);
panelTop.paintIcon(this, g, 0, actualPosPanelTop);
frameBottom.paintIcon(this, g, 0, actualPosFrameBottom);
panelBottom.paintIcon(this, g, 0, actualPosPanelBottom);
}
/*System.out.println("panelTopHeight: " + panelTopHeight + " | panelTopStartPosition: " + 0);
System.out.println("frameTopHeight: " + frameTopHeight + " | frameTopStartPosition: " + panelTopHeight);
int frameCenterStartPosition = panelTopHeight+frameTopHeight;
System.out.println("frameCenterHeight: " + panelOpenHeight + " | frameCenterStartPosition: " + frameCenterStartPosition);
int frameBottomStartPosition = panelTopHeight+panelOpenHeight-frameBottomHeight;
System.out.println("frameBottomHeight: " + frameBottomHeight + " | frameBottomStartPosition: " + frameBottomStartPosition);
int panelBottomStartPosition = panelTopHeight+panelOpenHeight;
System.out.println("panelBottomHeight: " + panelBottomHeight + " | panelBottomStartPosition: " + panelBottomStartPosition);*/
}
public void setOpend(boolean b) {
isOpend = b;
repaint();
setComponentsVisible(b);
}
public void setTopGap(int i) {
topGap = i;
calculateDimensions();
}
public void setBottomGap(int i) {
bottomGap = i;
calculateDimensions();
}
private void calculateDimensions() {
panelTopHeight = panelTop.getIconHeight();
panelTopWidth = panelTop.getIconWidth();
panelBottomHeight = panelBottom.getIconHeight();
panelBottomWidth = panelBottom.getIconWidth();
frameTopHeight = frameTop.getIconHeight();
frameTopWidth = frameTop.getIconWidth();
frameBottomHeight = frameBottom.getIconHeight();
frameBottomWidth = frameBottom.getIconWidth();
frameLeftWidth = frameLeft.getIconWidth();
frameCenterWidth = frameCenter.getIconWidth();
frameRightWidth = frameRight.getIconWidth();
panelClosedHeight = panelTopHeight + panelBottomHeight;
if (container != null) {
containerHeight = 0;
for (int i = 0; i < container.getComponents().length; i++)
containerHeight += container.getComponents()[i].getMinimumSize().height;
container.setBounds(frameLeftWidth, panelTopHeight+topGap, frameCenterWidth, containerHeight);
if (containerHeight + topGap + bottomGap < frameTopHeight + frameBottomHeight + 1) {
panelOpenHeight = frameTopHeight + frameBottomHeight + 1;
} else {
panelOpenHeight = containerHeight - frameTopHeight - frameBottomHeight + topGap + bottomGap;
}
} else
panelOpenHeight = frameTopHeight + frameBottomHeight + 1;
panelOpendHeight = panelClosedHeight + frameTopHeight + frameBottomHeight + panelOpenHeight;
if (panelTopWidth > panelBottomWidth)
panelWidth = panelTopWidth;
else
panelWidth = panelBottomWidth;
}
private void doCenterOpenAnimation() {
if (currentPanelOpendHeight < panelOpenHeight+frameTopHeight+frameBottomHeight) {
currentPanelOpendHeight++;
if (isOpeningUppwards) {
//PanelTop
if (actualPosPanelTop > 0)
actualPosPanelTop--;
//FrameTop
if (actualPosFrameBottom == panelOpendHeight-panelBottomHeight-frameBottomHeight && actualPosFrameTop > panelTopHeight)
actualPosFrameTop--;
//frameCenter
if (currentPanelOpendHeight >= frameTopHeight+frameBottomHeight) {
actualPosFrameCenter = panelOpendHeight-frameBottomHeight-panelBottomHeight-1;
currentCenterHeight = currentPanelOpendHeight - frameTopHeight - frameBottomHeight + 1;
}
//frameBottom
/*if (currentPanelOpendHeight < frameTopHeight * 2) {
actualPosFrameTop++;
actualPosFrameBottom--;
}*/
if (actualPosFrameBottom > panelOpendHeight - panelBottomHeight - frameBottomHeight)
actualPosFrameBottom--;
}
else {
//frameTop
if (actualPosFrameTop < panelTopHeight)
if (currentPanelOpendHeight%2 == 1) {
actualPosFrameTop++;
actualPosFrameBottom--;
}
//frameCenter
if (currentPanelOpendHeight >= frameTopHeight+frameBottomHeight) {
actualPosFrameCenter = panelTopHeight+frameTopHeight;
currentCenterHeight = currentPanelOpendHeight - frameTopHeight - frameBottomHeight + 1;
}
//frameBottom
if (actualPosFrameTop == panelTopHeight && actualPosFrameBottom < panelTopHeight+frameTopHeight+panelOpenHeight)
actualPosFrameBottom++;
//panelBottom
if (actualPosPanelBottom < panelTopHeight+frameTopHeight+panelOpenHeight+frameBottomHeight)
actualPosPanelBottom++;
}
}
else {
setComponentsVisible(true);
animationTimer.stop();
isOpening = false;
isOpend = true;
}
repaint();
}
private void doCloseAnimation() {
setComponentsVisible(false);
if (currentFrameTopPosition > panelTopHeight-frameTopHeight)
if (currentPanelOpendHeight%2 == 0)
currentFrameTopPosition--;
if (currentFrameBottomPosition > 0)
if (currentPanelOpendHeight%2 == 0)
currentFrameBottomPosition--;
if (currentPanelOpendHeight > frameTopHeight + frameBottomHeight)
currentCenterHeight--;
if (currentPanelOpendHeight > 0)
currentPanelOpendHeight--;
else {
animationTimer.stop();
isClosing = false;
isOpend = false;
}
repaint();
}
private void setComponentsVisible(boolean b) {
for (int x = 0; x < container.getComponents().length; x++) {
container.getComponents()[x].setVisible(b);
container.getComponents()[x].setEnabled(b);
}
}
public void setOpenUppwards(boolean b) {
isOpeningUppwards = b;
}
}