JInternalFrame sem barra de titulo - MDI completo :D

8 respostas
brlima

Pessoal,
Depois de quebrar a cabeça procurando algum jeito de fazer um aplicativo MDI onde o JInternalFrame ocupasse todo o espaço disponivel pelo JDesktopPane, acabei pegando varios pedacinhos e fazendo um exemplo-base bem legal.

Achei bacana fazer um "share" desse codigo, esperando que alguem possa ter outras ideias em cima dele, e compartilhando aqui com agente.

O ocdigo abaixo é um exemplo legalzinho de como fazer com que o JInternalFrame ocupe todo o espaço. O problema é que uma vez ocupado, para poder retornar ao estado normal, o jeito que consegui foi criando um menu pra controlar isso. Pensei em poder colocar um iconezinho pra redimensionar a jenela, mas colocar um iconexinho no JFrame deve ser bizarro ne :D :twisted:

Bem, se alguem conseguir, acho que ficaria show.

Resumindo: O codigo abaixo tem uma JFrame com um JDesktopPane. No JFrame tem um menu para:
- Criar um JInternalFrame com titulo personalizado;
- Maiximizar, Minimizar, Restaurar e Fechar o internalFrame selecionado.

Abraços!

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.JWindow;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameListener;

/**
 * 
 * @author Bruno Rios Lima
 */
public class SampleDesktopFrame extends JFrame{

	private JDesktopPane pane = new JDesktopPane();
	// guarda o frame atualmente selecionado para trabalhar com ele
	// nas opcçoes de menu
	private MyIF selectedFrame = null;
	
	public SampleDesktopFrame(){
		
		super("Sample DesktopPane");
		setJMenuBar(getWindowMenuBar());
		getContentPane().add(pane);
		setSize(800,600);
		show();
		
		addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		
	}
	
	public void setSelectedFrame(MyIF frame){
		selectedFrame = frame;
	}
	
	/**
	 * Cria o internalframe e devolve a referencia
	 */
	public JInternalFrame getFrame(String title){
		MyIF iFrame = new MyIF(title, this);
		iFrame.setMaximizable(true);
		iFrame.setResizable(true);
		iFrame.setIconifiable(true);
		iFrame.setFrameIcon(null);
		iFrame.setSize(300,300);
		iFrame.show();
		// Seta o frame criado como o selecioando
		selectedFrame = iFrame;
		return iFrame;
	}
	
	/**
	 * Devolve a barra de menu para trabalhar com a janela selecionada 
	 */
	public JMenuBar getWindowMenuBar(){
		
		// adiciona menu para controlar a janela selecionada
		JMenuBar menubar = new JMenuBar();
		JMenu menuWindow = new JMenu("Janela");
		JMenuItem itemCriar = new JMenuItem("Criar");
		JSeparator separador1 = new JSeparator();
		JMenuItem itemMaximizar = new JMenuItem("Maximizar");
		JMenuItem itemMinimizar = new JMenuItem("Minimizar");
		JMenuItem itemRestore = new JMenuItem("Restaurar");
		JMenuItem itemFechar = new JMenuItem("Fechar");
		
		itemRestore.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				// restore window selected
				selectedFrame.restoreTitleBar();
				try{
					if( selectedFrame.isMaximum() )
						selectedFrame.setMaximum(false);
					if( selectedFrame.isIcon() )
						selectedFrame.setIcon(false);
				}catch(PropertyVetoException pe){}
			}
		});
		
		itemMaximizar.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					if( selectedFrame.isIcon() )
						selectedFrame.setIcon(false);
					selectedFrame.setMaximum(true);
				}catch(PropertyVetoException pe){}
			}
		});
		
		itemMinimizar.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					if( selectedFrame.isMaximum() )
						selectedFrame.setMaximum(false);
					selectedFrame.setIcon(true);
				}catch(PropertyVetoException pe){}
			}
		});
		
		itemFechar.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				try{
					selectedFrame.setClosed(true);
				}catch(PropertyVetoException pe){}
			}
		});
		
		itemCriar.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				String title = JOptionPane.showInputDialog(null, "Informe o titulo da nova janela:");
				pane.add(getFrame(title));
			}
		});
		
		menubar.add(menuWindow);
		menuWindow.add(itemCriar);
		menuWindow.add(separador1);
		menuWindow.add(itemMaximizar);
		menuWindow.add(itemMinimizar);
		menuWindow.add(itemRestore);
		menuWindow.add(itemFechar);
		
		return menubar;
		
	}
	
	public static void main(String[] args) {
		new SampleDesktopFrame();
	}
}

/**
 * Classe que extende a JInternalFrame para implementar alguns metodos
 * para esconder a barra de titulo e restaurar quando solicitado.
 * 
 * Recebe como parametro do contrutor o FramePai para poder controlar
 * o internalFrame selecionado. Adicionar eventos para saber quando ganhou
 * foco para marcar como item atual.
 * 
 * Altera tambem o titulo do frame principal e restaura quando devido.
 * 
 * @author Bruno Rios Lima
 */
class MyIF extends JInternalFrame{
	
	private JComponent oldBar = ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane();
	private Dimension oldDim = null;
	private SampleDesktopFrame framePrincipal = null;
	private String originalTitleFromFrame = "";
	
	public MyIF(String title, SampleDesktopFrame frame_principal){
		super(title);
		framePrincipal = frame_principal;
		originalTitleFromFrame = frame_principal.getTitle();
		addPropertyChangeListener(new PropertyChangeListener(){
			public void propertyChange(PropertyChangeEvent e){
				String name = e.getPropertyName();
				if(name.equals(JInternalFrame.IS_MAXIMUM_PROPERTY)){
					if( isMaximum ){
						removeTitlBar();
						framePrincipal.setTitle(originalTitleFromFrame + " ["+ getTitle() +"]");
					}else{
						restoreTitleBar();
						framePrincipal.setTitle(originalTitleFromFrame);
					}
				}
				if(name.equals(JInternalFrame.IS_SELECTED_PROPERTY)){
					framePrincipal.setSelectedFrame(MyIF.this);
				}
			}
		});
	}
	
	/**
	 * Esconde a barra de titulo
	 */
	public void removeTitlBar(){
		oldBar = ((javax.swing.plaf.basic.BasicInternalFrameUI) getUI()).getNorthPane();
		oldDim = oldBar.getPreferredSize(); 
		oldBar.setSize(0,0);
		oldBar.setPreferredSize(new Dimension(0,0));
		repaint();
	}
	
	/**
	 * Mostra a barra de titulo do internalFrame
	 */
	public void restoreTitleBar(){
		oldBar.setPreferredSize(oldDim);
		repaint();
	}
	
}

8 Respostas

Hempx

Testei aqui, ficou bem legal…!!!
:arrow: Talvez aparecer um pop up qd vc clicar o botão direito em cima da janela mostrar as opções de maxi… minimizar… tbm seria uma boa.
:arrow: Ou talvez um double click com o botão direito restaurava a janela para seu tamanho normal!..

Parabéns :wink:
talvez até utilize um projeto meu aqui…

brlima

“Hempx”:
Testei aqui, ficou bem legal…!!!
:arrow: Talvez aparecer um pop up qd vc clicar o botão direito em cima da janela mostrar as opções de maxi… minimizar… tbm seria uma boa.
:arrow: Ou talvez um double click com o botão direito restaurava a janela para seu tamanho normal!..

Parabéns :wink:
talvez até utilize um projeto meu aqui…

Valeu! :smiley:

Até pensei nessas coisas, mas fiquei pensando no monte de componente que pode ter uma tela: onde o cara vai clicar pra aparecer o popup ou dar duplo-clique?

R

muito bom!!

M

Opa, beleza!!Ficou legal!!O que é feio nas internals, na minha opinião, é barra de títulos!!Feio demais!!!Inda bem que você escondeu ela!! :lol:

ViniGodoy

Muito legal.

Mas a dúvida é… vale a pena manter um código desse só para se livrar da barra de título?

Fizemos algumas coisas parecidas aqui, e poucas realmente valeram a pena.

debug

ViniGodoy

vc poderia dizer porque vc mencionou "poucas realmente valeram a pena. " ???

Tipo alguem tem outro exemplo para eliminar a barra do JInternalFrame?

estou iniciando em java e vou precisar eliminar a barra do JIntenalFrame :wink:

vlw!

ViniGodoy

Não vale a pena pq geralmente isso é uma neura só do programador, não do cliente. Também, é fácil convence-lo de que no Java não tem como fazer isso.

Alterar algo assim é complexo, aumenta os custos de manutenção e dificilmente gera um resultado ideal. Fora que, se vc faz testes na sua interface de usuário, esse código personalizado também vai te complicar.

Novamente eu pergunto. Vale a pena pagar todo esse custo só por essa pequena mudança gráfica?

debug

compreende seu ponto de vista, realmente é muito codigo para um detalhe.
mas no meu caso eu vou precisar mesmo devido qq espaco a mais na minha aplicacao é bem vinda :slight_smile:

Sem falar que tem monte de parpiteiros hehe

Caso conheca outra maneira, nao desfazendo que o brlima fez :slight_smile: , será be vindo

De qq maneira obrigado pela iniciativa do brlima e sugestoes dos demais.

tks!

Criado 8 de setembro de 2004
Ultima resposta 5 de mai. de 2008
Respostas 8
Participantes 6