Page 1 of 1

JDesktopPane and JInternalFrame Rate Topic: -----

#1 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8316
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Posted 08 January 2012 - 06:36 PM

*
POPULAR

How many times the question was asked in the forum: How do I put a Frame inside a JFrame ?
Actually you just can't :) For that you need a JDesktopPane, inserted into a JFrame, and JInternalFrame into that JDesktopPane.

This tutorial will show you the basic of these two components.
First a JDesktopPane, inserted as usual into a JFrame, inserted into this JDesktopPane, 10 JInternalFrame.

In the real life, the JInternalFrame will be very different entities with their characteristics, here, to simplify the demo, we will have 10 instances of the same frame.

All these internal frames have 2 buttons. One to give the "focus" to the previous frame one to set as "active" frame the next one. Each internal frame has also a menu to close it. Closing it can also be done using the X on the Window title. When closed, the JInternalFrame calls its JDesktopPane to be removed from its list.

When the next/previous JInternalFrame should be displayed, the JDestopPane checks if that InternalFrame is iconified or not, if it is the case it expands it.

MyDesktop.java that will create the 10 JInternalFrame
import javax.swing.*;
import java.util.*;      // for the ArrayList

public class MyDesktop extends JDesktopPane {

	// a JDesktopPane
	// it contains an array of 10 JInternal frame that it will create
	// it has simply 3 methods:
	// one to give focus to the previous JInternalFrame
	// one one to give focus to the next one
	// one to remove a JInternal frame that is closed from the list
	
	// to keep a list of the InternalFrame that I display
	ArrayList<MyInternalFrame> al;
	
	MyDesktop() {
		// create 10 InternalFrame
		al = new ArrayList<MyInternalFrame>();
		for(int i = 0; i < 10; i++) {
			MyInternalFrame mif = new MyInternalFrame(this, i);
			// put them in cascade
			mif.setBounds(i * 30, i * 30, 200, 100);
			add(mif);				// add to the desktop frame
			al.add(mif);			// add to my list
		}
		// make the fist one as the active one
		try {
			al.get(0).setSelected(true);
		}
		catch(Exception e) {
			// nothing I can do
		}

	}
	
	// called to show next InternalFrame
	void next(int id) {
		nextPrevious(id, +1);   // calls common private method which use a delat +1 or -1
	}
	// called to show the prrevious InternalFrame
	void previous(int id) {
		nextPrevious(id, -1);
	}
	// called internally for next or previous
	private void nextPrevious(int id, int delta) {
		// if no more frame (the arraylist contains only that internal frame)
		int len = al.size();
		if(len <= 1)
			return;
		int i = 0;
		// identify the Internaml Frame that did the call
		for(; i < len; ++i) {
			MyInternalFrame issuer = al.get(i);
			if(issuer.getId() == id)
				break;
		}
		// next of previous
		i += delta;
		// wrap around
		if(i < 0)
			i = len - 1;
		else if(i == len)
			i = 0;
		
		// give focus to that one
		try {
			MyInternalFrame issuer = al.get(i);
			// if it is iconified
			if(issuer.isIcon()) {
				issuer.setIcon(false);   // restore it
			}
			issuer.setSelected(true);
		}
		catch(Exception e) {
			// nothing I can do
		}
	}
	
	// an InternalFrame closes
	void close(int id) {
		// identify the Internaml Frame that did the call
		for(int i = 0; i < al.size(); ++i) {
			MyInternalFrame issuer = al.get(i);
			// and remove it
			if(issuer.getId() == id) {
				al.remove(i);
				break;
			}
		}
		
	}
	
	// to start the whole application
	public static void main(String[] args) {
		// build a JFrame
		JFrame frame = new JFrame("My Desktop Pane");
		// add a JDesktopPane into it
		JDesktopPane jdp = new MyDesktop();
		frame.add(jdp);
		// give the JFrame a Size and make it visible
		frame.setSize(800, 600);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
	}
}



Now the JInternalFrame
it has an InternalFrameListener to change to color YELLOW its background to show more evidently which one is activated

MyInternalFrame.java
package desktop;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

// A class that will be used for all the JInternalFrame
// in real life all the JInternal frame will vary here, just to show the concept, 
// they are simply all the same:
// A Menu to close them
// A previous and a next button to switch which one will be displayed in the JDesktopPane

public class MyInternalFrame extends JInternalFrame implements ActionListener, InternalFrameListener {

	// the JDesktopPane I belong to
	private MyDesktop father;
	private JMenuItem close;
	// buttons to show the previous/next Internal frame
	private JButton previous, next;
	// my Id so my JDesttopPane can identify me
	private int id;
	// the JPanel who's background will change to show which one has the focus
	private JPanel p;

	MyInternalFrame(MyDesktop father, int id)  {
		// make it with all option available
		super("Frame #" + (id+1), true, true, true, true);
		// save who I will call back when a button is click
		this.father = father;
		this.id = id;
		// add the JMenuBar
		JMenuBar mb = new JMenuBar();
		JMenu me = new JMenu("Menu");       // with one pull down menu
		close = new JMenuItem("Close");     // containing "close"
		me.add(close);
		close.addActionListener(this);		// call me back when clicked
		mb.add(me);
		setJMenuBar(mb);
		// a JPanel with the two buttons
		p = new JPanel();
		if(id == 0)
			p.setBackground(Color.YELLOW);
		else
			p.setBackground(Color.LIGHT_GRAY);
		
		previous = new JButton("Previous");
		previous.addActionListener(this);   // call me back when clicked
		p.add(previous);
		next = new JButton("Next");
		next.addActionListener(this);		// call me back when clicked
		p.add(next);
		add(p);
		// listener to receive activate/desctivate events
		addInternalFrameListener(this);
		setVisible(true);
	}

	// returns my Id
	int getId() {
		return id;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		Object o = e.getSource();
		// first test if it is one of the two buttons
		if(o == next) {
			father.next(id);
			return;
		}
		if(o == previous) {
			father.previous(id);
			return;
		}
		
		// so it is the close menu 
		father.close(id);
		dispose();

	}

	// to handle InternalFrameEvent
	// we change the JPanel background color when we become the active InternalFrame or not
	@Override
	public void internalFrameActivated(InternalFrameEvent arg0) {
		p.setBackground(Color.YELLOW);
	}
	@Override
	public void internalFrameDeactivated(InternalFrameEvent arg0) {
		p.setBackground(Color.LIGHT_GRAY);
	}
	@Override
	public void internalFrameClosed(InternalFrameEvent arg0) {
		father.close(id);   // inform my father I do not exist anymore
	}
	@Override
	public void internalFrameClosing(InternalFrameEvent arg0) {
	}
	@Override
	public void internalFrameDeiconified(InternalFrameEvent arg0) {
	}
	@Override
	public void internalFrameIconified(InternalFrameEvent arg0) {
	}
	@Override
	public void internalFrameOpened(InternalFrameEvent arg0) {
	}
}


This post has been edited by pbl: 08 January 2012 - 06:38 PM


Is This A Good Question/Topic? 6
  • +

Page 1 of 1