第15章 内部窗体和桌面窗格

15章 内部窗体和桌面窗格

  Swing提供实现多文档界面(MDI)应用程序的一组组件。MDI应用程序(如Microsoft WordAdobe FrameMaker)是用一个窗口实现的,这个窗口是应用程序中创建的文档的桌面。
  Swing提供带桌面的MDI功能和内部窗体,其中桌面由JDesktopPane类表示,内部窗体由JInternalFrame类表示。内部窗体在桌面上,并且可以在桌面内打开、关闭、最大化和图标化。Swing提供一个DesktopManager类,用这个类来实现桌面上的内部窗体的特定界面样式行为。

15.1 JInternalFrame

  由于内部窗体是外部窗体的复制品,所以内部窗体也是窗体。由于它们包含在另一个Swing容器中,所以它们是内部的,而这个容器通常是一个桌面窗格。
  内部窗体边框中所包含的控件与界面样式有关。标准Swing界面样式都提供关闭按钮、最大化按钮和最小化按钮,这可以从图15-1Metal界面样式中看到。另外,Metal界面样式还提供在标题条中的控制条和图标,如图15-1最下面的图片所示。
    
           图15-1 运行中的JInternalFrame

  单击图15-1所示的小应用程序中的按钮将产生内部窗体。图15-1顶层的窗体被选取,此时,这个窗体的边框是增亮的。
  例15-1列出了图15-1所示的小应用程序的代码。

15-1 运行中的JInternalFrame

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

 

public class Test extends JApplet {

        JButton b = new JButton("make frame");

        JDesktopPane desktopPane = new JDesktopPane();

        int windowCount = 1;

 

        public void init() {

               Container contentPane = getContentPane();

 

               contentPane.add(b, BorderLayout.NORTH);

               contentPane.add(desktopPane, BorderLayout.CENTER);

 

               desktopPane.setLayout(new FlowLayout());

 

               b.addActionListener(new ActionListener() {

                       public void actionPerformed(ActionEvent event) {

                               JInternalFrame jif = new JInternalFrame(

                                       "Internal Frame " + windowCount++, // title

                                       true,  // resizable

                                      true,  // closable

                                       true,  // maximizable

                                       true); // iconifiable

 

                               jif.setPreferredSize(new Dimension(250, 100));

                               desktopPane.add(jif);

                               jif.show();//新添加一句,原文没有

                               desktopPane.revalidate();

                       }

               });

        }

}

15.1.1 JInternalFrame属性

 

15.1.2 JInternalFrame事件

15-2 处理内部窗体事件

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

public class Test extends JApplet {
JDesktopPane desktopPane = new JDesktopPane();

public void init() {
Container contentPane = getContentPane();

contentPane.add(desktopPane, BorderLayout.CENTER);
desktopPane.setLayout(new FlowLayout());

JInternalFrame jif = new JInternalFrame(
"An Internal Frame", // title
false, // resizable
true, // closable
true, // maximizable
true); // iconifiable

jif.setPreferredSize(new Dimension(300, 250));
jif.addInternalFrameListener(new Listener(this));
jif.show();//
新添加一句,原文没有

desktopPane.add(jif);
}
}
class Listener implements InternalFrameListener {
private JApplet applet;

public Listener(JApplet applet) {
this.applet = applet;
}
public void internalFrameActivated(InternalFrameEvent e) {
applet.showStatus("frame activated");
}
public void internalFrameClosed(InternalFrameEvent e) {
applet.showStatus("frame closed");
}
public void internalFrameClosing(InternalFrameEvent e) {
applet.showStatus("frame closing");
}
public void internalFrameDeactivated(InternalFrameEvent e) {
applet.showStatus("frame deactivated");
}
public void internalFrameDeiconified(InternalFrameEvent e) {
applet.showStatus("frame deiconified");
}
public void internalFrameIconified(InternalFrameEvent e) {
applet.showStatus("frame iconified");
}
public void internalFrameOpened(InternalFrameEvent e) {
applet.showStatus("frame opened");
}
private void sleepForABit() {
try {
Thread.currentThread().sleep(5000);
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}

15-3 否决关闭内部窗体

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

public class Test extends JFrame {
JDesktopPane desktopPane = new JDesktopPane();

public Test() {
Container contentPane = getContentPane();

contentPane.add(desktopPane, BorderLayout.CENTER);
desktopPane.setLayout(new FlowLayout());

JInternalFrame jif = new JInternalFrame(
"Some Editor", // title
false, // resizable
true); // closable

jif.setPreferredSize(new Dimension(300, 250));
jif.addVetoableChangeListener(new CloseListener());
jif.show();//
新添加的一句,原文没有
desktopPane.add(jif);
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Vetoing Internal Frame Closing",
300,300,450,300);
}
}
class CloseListener implements VetoableChangeListener {
private Test applet;

public void vetoableChange(PropertyChangeEvent e)
throws PropertyVetoException {
String name = e.getPropertyName();

if(name.equals(JInternalFrame.IS_CLOSED_PROPERTY)) {
Component internalFrame = (Component)e.getSource();
Boolean oldValue = (Boolean)e.getOldValue(),
newValue = (Boolean)e.getNewValue();

if(oldValue == Boolean.FALSE &&
newValue == Boolean.TRUE) {
int answer = JOptionPane.showConfirmDialog(
internalFrame, // parentComponent
"Save Changes?", // message
"Unsaved Changes", // title
JOptionPane.YES_NO_CANCEL_OPTION);

if(answer == JOptionPane.CANCEL_OPTION) {
throw new PropertyVetoException(
"close cancelled", e);
}
}
}
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

15-4 替换一个内部窗体的图标

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

public class Test extends JApplet {
JDesktopPane desktopPane = new JDesktopPane();
JInternalFrame jif = new JInternalFrame(
"Internal Frame", // title
true, // resizble
true, // closable
true, // maximizable
true); // iconifiable

public void init() {
Container contentPane = getContentPane();

contentPane.add(desktopPane, BorderLayout.CENTER);

jif.setBounds(50, 50, 300, 200);
jif.setFrameIcon(new ImageIcon(this.getClass().getResource("print.gif")));
desktopPane.add(jif);
jif.show();//
源添加的一句,原文没有
}
}

 

 

15.1.3 AWT兼容

 

15-5 一个定制的桌面窗格

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

public class Test extends JApplet {
CustomDesktopPane desktopPane = new CustomDesktopPane();
int frameCount = 1, numFrames = 5, x, y;

public void init() {
Container contentPane = getContentPane();

setJMenuBar(createMenuBar());
contentPane.add(desktopPane, BorderLayout.CENTER);

for(int i=0; i < numFrames; ++i) {
JInternalFrame jif = new JInternalFrame(
"Internal Frame " + frameCount++, // title
true, // resizable
true, // closable
true, // maximizable
true); // iconifiable

x = (int)(Math.random() * 100);
y = (int)(Math.random() * 100);

jif.setBounds(x, y, 250, 100);
desktopPane.putClientProperty(
"JDesktopPane.dragMode",
"outline");

desktopPane.add(jif);
jif.show();//
新添加一句,原文没有
}
}
private JMenuBar createMenuBar() {
JMenuBar menubar = new JMenuBar();
JMenu windowMenu = new JMenu("Window");

windowMenu.add(new OpenAllAction());
windowMenu.add(new CloseAllAction());
windowMenu.add(new CascadeAction());

menubar.add(windowMenu);
return menubar;
}
class OpenAllAction extends AbstractAction {
public OpenAllAction() {
super("open all");
}
public void actionPerformed(ActionEvent e) {
desktopPane.openAll();
}
}
class CloseAllAction extends AbstractAction {
public CloseAllAction() {
super("close all");
}
public void actionPerformed(ActionEvent e) {
desktopPane.closeAll();
}
}
class CascadeAction extends AbstractAction {
public CascadeAction() {
super("cascade");
}
public void actionPerformed(ActionEvent e) {
desktopPane.cascade();
}
}
}
class CustomDesktopPane extends JDesktopPane {
private int xoffset = 20, yoffset = 20, w = 250, h = 350;

public void closeAll() {
JInternalFrame[] frames = getAllFrames();

for(int i=0; i < frames.length; ++i) {
if(!frames[i].isIcon()) {
try {
frames[i].setIcon(true);
}
catch(java.beans.PropertyVetoException ex) {
System.out.println("iconification vetoed!");
}
}
}
}
public void openAll() {
JInternalFrame[] frames = getAllFrames();

for(int i=0; i < frames.length; ++i) {
if(frames[i].isIcon()) {
try {
frames[i].setIcon(false);
}
catch(java.beans.PropertyVetoException ex) {
System.out.println("restoration vetoed!");
}
}
}
}
public void cascade() {
JInternalFrame[] frames = getAllFrames();
int x = 0, y = 0;

for(int i=0; i < frames.length; ++i) {
if( ! frames[i].isIcon()) {
frames[i].setBounds(x,y,w,h);
x += xoffset;
y += yoffset;
}
}
}
}

15.2 JDesktopPane

 


15.2.1 JDesktopPane
属性

 

15.2.2 JDesktopPane事件

 

15.2.3 JDesktopPane类总结

 

15.2.4 AWT兼容

 

15.3 DesktopManager

 

15-6 一个定制的DesktopManager

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

public class Test extends JApplet {
JDesktopPane desktopPane = new JDesktopPane();

public void init() {
Container contentPane = getContentPane();

contentPane.add(desktopPane, BorderLayout.CENTER);
desktopPane.setDesktopManager(new OutlineManager());

JInternalFrame jif = new JInternalFrame(
"Outline Drag and Resize", // title
true, // resizable
true, // closable
true, // maximizable
true); // iconifiable

jif.setBounds(10, 10, 250, 100);
desktopPane.add(jif);
jif.show();//
新添加的,原文没有
}
}
class OutlineManager extends DefaultDesktopManager {
private Rectangle start, last;
private boolean first = true;

// dragging ...

public void beginDraggingFrame(JComponent frame) {
initializeOutline(frame);
}
public void dragFrame(JComponent frame, int x, int y) {
updateOutline(frame, x, y, start.width, start.height);
}
public void endDraggingFrame(JComponent frame) {
endOutline(frame);
}

// resizing ...

public void beginResizingFrame(JComponent frame, int dir) {
initializeOutline(frame);
}
public void resizeFrame(JComponent frame,
int x, int y, int w, int h) {
updateOutline(frame, x, y, w, h);
}
public void endResizingFrame(JComponent frame) {
endOutline(frame);
}

// outline ...

private void initializeOutline(final JComponent frame) {
// the call to setVisible() calls repaint, which
// places a paint event on the event queue.
// therefore, the effect of the setVisible() call is
// not apparent until after this method returns

frame.setVisible(false);
start = frame.getBounds();
last = new Rectangle(start);
first = true;

// the Runnable below paints the initial outline
// after the repaint event spawned by setVisible() is
// handled

SwingUtilities.invokeLater(new Runnable() {
public void run() {
updateOutline(frame,start.x,start.y,
start.width,start.height);
}
});
}
private void updateOutline(JComponent frame,
int x, int y, int w, int h) {
Container container = frame.getParent();
Graphics g = container.getGraphics();

try {
g.setXORMode(container.getBackground());

if( ! first) {
g.drawRect(last.x, last.y,
last.width-1, last.height-1);
}
g.drawRect(x, y, w-1, h-1);
first = false;
}
finally {
g.dispose();
last.setBounds(x,y,w,h);
}
}
private void endOutline(JComponent frame) {
frame.setVisible(true);
setBoundsForFrame(
frame, last.x, last.y, last.width, last.height);
}
}

15.4 本章回顾

  略

上一篇:Java 性能测试框架工具-JunitPerf


下一篇:ant 学习(3)--结合junit形成自动化测试小框架