Java/Swing JFC/MDI
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
Build multiple document interface by yourself
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.Hashtable;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.LookAndFeel;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.MatteBorder;
import javax.swing.event.MouseInputAdapter;
import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.ruponentUI;
import javax.swing.plaf.FontUIResource;
public class LayeredPaneDemo extends JFrame {
public LayeredPaneDemo() {
super("");
setSize(570, 400);
getContentPane().setBackground(new Color(244, 232, 152));
getLayeredPane().setOpaque(true);
InnerFrame[] frames = new InnerFrame[5];
for (int i = 0; i < 5; i++) {
frames[i] = new InnerFrame("InnerFrame " + i);
frames[i].setBounds(50 + i * 20, 50 + i * 20, 200, 200);
getLayeredPane().add(frames[i]);
}
WindowListener l = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
};
addWindowListener(l);
setVisible(true);
}
public static void main(String[] args) {
new LayeredPaneDemo();
}
}
class InnerFrame extends JPanel {
private static String IMAGE_DIR = "mdi" + java.io.File.separator;
private static ImageIcon PRESS_RESTORE_BUTTON_ICON = new ImageIcon(
IMAGE_DIR + "pressrestore.gif");
private static ImageIcon PRESS_ICONIZE_BUTTON_ICON = new ImageIcon(
IMAGE_DIR + "pressiconize.gif");
private static final int WIDTH = 200;
private static final int HEIGHT = 200;
private static final int TITLE_BAR_HEIGHT = 25;
private static Color TITLE_BAR_BG_COLOR = new Color(108, 190, 116);
private String title;
private JLabel titleLabel;
private boolean isIconified;
private JPanel titlePanel;
private JPanel contentPanel;
private JPanel buttonPanel;
private JPanel buttonWrapperPanel;
private InnerFrameButton iconizeButton;
private InnerFrameButton closeButton;
public InnerFrame(String t) {
title = t;
setLayout(new BorderLayout());
createTitleBar();
contentPanel = new JPanel();
add(titlePanel, BorderLayout.NORTH);
add(contentPanel, BorderLayout.CENTER);
}
public void toFront() {
if (getParent() instanceof JLayeredPane)
((JLayeredPane) getParent()).moveToFront(this);
}
public void close() {
if (getParent() instanceof JLayeredPane) {
JLayeredPane jlp = (JLayeredPane) getParent();
jlp.remove(InnerFrame.this);
jlp.repaint();
}
}
public void setIconified(boolean b) {
isIconified = b;
if (b) {
setBounds(getX(), getY(), WIDTH, TITLE_BAR_HEIGHT);
} else {
setBounds(getX(), getY(), WIDTH, HEIGHT);
revalidate();
}
}
public boolean isIconified() {
return isIconified;
}
// Title Bar
public void createTitleBar() {
titlePanel = new JPanel() {
public Dimension getPreferredSize() {
return new Dimension(InnerFrame.WIDTH,
InnerFrame.TITLE_BAR_HEIGHT);
}
};
titlePanel.setLayout(new BorderLayout());
titlePanel.setOpaque(true);
titlePanel.setBackground(TITLE_BAR_BG_COLOR);
titleLabel = new JLabel(title);
titleLabel.setForeground(Color.black);
buttonWrapperPanel = new JPanel();
buttonWrapperPanel.setOpaque(false);
buttonPanel = new JPanel(new GridLayout(1, 2));
buttonPanel.setOpaque(false);
buttonPanel.setAlignmentX(0.5f);
buttonPanel.setAlignmentY(0.5f);
buttonWrapperPanel.add(buttonPanel);
titlePanel.add(titleLabel, BorderLayout.CENTER);
titlePanel.add(buttonWrapperPanel, BorderLayout.EAST);
InnerFrameTitleBarMouseAdapter iftbma = new InnerFrameTitleBarMouseAdapter(
this);
titlePanel.addMouseListener(iftbma);
titlePanel.addMouseMotionListener(iftbma);
}
// title bar mouse adapter for frame dragging
class InnerFrameTitleBarMouseAdapter extends MouseInputAdapter {
InnerFrame innerFrame;
int xDifference, yDifference;
boolean isDragging;
public InnerFrameTitleBarMouseAdapter(InnerFrame inf) {
innerFrame = inf;
}
public void mouseDragged(MouseEvent e) {
if (isDragging)
innerFrame.setLocation(e.getX() - xDifference + getX(), e.getY()
- yDifference + getY());
}
public void mousePressed(MouseEvent e) {
innerFrame.toFront();
xDifference = e.getX();
yDifference = e.getY();
isDragging = true;
}
public void mouseReleased(MouseEvent e) {
isDragging = false;
}
}
// custom button class for title bar
class InnerFrameButton extends JButton {
Dimension size;
public InnerFrameButton(ImageIcon ii) {
super(ii);
size = new Dimension(ii.getIconWidth(), ii.getIconHeight());
setOpaque(false);
setContentAreaFilled(false);
setBorder(null);
}
public Dimension getPreferredSize() {
return size;
}
public Dimension getMinimumSize() {
return size;
}
public Dimension getMaximumSize() {
return size;
}
}
}
class InnerFrameUI extends javax.swing.plaf.PanelUI {
private static InnerFrameUI frameUI;
protected static Color DEFAULT_TITLE_BAR_BG_COLOR;
protected static Color DEFAULT_SELECTED_TITLE_BAR_BG_COLOR;
protected static Color DEFAULT_TITLE_BAR_FG_COLOR;
protected static Color DEFAULT_SELECTED_TITLE_BAR_FG_COLOR;
protected static Font DEFAULT_TITLE_BAR_FONT;
protected static Border DEFAULT_INNER_FRAME_BORDER;
protected static Icon DEFAULT_FRAME_ICON;
private static Hashtable myDefaults = new Hashtable();
static {
myDefaults.put("InternalFrame.inactiveTitleBackground",
new ColorUIResource(108, 190, 116));
myDefaults.put("InternalFrame.inactiveTitleForeground",
new ColorUIResource(Color.black));
myDefaults.put("InternalFrame.activeTitleBackground",
new ColorUIResource(91, 182, 249));
myDefaults.put("InternalFrame.activeTitleForeground",
new ColorUIResource(Color.black));
myDefaults.put("InternalFrame.titleFont", new FontUIResource(
"Dialog", Font.BOLD, 12));
myDefaults.put("InternalFrame.border", new BorderUIResource(
new MatteBorder(4, 4, 4, 4, Color.blue)));
}
public static ComponentUI createUI(JComponent c) {
LookAndFeel currentLF = UIManager.getLookAndFeel();
if (frameUI == null)
frameUI = new InnerFrameUI();
try {
frameUI.installDefaults();
InnerFrame frame = (InnerFrame) c;
frame.setBorder(DEFAULT_INNER_FRAME_BORDER);
if (frame.isShowing())
frame.repaint();
} catch (Exception ex) {
System.err.println(ex);
ex.printStackTrace();
}
return frameUI;
}
public void installUI(JComponent c) {
InnerFrame frame = (InnerFrame) c;
super.installUI(frame);
}
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
}
protected void installDefaults() {
DEFAULT_TITLE_BAR_BG_COLOR = (Color) findDefaultResource("InternalFrame.inactiveTitleBackground");
DEFAULT_TITLE_BAR_FG_COLOR = (Color) findDefaultResource("InternalFrame.inactiveTitleForeground");
DEFAULT_SELECTED_TITLE_BAR_BG_COLOR = (Color) findDefaultResource("InternalFrame.activeTitleBackground");
DEFAULT_SELECTED_TITLE_BAR_FG_COLOR = (Color) findDefaultResource("InternalFrame.activeTitleForeground");
DEFAULT_TITLE_BAR_FONT = (Font) findDefaultResource("InternalFrame.titleFont");
DEFAULT_INNER_FRAME_BORDER = (Border) findDefaultResource("InternalFrame.border");
DEFAULT_FRAME_ICON = (Icon) findDefaultResource("InternalFrame.icon");
}
protected Object findDefaultResource(String id) {
Object obj = null;
try {
UIDefaults uiDef = UIManager.getDefaults();
obj = uiDef.get(id);
} catch (Exception ex) {
System.err.println(ex);
}
if (obj == null)
obj = myDefaults.get(id);
return obj;
}
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (c.getBorder() != null)
c.getBorder().paintBorder(c, g, 0, 0, c.getWidth(), c.getHeight());
}
public Color getTitleBarBkColor() {
return DEFAULT_TITLE_BAR_BG_COLOR;
}
public Color getSelectedTitleBarBkColor() {
return DEFAULT_SELECTED_TITLE_BAR_BG_COLOR;
}
public Color getTitleBarFgColor() {
return DEFAULT_TITLE_BAR_FG_COLOR;
}
public Color getSelectedTitleBarFgColor() {
return DEFAULT_SELECTED_TITLE_BAR_FG_COLOR;
}
public Font getTitleBarFont() {
return DEFAULT_TITLE_BAR_FONT;
}
public Border getInnerFrameBorder() {
return DEFAULT_INNER_FRAME_BORDER;
}
}
Create a virtual desktop in your application
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class Main extends JFrame {
public Main() {
JMenuBar bar = new JMenuBar();
JMenu addMenu = new JMenu("Add");
JMenuItem newFrame = new JMenuItem("Internal Frame");
addMenu.add(newFrame);
bar.add(addMenu);
setJMenuBar(bar);
final JDesktopPane theDesktop = new JDesktopPane();
getContentPane().add(theDesktop);
newFrame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JInternalFrame frame = new JInternalFrame("Internal Frame", true, true, true, true);
Container c = frame.getContentPane();
MyJPanel panel = new MyJPanel();
c.add(panel, BorderLayout.CENTER);
frame.setSize(200,200);
frame.setOpaque(true);
theDesktop.add(frame);
}
});
setSize(500, 400);
setVisible(true);
}
public static void main(String args[]) {
Main app = new Main();
}
}
class MyJPanel extends JPanel {
public MyJPanel() {
add(new JLabel("adf"));
}
}
Creating a JDesktopPane Container
import java.awt.BorderLayout;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JTextArea;
public class Main {
public static void main(String[] argv) throws Exception {
boolean resizable = true;
boolean closeable = true;
boolean maximizable = true;
boolean iconifiable = true;
String title = "Frame Title";
JInternalFrame iframe = new JInternalFrame(title, resizable, closeable, maximizable,
iconifiable);
iframe.setSize(300, 300);
iframe.setVisible(true);
iframe.getContentPane().add(new JTextArea());
JDesktopPane desktop = new JDesktopPane();
desktop.add(iframe);
JFrame frame = new JFrame();
frame.getContentPane().add(desktop, BorderLayout.CENTER);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
// This is example is from Kjell Dirdal.
// Referenced from http://www.javaworld.ru/javaworld/jw-05-2001/jw-0525-mdi.html
import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyVetoException;
import javax.swing.DefaultDesktopManager;
import javax.swing.JCheckBoxMenuItem;
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.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
public class KjellDirdalNotepad extends JFrame {
private MDIDesktopPane desktop = new MDIDesktopPane();
private JMenuBar menuBar = new JMenuBar();
private JMenu fileMenu = new JMenu("File");
private JMenuItem newMenu = new JMenuItem("New");
private JScrollPane scrollPane = new JScrollPane();
public KjellDirdalNotepad() {
menuBar.add(fileMenu);
menuBar.add(new WindowMenu(desktop));
fileMenu.add(newMenu);
setJMenuBar(menuBar);
setTitle("MDI Test");
scrollPane.getViewport().add(desktop);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(scrollPane, BorderLayout.CENTER);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
newMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
desktop.add(new TextFrame());
}
});
}
public static void main(String[] args) {
KjellDirdalNotepad notepad = new KjellDirdalNotepad();
notepad.setSize(600, 400);
notepad.setVisible(true);
}
}
class TextFrame extends JInternalFrame {
private JTextArea textArea = new JTextArea();
private JScrollPane scrollPane = new JScrollPane();
public TextFrame() {
setSize(200, 300);
setTitle("Edit Text");
setMaximizable(true);
setIconifiable(true);
setClosable(true);
setResizable(true);
scrollPane.getViewport().add(textArea);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(scrollPane, BorderLayout.CENTER);
}
}
/**
* An extension of WDesktopPane that supports often used MDI functionality. This
* class also handles setting scroll bars for when windows move too far to the
* left or bottom, providing the MDIDesktopPane is in a ScrollPane.
*/
class MDIDesktopPane extends JDesktopPane {
private static int FRAME_OFFSET = 20;
private MDIDesktopManager manager;
public MDIDesktopPane() {
manager = new MDIDesktopManager(this);
setDesktopManager(manager);
setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
}
public void setBounds(int x, int y, int w, int h) {
super.setBounds(x, y, w, h);
checkDesktopSize();
}
public Component add(JInternalFrame frame) {
JInternalFrame[] array = getAllFrames();
Point p;
int w;
int h;
Component retval = super.add(frame);
checkDesktopSize();
if (array.length > 0) {
p = array[0].getLocation();
p.x = p.x + FRAME_OFFSET;
p.y = p.y + FRAME_OFFSET;
} else {
p = new Point(0, 0);
}
frame.setLocation(p.x, p.y);
if (frame.isResizable()) {
w = getWidth() - (getWidth() / 3);
h = getHeight() - (getHeight() / 3);
if (w < frame.getMinimumSize().getWidth())
w = (int) frame.getMinimumSize().getWidth();
if (h < frame.getMinimumSize().getHeight())
h = (int) frame.getMinimumSize().getHeight();
frame.setSize(w, h);
}
moveToFront(frame);
frame.setVisible(true);
try {
frame.setSelected(true);
} catch (PropertyVetoException e) {
frame.toBack();
}
return retval;
}
public void remove(Component c) {
super.remove(c);
checkDesktopSize();
}
/**
* Cascade all internal frames
*/
public void cascadeFrames() {
int x = 0;
int y = 0;
JInternalFrame allFrames[] = getAllFrames();
manager.setNormalSize();
int frameHeight = (getBounds().height - 5) - allFrames.length * FRAME_OFFSET;
int frameWidth = (getBounds().width - 5) - allFrames.length * FRAME_OFFSET;
for (int i = allFrames.length - 1; i >= 0; i--) {
allFrames[i].setSize(frameWidth, frameHeight);
allFrames[i].setLocation(x, y);
x = x + FRAME_OFFSET;
y = y + FRAME_OFFSET;
}
}
/**
* Tile all internal frames
*/
public void tileFrames() {
java.awt.ruponent allFrames[] = getAllFrames();
manager.setNormalSize();
int frameHeight = getBounds().height / allFrames.length;
int y = 0;
for (int i = 0; i < allFrames.length; i++) {
allFrames[i].setSize(getBounds().width, frameHeight);
allFrames[i].setLocation(0, y);
y = y + frameHeight;
}
}
/**
* Sets all component size properties ( maximum, minimum, preferred) to the
* given dimension.
*/
public void setAllSize(Dimension d) {
setMinimumSize(d);
setMaximumSize(d);
setPreferredSize(d);
}
/**
* Sets all component size properties ( maximum, minimum, preferred) to the
* given width and height.
*/
public void setAllSize(int width, int height) {
setAllSize(new Dimension(width, height));
}
private void checkDesktopSize() {
if (getParent() != null && isVisible())
manager.resizeDesktop();
}
}
/**
* Private class used to replace the standard DesktopManager for JDesktopPane.
* Used to provide scrollbar functionality.
*/
class MDIDesktopManager extends DefaultDesktopManager {
private MDIDesktopPane desktop;
public MDIDesktopManager(MDIDesktopPane desktop) {
this.desktop = desktop;
}
public void endResizingFrame(JComponent f) {
super.endResizingFrame(f);
resizeDesktop();
}
public void endDraggingFrame(JComponent f) {
super.endDraggingFrame(f);
resizeDesktop();
}
public void setNormalSize() {
JScrollPane scrollPane = getScrollPane();
int x = 0;
int y = 0;
Insets scrollInsets = getScrollPaneInsets();
if (scrollPane != null) {
Dimension d = scrollPane.getVisibleRect().getSize();
if (scrollPane.getBorder() != null) {
d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, d.getHeight()
- scrollInsets.top - scrollInsets.bottom);
}
d.setSize(d.getWidth() - 20, d.getHeight() - 20);
desktop.setAllSize(x, y);
scrollPane.invalidate();
scrollPane.validate();
}
}
private Insets getScrollPaneInsets() {
JScrollPane scrollPane = getScrollPane();
if (scrollPane == null)
return new Insets(0, 0, 0, 0);
else
return getScrollPane().getBorder().getBorderInsets(scrollPane);
}
private JScrollPane getScrollPane() {
if (desktop.getParent() instanceof JViewport) {
JViewport viewPort = (JViewport) desktop.getParent();
if (viewPort.getParent() instanceof JScrollPane)
return (JScrollPane) viewPort.getParent();
}
return null;
}
protected void resizeDesktop() {
int x = 0;
int y = 0;
JScrollPane scrollPane = getScrollPane();
Insets scrollInsets = getScrollPaneInsets();
if (scrollPane != null) {
JInternalFrame allFrames[] = desktop.getAllFrames();
for (int i = 0; i < allFrames.length; i++) {
if (allFrames[i].getX() + allFrames[i].getWidth() > x) {
x = allFrames[i].getX() + allFrames[i].getWidth();
}
if (allFrames[i].getY() + allFrames[i].getHeight() > y) {
y = allFrames[i].getY() + allFrames[i].getHeight();
}
}
Dimension d = scrollPane.getVisibleRect().getSize();
if (scrollPane.getBorder() != null) {
d.setSize(d.getWidth() - scrollInsets.left - scrollInsets.right, d.getHeight()
- scrollInsets.top - scrollInsets.bottom);
}
if (x <= d.getWidth())
x = ((int) d.getWidth()) - 20;
if (y <= d.getHeight())
y = ((int) d.getHeight()) - 20;
desktop.setAllSize(x, y);
scrollPane.invalidate();
scrollPane.validate();
}
}
}
/**
* Menu component that handles the functionality expected of a standard
* "Windows" menu for MDI applications.
*/
class WindowMenu extends JMenu {
private MDIDesktopPane desktop;
private JMenuItem cascade = new JMenuItem("Cascade");
private JMenuItem tile = new JMenuItem("Tile");
public WindowMenu(MDIDesktopPane desktop) {
this.desktop = desktop;
setText("Window");
cascade.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
WindowMenu.this.desktop.cascadeFrames();
}
});
tile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
WindowMenu.this.desktop.tileFrames();
}
});
addMenuListener(new MenuListener() {
public void menuCanceled(MenuEvent e) {
}
public void menuDeselected(MenuEvent e) {
removeAll();
}
public void menuSelected(MenuEvent e) {
buildChildMenus();
}
});
}
/* Sets up the children menus depending on the current desktop state */
private void buildChildMenus() {
int i;
ChildMenuItem menu;
JInternalFrame[] array = desktop.getAllFrames();
add(cascade);
add(tile);
if (array.length > 0)
addSeparator();
cascade.setEnabled(array.length > 0);
tile.setEnabled(array.length > 0);
for (i = 0; i < array.length; i++) {
menu = new ChildMenuItem(array[i]);
menu.setState(i == 0);
menu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JInternalFrame frame = ((ChildMenuItem) ae.getSource()).getFrame();
frame.moveToFront();
try {
frame.setSelected(true);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
}
});
menu.setIcon(array[i].getFrameIcon());
add(menu);
}
}
/*
* This JCheckBoxMenuItem descendant is used to track the child frame that
* corresponds to a give menu.
*/
class ChildMenuItem extends JCheckBoxMenuItem {
private JInternalFrame frame;
public ChildMenuItem(JInternalFrame frame) {
super(frame.getTitle());
this.frame = frame;
}
public JInternalFrame getFrame() {
return frame;
}
}
}
Getting All Frames in a JDesktopPane Container
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
public class Main {
public static void main(String[] argv) throws Exception {
JDesktopPane desktop = new JDesktopPane();
JInternalFrame[] frames = desktop.getAllFrames();
for (int i = 0; i < frames.length; i++) {
String title = frames[i].getTitle();
boolean isVisible = frames[i].isVisible();
boolean isCloseable = frames[i].isClosable();
boolean isResizeable = frames[i].isResizable();
boolean isIconifiable = frames[i].isIconifiable();
boolean isIcon = frames[i].isIcon();
boolean isMaximizable = frames[i].isMaximizable();
boolean isSelected = frames[i].isSelected();
}
}
}