Efeutar Zoom em janelas swing

13 respostas
kemperacc

Pessoal, alguem jah viu algo do tipo dar zoom em janelas?

tipo o winamp, que vc escolhe o fator 200, 100, 50 etc…

Estou pensando em fazer algo assim, mas se jah existir, vou utilizar ou melhorar…

[]s

13 Respostas

quikkoo

consigo fazer isso no linux, criando um metodo nativo e la trocando o modo de video do X, com a linguagem c, serve?
ja é um passo né…hehehe

mas acho q da pra fazer com a(s) classe(s) GraphicsDevice e DisplayMode

kemperacc

O problema eh que eu nao quero perder a portabilidade do programa, mas mesmo assim, manda o negocio ai, gosto de estudar coisas novas…

[]s e obrigado

kemperacc

Falotu dizer um detalhe, eu nao preciso que a janela funcione enquanto estiver diminuida, pode ser um bitmap mesmo…

Eh pq eu to pensado em implementar um “F12” ou qq outra tecla, que vai miniaturizar todas as janelas, ateh que caibam na tela, entao o usuario clica sobre uma e ela vem para o primeiro plano, tipo no Os X e o XGL

[]s

kemperacc
private void zoomOut(JDialog theWindow){
			double fator = 0.5;
			Dimension w = theWindow.getSize();
			w.setSize(w.getWidth()*fator, w.getHeight()*fator);
			theWindow.setSize(w);
 
                        //Falta fazer um loop percorrendo todos os controles,
                        //mudando a sua dimension tal qual fiz e sua localizacao
                        // com o tamanho da janela
                        //Mas eu nao conseguir achar como percorrer todos os controles
                        // da janela
}
kemperacc

Alguem pode ajudar?

Sami_Koivu

Olá,

Eu fiz muito rapidamente só para testar a idéia. Ele trabalha com bitmap mesmo, ele manda o JDialog se desenhar num BufferedImage e depois usa esse BufferedImage num outro JDialog.

Parece meio bugado, etc, mas vê se serve como base para você.

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;

import javax.swing.JColorChooser;
import javax.swing.JDialog;

public class ZoomWindow extends JDialog {
    Image image = null;

    JDialog dialog = null;

    public ZoomWindow(JDialog dialog, double zoomFactor) {
        super();
        setTitle(dialog.getTitle());
        setJMenuBar(null);
        this.dialog = dialog;
        Rectangle r = dialog.getBounds();
        this.image = new BufferedImage(r.width, r.height,
                BufferedImage.TYPE_INT_RGB);
        
        dialog.paint(this.image.getGraphics());
        r.x *= zoomFactor;
        r.y *= zoomFactor;
        r.width *= zoomFactor;
        r.height *= zoomFactor;
        this.setBounds(r);
        dialog.setVisible(false);
        this.setVisible(true);
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                ZoomWindow.this.setVisible(false);
                ZoomWindow.this.dispose();
                ZoomWindow.this.dialog.setVisible(true);
            }
        });
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(this.image, 0, 0, this.getWidth(), this.getHeight(),
                (ImageObserver) null);
    }

    public static void main(String[] args) throws Exception {
        final JDialog myDialog = new JDialog();
        myDialog.getContentPane().setLayout(new BorderLayout());
        JColorChooser chooser = new JColorChooser();
        myDialog.getContentPane().add(chooser, BorderLayout.CENTER);
        myDialog.pack();
        myDialog.setVisible(true);
        myDialog.repaint();
        Runnable runnable = new Runnable() {
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }
                ZoomWindow zw = new ZoomWindow(myDialog, 0.5);
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }
}
kemperacc

Tah, vou testar, se tiver correcoes, posto aki as mesmas.

Obrigado

kemperacc

Oi, fiz algumas alteracoes na classe,

Retirei o metodo MAIN
E agora a janela “zonificada” fica centralizada em relacao à janela de origem

Sugestao a ser feita: Como fazer para dar um efeito do tipo “blur” para dar uma embaçada leve na janela, pois ao diminur muito, fica estranha.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import javax.swing.JDialog;

public class ZoomWindow extends JDialog {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	Image image = null;

	JDialog dialog = null;

	public ZoomWindow(JDialog dialog, double zoomFactor) {
		super();
		setTitle(dialog.getTitle());
		setJMenuBar(null);
		this.dialog = dialog;
		Rectangle r = dialog.getBounds();
		this.image = new BufferedImage(r.width, r.height,
				BufferedImage.TYPE_INT_RGB);

		dialog.paint(this.image.getGraphics());
		r.x *= zoomFactor;
		r.y *= zoomFactor;
		r.width *= zoomFactor;
		r.height *= zoomFactor;
		this.setBounds(r);

		this.setLocation(dialog.getLocation().x
				+ (dialog.getWidth() / 2 - this.getWidth() / 2), dialog
				.getLocation().y
				+ (dialog.getHeight() / 2) - this.getHeight() / 2);

		dialog.setVisible(false);
		this.setVisible(true);
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				ZoomWindow.this.setVisible(false);
				ZoomWindow.this.dispose();
				ZoomWindow.this.dialog.setVisible(true);
			}
		});
	}

	@Override
	public void paint(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		g2.drawImage(this.image, 0, 0, this.getWidth(), this.getHeight(),
				(ImageObserver) null);
	}
}
quikkoo

se ainda estiver interessado o codigo é esse, dae vc colca em metodos nativos e pronto… funciona, so nao esqeca de linkar a bilioteca durante a compilacao

/* parametros de compilacao: -L/usr/X11R6/lib -lXxf86vm */
#include <X11/extensions/xf86vmode.h>

Display *display = XOpenDisplay(0);
int screen = DefaultScreen(display);
XF86VidModeModeInfo **modes, deskmode;
int modenum;

XF86VidModeGetAllModeLines(GLWin.display, GLWin.screen, &modenum, &modes);

/* save desktop-resolution before switching modes */
deskmode = *modes[0];

XF86VidModeSwitchToMode(display, screen, modes[?]);
XF86VidModeSetViewPort(display, screen, 0, 0);

no lugar da interrogacao vc coloca o indice do modo visual q vc qr, vc oide usar as informacoes dentro da estrutura pra fazer sua escolha
e para voltar ao normal:

XF86VidModeSwitchToMode(display, screen, &deskmode);
XF86VidModeSetViewPort(display,.screen, 0, 0);

definicao da estrutura de dados XF86VidModeModeInfo

typedef struct
{
	unsigned int dotclock;  /* Pixel clock */
	unsigned short hdisplay;  /* Number of display pixels horizontally */
	unsigned short hsyncstart;  /* Horizontal sync start */
	unsigned short hsyncend;  /* Horizontal sync end */
	unsigned short htotal;  /* Total horizontal pixels */
	unsigned short vdisplay;  /* Number of display pixels vertically */
	unsigned short vsyncstart;  /* Vertical sync start */
	unsigned short vsyncend;  /* Vertical sync start */
	unsigned short vtotal;  /* Total vertical pixels */
	unsigned int flags;  /* Mode flags */
	int privsize;  /* Size of private */
	INT32 *private;  /* Server privates */
} XF86VidModeModeInfo;
kemperacc

quikkoo:
se ainda estiver interessado o codigo é esse, dae vc colca em metodos nativos e pronto… funciona, so nao esqeca de linkar a bilioteca durante a compilacao

/* parametros de compilacao: -L/usr/X11R6/lib -lXxf86vm */
#include <X11/extensions/xf86vmode.h>

Display *display = XOpenDisplay(0);
int screen = DefaultScreen(display);
XF86VidModeModeInfo **modes, deskmode;
int modenum;

XF86VidModeGetAllModeLines(GLWin.display, GLWin.screen, &modenum, &modes);

/* save desktop-resolution before switching modes */
deskmode = *modes[0];

XF86VidModeSwitchToMode(display, screen, modes[?]);
XF86VidModeSetViewPort(display, screen, 0, 0);

no lugar da interrogacao vc coloca o indice do modo visual q vc qr, vc oide usar as informacoes dentro da estrutura pra fazer sua escolha
e para voltar ao normal:

XF86VidModeSwitchToMode(display, screen, &deskmode);
XF86VidModeSetViewPort(display,.screen, 0, 0);

definicao da estrutura de dados XF86VidModeModeInfo

typedef struct { unsigned int dotclock; /* Pixel clock */ unsigned short hdisplay; /* Number of display pixels horizontally */ unsigned short hsyncstart; /* Horizontal sync start */ unsigned short hsyncend; /* Horizontal sync end */ unsigned short htotal; /* Total horizontal pixels */ unsigned short vdisplay; /* Number of display pixels vertically */ unsigned short vsyncstart; /* Vertical sync start */ unsigned short vsyncend; /* Vertical sync start */ unsigned short vtotal; /* Total vertical pixels */ unsigned int flags; /* Mode flags */ int privsize; /* Size of private */ INT32 *private; /* Server privates */ } XF86VidModeModeInfo;

Obriago pelo codigo, vou dar uma estudada nele, mas acho que em java vai dar certo

[]s

kemperacc

Pessoal, esta dando SMOOTH jah na janela, mas ainda tem um ultimo problema a resolver…

A janela miniatura gerada tem que ser de tamanho fixo (nao pode sofre resize)

setResizible(false)

Porem, se definir como false, a imagem nao eh printada…

Segue a versao “quase final” da classe:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import javax.swing.JDialog;

public class ZoomWindow extends JDialog {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	Image image = null;

	JDialog dialog = null;

	Integer correcaoX = 0;

	Integer correcaoY = 0;

	public ZoomWindow(JDialog dialog, double zoomFactor) {
		super();
		setTitle(dialog.getTitle());

		/*
		 * TODO Ao definir como false tah dando pau, nao mostra o bitmap
		 * gerado.. setResizable(false);
		 */
		setJMenuBar(null);
		this.dialog = dialog;
		Rectangle r = dialog.getContentPane().getBounds();

		correcaoY = dialog.getHeight() - dialog.getContentPane().getHeight();
		correcaoX = dialog.getWidth() - dialog.getContentPane().getWidth();

		this.image = new BufferedImage(r.width, r.height,
				BufferedImage.TYPE_INT_RGB);

		r.x *= zoomFactor;
		r.y *= zoomFactor;
		r.width *= zoomFactor;
		r.height *= zoomFactor;
		this.setBounds(r);

		this.setLocation(dialog.getLocation().x
				+ (dialog.getWidth() / 2 - this.getWidth() / 2), dialog
				.getLocation().y
				+ (dialog.getHeight() / 2) - this.getHeight() / 2);

		dialog.getContentPane().paint(this.image.getGraphics());

		image = image.getScaledInstance(r.width, r.height, Image.SCALE_SMOOTH);

		dialog.setVisible(false);
		this.setVisible(true);
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				ZoomWindow.this.setVisible(false);
				ZoomWindow.this.dispose();
				ZoomWindow.this.dialog.setVisible(true);
			}
		});
	}

	@Override
	public void paint(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;

		g2.drawImage(this.image, correcaoX, correcaoY, this.getContentPane()
				.getWidth(), this.getContentPane().getHeight(),
				(ImageObserver) null);
	}
}
quikkoo

sim, tb acho q ficaria melhor usar java, assim vc manteria sua portabilidade, pq vc tenta usar as classes q eu mensionei no inicio, acho q elas fazem a mesma coisa q o codigo q eu postei

Sami_Koivu

Olá,

Legais as melhorias. Fiz um teste rápido aqui, e funcionou mesmo com setResizable(false).

[]s,
Sami

Criado 27 de novembro de 2006
Ultima resposta 28 de nov. de 2006
Respostas 13
Participantes 3