Soluction for JDesktopPan
To: comp.lang.java.gui
1) Put a JDesktopPane inside a JScrollPane.
2) Set the JDesktopPane's DesktopManager property with this class:
MDIDesktopManager.
myMDIDeskMan=new MDIDesktopManager();
myDeskPane.setDesktopManager(myMDIDeskMan);
3) (optional) set optional's parameters
myMDIDeskMan.setTranslacaoSuave(true); //changes in active
window will scroll slowly to the new active window
myMDIDeskMan.setVelocidadeTranslacao(18); //scroll velocity in
an active window change
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.HashMap;
import java.util.Map;
import javax.swing.DefaultDesktopManager;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
/**
* Classe para sobrescrever o DefaultDesktopManager para os {@link
JDesktopPane},
* dando a ele a capacidade de ajuste no scroll (redimensiona o
preferedSize de acordo,
* para que um {@link JScrollPane} controle sua =E1rea).
* Al=E9m disto, o Manager se preocupa em ajustar o scroll de modo que a
janela ativa
* fique completamente vis=EDvel (dentro do poss=EDvel) na viewport do
scrollpane.
* @author iglezias
*/
public class MDIDesktopManager extends DefaultDesktopManager {
public static final long serialVersionUID = 1;
private Map<JDesktopPane,JInternalFrame> lastFrame = new
HashMap<JDesktopPane,JInternalFrame>(2);
private boolean translacaoSuave=true;
private int velocidadeTranslacao=25;
public MDIDesktopManager() {
super();
}
/**
* @see #setTranslacaoSuave(boolean)
* @return
*/
public boolean isTranslacaoSuave() {
return translacaoSuave;
}
/**
* Se true, eventuais translacoes da view para focalizar
completamente o
* InternalFrame atual ser=E3o suaves (n=E3o instant=E2neas)
* @param translacaoSuave
*/
public void setTranslacaoSuave(boolean translacaoSuave) {
this.translacaoSuave = translacaoSuave;
}
/**
* @see #setVelocidadeTranslacao(int)
* @return
*/
public int getVelocidadeTranslacao() {
return velocidadeTranslacao;
}
/**
* Caso {@link #isTranslacaoSuave()}, define a velocidade com que
esta translacao se dar=E1.
* @param velocidadeTranslacao
*/
public void setVelocidadeTranslacao(int velocidadeTranslacao) {
this.velocidadeTranslacao = velocidadeTranslacao;
}
@Override
public void endResizingFrame(JComponent f) {
super.endResizingFrame(f);
resizeDesktop(f);
}
@Override
public void endDraggingFrame(final JComponent f) {
super.endDraggingFrame(f);
resizeDesktop(f);
}
@Override
public void maximizeFrame(JInternalFrame f) {
super.maximizeFrame(f);
resizeDesktop(f);
}
@Override
public void minimizeFrame(JInternalFrame f) {
super.minimizeFrame(f);
resizeDesktop(f);
}
@Override
public void activateFrame(JInternalFrame f) {
super.activateFrame(f);
lastFrame.put(getDesktopPaneForFrame(f), f);
resizeDesktop(f);
}
@Override
public void closeFrame(JInternalFrame f) {
super.closeFrame(f);
lastFrame.put(getDesktopPaneForFrame(f), null);
resizeDesktop(f);
}
public JScrollPane getScrollPane(JDesktopPane desktop) {
if (desktop!=null && desktop.getParent() instanceof
JViewport) {
JViewport viewPort = (JViewport) desktop.getParent();
if (viewPort.getParent() instanceof JScrollPane)
return (JScrollPane) viewPort.getParent();
}
return null;
}
public JDesktopPane getDesktopPaneForFrame(JComponent frame) {
JDesktopPane result=null;
if (frame.getParent()!=null && (frame.getParent() instanceof
JDesktopPane) ) {
result=(JDesktopPane) frame.getParent();
}
// Component c=frame;
// while (result==null && (c=c.getParent())!=null ) {
// if (c instanceof JDesktopPane) {
// result = (JDesktopPane) c;
// }
// }
return result;
}
protected void resizeDesktop(JComponent f) {
JDesktopPane desktop = this.getDesktopPaneForFrame(f);
JScrollPane scrollPane = getScrollPane(desktop);
if (scrollPane == null) return;
scrollPane.invalidate();
JInternalFrame ultFrame = lastFrame.get(desktop);
if (ultFrame != null && ultFrame.isMaximum()) {
desktop.setPreferredSize(null);
} else {
{ //descobre janelas com x ou y negativos...
int xMenor = Integer.MAX_VALUE, yMenor =
Integer.MAX_VALUE;
// boolean haJanelasCroped=false;
// Rectangle visibleRect =
scrollPane.getViewport().getViewRect();
for (JInternalFrame frm : desktop.getAllFrames()) {
if (frm.isMaximum()) continue;
if (frm.getX() < xMenor) {
xMenor = frm.getX();
}
if (frm.getY() < yMenor) {
yMenor = frm.getY();
}
// if (!visibleRect.contains(frm.getBounds())) {
// haJanelasCroped=true;
// }
}
if (xMenor<0 || yMenor<0 /*|| haJanelasCroped*/)
{ //normaliza todas janelas para ter x e y maior q zero
for (JInternalFrame frm : desktop.getAllFrames())
{
if (frm.isMaximum()) continue;
Point pos=new Point(frm.getLocation());
pos.translate( (xMenor<0)?-xMenor:0 ,
(yMenor<0)?-yMenor:0 );
frm.setLocation(pos);
}
}
}
int larguraCerta = 0, alturaCerta = 0;
for (JInternalFrame frm : desktop.getAllFrames()) {
if (frm.isMaximum()) continue;
if (frm.getX() + frm.getWidth() > larguraCerta) {
larguraCerta = frm.getX() + frm.getWidth();
}
if (frm.getY() + frm.getHeight() > alturaCerta) {
alturaCerta = frm.getY() + frm.getHeight();
}
}
desktop.setPreferredSize(new Dimension(larguraCerta,
alturaCerta));
}
scrollPane.validate();
{ //Se janela nao tiver completamente visivel, mexe no scroll
do viewport para que
//fique completamente visivel...
if (ultFrame!=null && !ultFrame.isMaximum()) {
Rectangle visibleRect =
scrollPane.getViewport().getViewRect();
Rectangle frmBounds = ultFrame.getBounds();
if (!visibleRect.contains(frmBounds)) {
int deslocX=0, deslocY=0;
// Rectangle intersec =
visibleRect.intersection(this.ultFrame.getBounds());
if (frmBounds.x < visibleRect.x) {
//ViewX deve ter deslocamento para esquerda
(<0)
deslocX = frmBounds.x-visibleRect.x;
} else if ((frmBounds.x+frmBounds.width) >
(visibleRect.x+visibleRect.width) ) {
//ViewX deve ter deslocamento para direita
(>0)
deslocX = (frmBounds.x+
Math.min(frmBounds.width,visibleRect.width) )
- (visibleRect.x+visibleRect.width);
}
if (frmBounds.y < visibleRect.y) {
//ViewY deve ter deslocamento para Cima (<0)
deslocY = frmBounds.y-visibleRect.y;
} else if ((frmBounds.y+frmBounds.height) >
(visibleRect.y+visibleRect.height) ) {
//ViewY deve ter deslocamento para Baixo (>0)
deslocY = (frmBounds.y
+Math.min(frmBounds.height,visibleRect.height) )
- (visibleRect.y+visibleRect.height);
}
if (!this.translacaoSuave) {
Point
posicaoView=scrollPane.getViewport().getViewPosition();
posicaoView.translate(deslocX,
deslocY);
scrollPane.getViewport().setViewPosition(posicaoView);
} else {
//Faz deslocamento na view, de forma
progressiva...
// SwingUtilities.invokeLater(
// new
ThreadDeslocaView(scrollPane.getViewport(), deslocX, deslocY,
velocidadeTranslacao)
// );
new Thread(
new
ThreadDeslocaView(scrollPane.getViewport(), deslocX, deslocY,
velocidadeTranslacao)
).run();
}
}
}
}
if (ultFrame!=null) {
ultFrame.repaint();
}
}
}
class ThreadDeslocaView implements Runnable {
private final int dXIni, dYIni;
private final JViewport view;
private final int velocidade;
public ThreadDeslocaView(JViewport viewport, int dx, int dy, int
velocidade) {
this.view = viewport;
this.dXIni = dx;
this.dYIni = dy;
this.velocidade = velocidade;
}
public void run() {
new Thread() {
int dX=dXIni, dY=dYIni;
@Override
public void run() {
int deslocX, deslocY;
((JScrollPane) view.getParent()).invalidate();
// while (dX!=0 || dY!=0) {
// if (dX>0) {
// dX-=1;
// deslocX=1;
// } else if (dX<0) {
// dX+=1;
// deslocX=-1;
// } else {
// deslocX=0;
// }
// if (dY>0) {
// dY-=1;
// deslocY=1;
// } else if (dY<0) {
// dY+=1;
// deslocY=-1;
// } else {
// deslocY=0;
// }
// Point posicaoView=view.getViewPosition();
// posicaoView.translate(deslocX, deslocY);
// ((JScrollPane) view.getParent()).invalidate();
// view.setViewPosition(posicaoView);
// ((JScrollPane) view.getParent()).revalidate();
//// try { sleep(10);
//// } catch (InterruptedException e) {}
// }
while (dX!=0) {
if (dX>0) {
dX-=velocidade;
if (dX<0) {
dX=0;
deslocX=velocidade+dX;
} else {
deslocX=velocidade;
}
} else if (dX<0) {
dX+=velocidade;
if (dX>0) {
dX=0;
deslocX=-velocidade-dX;
} else {
deslocX=-velocidade;
}
} else {
deslocX=0;
}
Point posicaoView=view.getViewPosition();
posicaoView.translate(deslocX, 0);
view.setViewPosition(posicaoView);
((JScrollPane) view.getParent()).revalidate();
}
while (dY!=0) {
if (dY>0) {
dY-=velocidade;
if (dY<0) {
dY=0;
deslocY=velocidade+dY;
} else {
deslocY=velocidade;
}
} else if (dY<0) {
dY+=velocidade;
if (dY>0) {
dY=0;
deslocY=-velocidade-dY;
} else {
deslocY=-velocidade;
}
} else {
deslocY=0;
}
Point posicaoView=view.getViewPosition();
posicaoView.translate(0, deslocY);
view.setViewPosition(posicaoView);
((JScrollPane) view.getParent()).revalidate();
}
}
}.run();
}
}
---
* Synchronet * The Whitehouse BBS --- whitehouse.hulds.com --- check it out free usenet!
--- Synchronet 3.15a-Win32 NewsLink 1.92
Time Warp of the Future BBS - telnet://time.synchro.net:24